Building a theme
Foundry themes own presentation. A theme defines layouts, partials, theme assets, and a small manifest that describes the package.
Start with the scaffold
foundry theme scaffold <theme-name>
foundry theme validate <theme-name>
foundry theme switch <theme-name>
The scaffolded theme gives you the expected directory structure and the required base set of layouts and partials.
Theme structure
themes/editorial/
theme.yaml
assets/
css/
base.css
layouts/
base.html
index.html
page.html
post.html
list.html
partials/
head.html
header.html
footer.html
Manifest fields
theme.yaml describes the theme, the layouts it supports, the configuration
it expects, and the slot surface it guarantees.
name: editorial
title: Editorial
version: 0.1.0
description: A Foundry theme.
license: MIT
min_foundry_version: 0.1.0
compatibility_version: v1
layouts:
- base
- index
- page
- post
- list
supported_layouts:
- base
- index
- page
- post
- list
screenshots:
- screenshots/home.png
config_schema:
- name: accent_color
label: Accent Color
type: text
default: "#0c7c59"
slots:
- head.end
- body.start
- body.end
- page.before_main
- page.after_main
- page.before_content
- page.after_content
- post.before_header
- post.after_header
- post.before_content
- post.after_content
- post.sidebar.top
- post.sidebar.overview
- post.sidebar.bottom
Layout responsibilities
- base.html: wraps the page shell and usually includes shared head, header, footer, and plugin slots.
- index.html: renders the home page or language root page.
- page.html: renders page documents.
- post.html: renders post documents.
- list.html: renders list-style views such as taxonomy archives.
Required slots
For the launch version of Foundry, theme validation enforces a minimum slot contract. A valid theme must declare and render all of the following slots:
head.endbody.startbody.endpage.before_mainpage.after_mainpage.before_contentpage.after_contentpost.before_headerpost.after_headerpost.before_contentpost.after_contentpost.sidebar.toppost.sidebar.overviewpost.sidebar.bottom
Validation behavior
Theme validation now reports a fuller diagnostic set:
- the theme manifest declares the required slot names
- the expected layouts actually render those slot calls
- required layouts and required partials are present
- templates do not reference missing layouts or partials
- the layout set parses cleanly with the current Foundry template helpers
Manifest reference
-
layoutsandsupported_layoutsdefine the expected template surface. Ifsupported_layoutsis present, validation treats it as the authoritative layout contract. -
config_schemadescribes theme-level configuration fields using the same schema field shapes used elsewhere in Foundry. -
screenshotsis metadata for admin/docs/reporting and should point at paths inside the theme package. -
sdk_versionis the official Foundry JavaScript SDK contract version the theme expects. The shipped default themes targetv1, and validation now rejects themes that declare an unsupported SDK contract. -
compatibility_versionis the theme-platform contract version. Use it to signal compatibility with future theme-platform changes.
Theme and plugin interplay
Theme templates should leave room for plugin-provided markup. If you introduce a new slot, document it in the theme manifest and place it intentionally in the layout instead of treating slots as arbitrary append-only escape hatches.
Assets
Put theme CSS and other theme-owned assets under assets/. During build or
preview, Foundry copies theme assets into public/theme/ and bundles
discovered CSS into the main CSS output.
Validation checklist
- Run
foundry theme validate <name>. - Preview with
foundry serveorfoundry serve-preview. - Confirm page, post, and taxonomy archive templates all render cleanly.
- Check that plugin slots still have sensible placement.
Reference theme
The default theme in the repository is the canonical reference for current layout expectations and slot placement.
Admin theme widget slots
Admin themes use a separate manifest, admin-theme.yaml. In addition to the
component contract, admin themes now declare widget_slots so plugin-defined
admin widgets can mount against a validated slot surface instead of guessing where the
shell has room for them.
name: default
title: Default Admin
version: 0.1.0
admin_api: v1
sdk_version: v1
compatibility_version: v1
components:
- shell
- login
- navigation
- documents
- media
- users
- config
- plugins
- themes
- audit
widget_slots:
- overview.after
- documents.sidebar
- media.sidebar
- plugins.sidebar
For the current admin-platform contract, all four widget slots are required. The default admin theme auto-mounts plugin widgets declared for those slots, and alternate admin themes are validated against the same baseline.