Foundry logo Foundry Configuration reference

What this file does

content/config/site.yaml is the main runtime config for a Foundry site. It controls site identity, serving, admin behavior, build output, content layout, taxonomies, plugin activation, deploy targets, feeds, and theme-facing values.

Foundry also supports environment overlays such as content/config/site.preview.yaml. Those files are layered on top of the base config when you run commands like foundry build --env preview.

If you want a full explicit config with every current default written out, start from content/config/example.site.yaml.

How Admin Settings Relate To site.yaml

Foundry keeps content/config/site.yaml as the source of truth on disk, even when you edit settings through the admin UI.

The admin Settings area uses structured forms because forms are safer and more usable for most changes than editing a raw YAML document directly. Under the hood, the flow is:

  • YAML on disk: the persistent project config remains YAML.
  • Structured object in memory: the admin loads that YAML into a config object.
  • Forms in the UI: the object is presented as inputs, toggles, selects, and section-specific editors.
  • Structured save back to YAML: when you save, Foundry validates the structured config and writes it back to site.yaml.

Some parts of the config surface are naturally scalar and form-friendly. Others, such as taxonomy definitions, field schemas, deploy targets, menus, params, and permalinks, are more deeply nested. Those still live inside the structured Settings area, but they may use JSON-shaped editors in their own tabs rather than trying to force everything into a single giant YAML textarea.

Foundry also keeps an Advanced YAML tab in admin. That exists so advanced users can still edit the raw config directly when they need full manual control or want to work with values that are easier to express in YAML than in a form.

Minimal example

name: "foundry"
title: "Foundry CMS"
base_url: "http://localhost:8080"
theme: "default"

backup:
  enabled: false
  dir: ".foundry/backups"

server:
  addr: ":8080"
  live_reload: true

admin:
  enabled: true
  path: "/__admin"
  theme: "default"

content:
  pages_dir: "pages"
  posts_dir: "posts"

Top-level keys

These keys define the overall site identity and root directory layout.

  • name: machine-oriented site identifier used in status output and metadata. Default: foundry.
  • title: human-facing site title. Default: Foundry CMS.
  • base_url: canonical site base URL used for absolute links, feeds, preview manifests, and deploy output. Default: empty.
  • theme: active frontend theme name under themes/. Default: default.
  • environment: environment label such as default, preview, or production. Default: default.
  • default_lang: default language code for content routing. Default: en.
  • content_dir: root content directory. Default: content.
  • public_dir: build output directory. Default: public.
  • themes_dir: theme root directory. Default: themes.
  • data_dir: runtime data directory used for state files and structured data. Default: data.
  • plugins_dir: plugin installation directory. Default: plugins.

backup

This group controls zip backups for the content tree and the optional debounced on-change backup flow while the preview server is running.

  • enabled: enables managed backup behavior. Default: false.
  • dir: output directory for managed backup archives. Default: .foundry/backups.
  • on_change: when true, foundry serve and foundry serve-preview create backups after content changes settle. Default: false.
  • debounce_seconds: quiet period before an on-change backup fires. Default: 45.
  • retention_count: number of backup archives to keep in backup.dir before older ones are pruned. Default: 20.
  • min_free_mb: minimum safety buffer added to backup free-space checks. Default: 256.
  • headroom_percent: minimum free-space multiplier relative to the source size before a backup starts. Default: 125.
backup:
  enabled: true
  dir: ".foundry/backups"
  on_change: true
  debounce_seconds: 45
  retention_count: 20
  min_free_mb: 256
  headroom_percent: 125

Zip backups are the primary export and restore format. Foundry also supports local Git-backed snapshots via foundry backup git-snapshot and foundry backup git-log, stored under .foundry/backups/git.

server

This group controls the preview server and live reload behavior.

  • addr: bind address for the preview server. Default: :8080.
  • live_reload: enables or disables live reload. Default: false.
  • live_reload_mode: reload transport. Use stream for Server-Sent Events or poll when browser connection limits make SSE unreliable. Default: stream.
  • auto_open_browser: automatically opens the preview URL after startup. Default: false.
  • debug_routes: enables extra debug-only route output where supported. Default: false.
