Theme Library
The admin theme workflow is Theme Library -> Customize -> Preview -> Apply. It replaces the generic theme-record editing habit with one owner/admin flow for installed theme instances, catalogue/local definitions, pending installs, and diagnostics.

What The Page Shows
Section titled “What The Page Shows”| Section | Source | What admins do |
|---|---|---|
| Installed themes | themes records plus registered package definitions | Customize, preview, and apply a theme instance. |
| Available themes | registered ThemeDefinitionData entries without a matching themes.key record | Create the missing installed theme instance from the unified Add theme slide-over. |
| Pending installs | Marketplace install intents when the Marketplace table exists | See that a theme install is still waiting for Composer/deployment work. |
| Diagnostics | ValidateThemeDefinitionAction output | Find missing renderer, preset, section, asset, preview image, and parent-theme problems before applying. |
The installed themes table is a normal Filament table with compact columns for preview, name/description, active preset, site usage, status, diagnostics, and actions. Diagnostics are shown as a clickable badge; errors block Apply theme but do not expand noisy details into the row.
Theme table images prefer package definition data. The admin card image fallback order is:
- theme media image
admin.editor.image- generated admin image
ThemeDefinitionData::previewImage- initials fallback
Add Themes
Section titled “Add Themes”Use Add theme for all new theme entry points:
- Add my own theme creates a custom installed theme record.
- Create from installed package creates a theme from a registered package/local
ThemeDefinitionData. - Search marketplace is reserved for Marketplace installs when that package is present.
Package definition creation uses the definition name, assets, and first preset. The first preset is saved as meta.editor.preset.active, so the theme can be customized, previewed, and applied immediately after creation. Creating a theme does not make it the global default; admins still use Apply theme for activation. Definitions with diagnostics errors stay blocked until the missing parent, renderer, or preset problem is fixed.
Customize
Section titled “Customize”Use Customize on an installed theme. The slide-over is a guided editor with sections on the left and a sticky sandboxed iframe preview on the right. The preview is built from unsaved form state and only persists when the admin explicitly saves.
Core groups:
- Quick setup: active preset plus admin editor metadata in
admin.editor.*. - Brand:
meta.editor.brand.*. - Header:
meta.editor.header.*. - Page surface:
meta.editor.surface.*. - Footer:
meta.editor.footer.*. - Assets:
meta.editor.assets.pathsandmeta.editor.assets.buildPath. - Advanced:
meta.editor.advanced.*, including sandboxed custom CSS.
Do not expose blueprint/default/status as the main workflow. They can still exist in advanced/admin areas for maintainers who need them.
Preview
Section titled “Preview”Preview asks for a site, page, and preset. It does not silently pick the first default page.
The preview URL is generated by CreateThemePreviewUrlAction and signed through the normal admin preview route. When a preset is selected, the URL also carries a ThemePreviewSigner token. The token resolves inside theme runtime only for the preview request, so the selected preset can be checked before saving/applying it broadly.
Preview is an authenticated admin surface:
- unsigned requests are rejected
- non-admin users are rejected
- site-scoped admins can preview only assigned sites
- responses are private/no-store
- authoring metadata is not printed into the preview HTML
Apply theme uses SetActiveThemeForSitesAction.
| Scope | Effect | Cache behavior |
|---|---|---|
| Global default | marks the selected theme active and default, clears other defaults | ThemeObserver invalidates frontend surrogate keys for affected sites. |
| Selected sites | saves theme_id on each selected Site model | SiteObserver flushes site/theme relation caches and emits frontend surrogate invalidation. |
The Filament action re-checks scope server-side. Site-scoped admins cannot submit a tampered request to set the global default or apply a theme to unassigned sites.

Diagnostics
Section titled “Diagnostics”Run diagnostics from the UI or the command line:
php artisan capell:themes:validatephp artisan capell:themes:validate foundationDiagnostics check:
- package definition registration
- installed
themes.keymatch themeKeyconsistency- renderer registration
- parent/extends chain
- standard section coverage
- declared frontend assets
- preset availability
- preview image metadata
Warnings mean the theme may still be previewable, but the package author should fix the manifest/registration before release. Errors mean the theme should not be applied until the missing definition or renderer contract is fixed.
Public Safety
Section titled “Public Safety”Theme library changes must not change the public-output safety contract. Anonymous/public HTML must not include admin labels, package internals, field paths, model IDs, signed editor URLs, or authoring scripts.
Runtime reads the selected theme, active preset, brand profile, and package definition server-side. Public output receives ordinary frontend HTML and token CSS only.