server:
  addr: ":8080"
  live_reload: true
  live_reload_mode: "poll"
  auto_open_browser: false
  debug_routes: false

admin

This group controls the admin shell, admin auth, persistent session state, and admin-only debug features.

  • enabled: enables or disables the admin surface. Default: false.
  • addr: reserved for a separate admin bind address. The current server mounts admin under the main HTTP server. Default: empty.
  • path: admin mount path. Default: /__admin.
  • local_only: rejects forwarded or non-local admin access when true. Default: false.
  • access_token: optional API token for automation or non-browser admin access. Default: empty.
  • theme: active admin theme under themes/admin-themes/. Default: default.
  • session_secret: optional secret used when hashing persisted admin session tokens. Set this in production or via FOUNDRY_ADMIN_SESSION_SECRET so session hashes are keyed with an explicit server secret. Default: empty.
  • totp_secret_key: base64-encoded 32-byte key used to encrypt stored TOTP secrets at rest. Set this in production or via FOUNDRY_ADMIN_TOTP_SECRET_KEY. New TOTP setup requires it. Default: empty.
  • users_file: filesystem-backed user database file. Default: content/config/admin-users.yaml.
  • session_store_file: persistent session store file. Foundry stores a session token hash there, not the raw reusable bearer token. Default: data/admin/sessions.yaml.
  • lock_file: persistent document lock file used by editor locking. Default: data/admin/locks.yaml.
  • session_ttl_minutes: idle browser session timeout. Default: 30.
  • session_idle_timeout_minutes: explicit inactivity timeout for admin sessions. Set to 0 to disable the separate idle-policy check and rely only on the rolling session TTL. Default: 0.
  • session_max_age_minutes: absolute maximum admin session lifetime, even if the session remains active. Set to 0 to disable the cap. Default: 0.
  • single_session_per_user: when enabled, Foundry revokes older sessions for the same user at login time. Default: false.
  • password_min_length: minimum password length for save and reset flows. Default: 12.
  • password_reset_ttl_minutes: password reset token lifetime. Default: 30.
  • totp_issuer: issuer string embedded in TOTP setup URIs. Default: Foundry.

admin.debug

  • pprof: enables authenticated net/http/pprof access and the admin Debug page runtime summary. Default: false.
admin:
  enabled: true
  addr: ""
  path: "/__admin"
  local_only: false
  access_token: ""
  session_secret: ""
  totp_secret_key: ""
  theme: "default"
  users_file: "content/config/admin-users.yaml"
  session_store_file: "data/admin/sessions.yaml"
  lock_file: "data/admin/locks.yaml"
  session_ttl_minutes: 30
  session_idle_timeout_minutes: 30
  session_max_age_minutes: 480
  single_session_per_user: false
  password_min_length: 12
  password_reset_ttl_minutes: 30
  totp_issuer: "Foundry"
  debug:
    pprof: true

Admin security

  • Set admin.session_secret or FOUNDRY_ADMIN_SESSION_SECRET in production.
  • Without it, Foundry still hashes session tokens at rest, but with plain SHA-256 instead of keyed HMAC-SHA-256.
  • Set admin.totp_secret_key or FOUNDRY_ADMIN_TOTP_SECRET_KEY in production to encrypt TOTP secrets at rest.
  • New TOTP setup requires that encryption key. Legacy plaintext TOTP secrets still verify and are migrated to encrypted form when used.
  • Admin password hashes now default to argon2id$....
  • Legacy PBKDF2 password hashes still verify and are upgraded automatically on successful login.
  • For non-local admin access, set base_url to an https:// origin and make sure your reverse proxy forwards HTTPS correctly so Secure cookies work as intended.
  • Rotating admin.session_secret invalidates all browser sessions.
  • Rotating admin.totp_secret_key requires TOTP re-enrollment for any still-encrypted secrets that cannot be migrated under the new key.
  • If either secret is suspected compromised, rotate it, revoke active sessions, and review the audit log before restoring access.
  • Compatibility note: legacy plaintext sessions, legacy plaintext TOTP secrets, and legacy PBKDF2 hashes are kept only as a migration bridge and are intended to be removed after the 1.4.x line.

build

This group controls the shape of static build output.

  • clean_public_dir: removes public/ before a build. Default: false.
  • include_drafts: includes draft content in build output. Default: false.
  • minify_html: minifies rendered HTML. Default: false.
  • copy_assets: copies content-owned static assets into output. Default: false.
  • copy_images: copies image media into output. Default: false.
  • copy_uploads: copies legacy uploads plus the current non-image media collections where applicable. Default: false.

content

This group defines directory names under content/ and a few core content defaults.

  • pages_dir: page document directory. Default: pages.
  • posts_dir: post document directory. Default: posts.
  • images_dir: image media directory. Default: images.
  • videos_dir: video media directory. Default: videos.
  • audio_dir: audio media directory. Default: audio.
  • documents_dir: document-like media directory. Default: documents.
  • assets_dir: content-owned static asset directory. Default: assets.
  • uploads_dir: legacy upload directory retained for compatibility. Default: uploads.
  • max_versions_per_file: maximum retained filesystem versions per file before pruning. Default: 10.
  • default_layout_page: default layout for pages. Default: page.
  • default_layout_post: default layout for posts. Default: post.
  • default_page_slug_index: slug used for section-index pages. Default: index.
content:
  pages_dir: "pages"
  posts_dir: "posts"
  images_dir: "images"
  videos_dir: "videos"
  audio_dir: "audio"
  documents_dir: "documents"
  assets_dir: "assets"
  uploads_dir: "uploads"
  max_versions_per_file: 10
  default_layout_page: "page"
  default_layout_post: "post"
  default_page_slug_index: "index"

permalinks

This group defines the route templates used when Foundry assigns URLs to pages and posts.

  • page_default: default-language page route pattern.
  • page_i18n: non-default-language page route pattern.
  • post_default: default-language post route pattern.
  • post_i18n: non-default-language post route pattern.
permalinks:
  page_Default: "/:slug/"
  page_i18n: "/:lang/:slug/"
  post_Default: "/posts/:slug/"
  post_i18n: "/:lang/posts/:slug/"

taxonomies

This group enables taxonomy rendering and defines which taxonomies exist.

  • enabled: enables taxonomy support. Default: false.
  • default_set: taxonomy names enabled by default for content. Default: [tags, categories].
  • definitions: per-taxonomy definitions keyed by taxonomy name. Default: {}.

Each taxonomy definition supports:

  • title: human title for the taxonomy.
  • labels: per-language label map.
  • archive_layout: optional archive layout override.
  • term_layout: layout used for individual term pages.
  • order: ordering hint such as alpha.
taxonomies:
  enabled: true
  default_set:
    - tags
    - categories
  definitions:
    tags:
      title: "Tags"
      labels:
        en: "Tags"
        es: "Etiquetas"
      archive_layout: "list"
      term_layout: "list"
      order: "alpha"
    categories:
      title: "Categories"
      labels:
        en: "Categories"
      archive_layout: "list"
      term_layout: "list"

plugins

This group controls which installed plugins are enabled for the site.

  • enabled: list of plugin names to enable. Default: empty list.
plugins:
  enabled:
    - toc
    - relatedposts
    - readingtime

Advanced Custom Fields

Foundry no longer stores advanced custom-field schemas in content/config/site.yaml. Advanced fields are now a theme-owned contract.

  • Theme schema: declare field contracts in theme.yaml under field_contracts.
  • Page values: keep page-specific values in page frontmatter under fields:.
  • Shared values: store shared/global field values in content/custom-fields.yaml.
  • Admin discoverability: the editor resolves applicable fields from the active theme based on document type, layout, and slug.
field_contracts:
  - key: marketing-page
    title: Marketing Page
    target:
      scope: document
      types: [page]
      layouts: [page]
      slugs: [pricing, about, contact]
    fields:
      - name: hero_title
        type: text
        label: Hero Title
      - name: hero_body
        type: textarea
        label: Hero Body
  - key: site_marketing
    title: Site Marketing
    target:
      scope: shared
      key: site_marketing
    fields:
      - name: primary_cta_label
        type: text
        label: Primary CTA Label
---
title: Pricing
slug: pricing
layout: page
fields:
  hero_title: Clear pricing for modern teams
  hero_body: Foundry keeps publishing infrastructure calm and predictable.
---
values:
  site_marketing:
    primary_cta_label: Start with Foundry

If you still have legacy field schemas in site.yaml, migrate them with foundry theme migrate field-contracts.

seo

This group controls SEO-oriented output defaults.

  • enabled: enables SEO-related handling where supported. Default: false.
  • default_title_sep: default title separator when combining page and site titles. Default: empty.

cache

This group controls cache-related behavior where supported by the current runtime.

  • enabled: enables cache-related behavior. Default: false.

security

This group controls security-sensitive rendering behavior.

  • allow_unsafe_html: preserves raw HTML from Markdown when true. Leave this false unless you intentionally trust raw HTML in content. Default: false.

feed

This group controls RSS and sitemap output.

  • rss_path: RSS route path. Default: /rss.xml.
  • sitemap_path: sitemap route path. Default: /sitemap.xml.
  • rss_limit: maximum number of items in the RSS feed. Default: 50.
  • rss_title: feed title. Default: the site title.
  • rss_description: feed description. Default: the site title.
feed:
  rss_path: "/rss.xml"
  sitemap_path: "/sitemap.xml"
  rss_limit: 50
  rss_title: "Foundry CMS"
  rss_description: "Foundry CMS"

deploy

This group defines named deploy targets that can override selected config values during builds.

  • default_target: target name to use by default. Default: empty.
  • targets: map of named deploy targets. Default: {}.

Each deploy target supports:

  • base_url: override canonical base URL.
  • public_dir: override output directory.
  • theme: override frontend theme.
  • include_drafts: override build draft inclusion.
  • environment: override environment label.
  • preview: when true, forces preview-style draft inclusion.
  • live_reload_mode: override live reload transport for the target.
deploy:
  default_target: "production"
  targets:
    production:
      base_url: "https://example.com"
      public_dir: "public-prod"
      theme: "default"
      include_drafts: false
      environment: "production"
      preview: false
      live_reload_mode: "stream"
    preview:
      base_url: "https://preview.example.com"
      public_dir: "public-preview"
      include_drafts: true
      environment: "preview"
      preview: true
      live_reload_mode: "poll"

params

This is a free-form map of site-level values exposed to themes, templates, and plugins.

  • params: arbitrary key-value data. Default: {}.
params:
  company_name: "Sphire"
  support_email: "support@example.com"
  home_eyebrow: "Launch Week"

menus

This group defines named menus. Each menu contains items with name and url.

  • menus: menu map keyed by menu name. Default: {}.
  • name: item label shown in the UI.
  • url: destination URL.
menus:
  main:
    - name: "Home"
      url: "/"
    - name: "Docs"
      url: "/docs/"
  footer:
    - name: "RSS"
      url: "/rss.xml"
    - name: "GitHub"
      url: "https://github.com/sphireinc/foundry"

Defaults and examples

  • Use content/config/example.site.yaml when you want every current default spelled out explicitly.
  • Keep content/config/site.yaml focused on the values you are actually overriding.
  • Use overlays like content/config/site.preview.yaml or named deploy targets when a setting should only change for preview or production builds.
  • When a group contains nested structures like taxonomies.definitions, or deploy.targets, prefer full YAML snippets over terse one-line docs so the expected shape stays obvious. For advanced custom fields, define the contract in theme.yaml and keep shared values in content/custom-fields.yaml.