Switching themes
Switching the active theme is a deliberate, all-or-nothing operation. The new theme's HTML / CSS replaces the old theme's everywhere on your site at once. There's no per-page theme override, no a/b
Switching the active theme is a deliberate, all-or-nothing operation. The new theme's HTML / CSS replaces the old theme's everywhere on your site at once. There's no per-page theme override, no a/b testing.
This page walks through what happens when you switch and how to recover if it goes wrong.
The switch flow
Open Themes in the sidebar.
Click the Activate button on an inactive theme's card.
A confirmation modal explains the switch will:
- Update
settings.activeThemeIdin Firestore - Upload the new theme's CSS to
/theme-assets/<new-theme-id>.css - Regenerate every published HTML page with the new theme's templates
- Re-run every plugin's regeneration target (sitemaps, RSS, search index, etc.)
- Update
Click Switch & regenerate to confirm.
The publisher's
regenerateAll()runs:- Re-renders every online post (
<n>files) - Re-renders every page (
<m>files) - Re-renders every category archive
- Re-renders the home page
- Re-uploads
menu.json(theme switch may change branding logo URL) - Re-uploads
posts.json(some themes have different post-card data needs) - Runs every plugin's regen target (e.g.
flexweg-sitemapsre-emits sitemaps with the new theme's URL conventions)
- Re-renders every online post (
The publish log shows progress. Each upload takes a small fraction of a second; total time scales with the number of online posts. A site with 100 posts switches in ~30s.
What changes
After a successful switch:
- ✓ Every public page now serves with the new theme's HTML
- ✓ The new theme's CSS is at
/theme-assets/<new-theme-id>.css - ✓ The old theme's CSS at
/theme-assets/<old-theme-id>.cssis left in place (still referenced by no published page, but not deleted automatically — useful as a backup if you want to switch back) - ✓ Theme blocks from the previous theme are still present in your post bodies as
<div data-cms-block="<old-theme>/<block>">markers, but they won't render (the new theme's marker regex doesn't recognise them). Edit affected posts to remove or replace those blocks.
What doesn't change
- ✗ Your posts, pages, categories, tags, media — none of these touch on the theme
- ✗ Plugin configurations — settings page configs are theme-agnostic
- ✗ Menus — the menu builder doesn't depend on the theme; only the rendering at the public site changes
- ✗ Image variants in your media library — keep their existing variants. New uploads will use the new theme's
imageFormatscatalog. - ✗ Your settings (site title, language, baseUrl, etc.)
Theme blocks from the previous theme
Theme blocks are scoped to the theme that registered them. For example:
- The
magazinetheme registersmagazine/hero-split,magazine/most-read,magazine/promo-card - The
corporatetheme registerscorporate/hero-overlay,corporate/services-grid, etc. - The
defaulttheme registers no theme blocks (uses only core blocks)
If you've inserted a magazine/hero-split in a post and switch to corporate, that block markers stays in the post's markdown (<div data-cms-block="magazine/hero-split" data-attrs="…">) but corporate's render pipeline doesn't recognise it. The publisher leaves the marker as-is in the rendered HTML — visitors see an empty <div> where the block was.
To clean up:
- Open the affected post.
- The block shows as "unknown block" in the editor — delete it or replace with a corporate-equivalent.
- Save + re-publish.
If you have many such posts, you can do a one-time scan via Firestore: search the posts/ collection for documents whose contentMarkdown contains data-cms-block="<old-theme>/.
Switching back
The old theme's CSS is still on Flexweg (we don't auto-delete on switch). If you switch back:
- Same flow — confirmation modal, regenerate everything
- The old CSS at
/theme-assets/<old-theme-id>.cssis still there, so it's instantly served (no need to re-sync) - Theme blocks from the corporate (or whatever interim theme) still exist in posts; same cleanup applies
When the switch fails partway
regenerateAll is idempotent — it can be re-run without making things worse. If the switch fails halfway through (network blip, Flexweg API quota hit), the publish log shows which step failed. After fixing the underlying issue:
- Themes → Regenerate site → Everything — re-runs the full regen with the now-active theme
- Or just publish individual posts that are out-of-date
Some posts may temporarily be served with old-theme HTML referencing new-theme CSS (or vice versa) — visitors see a brief mismatch until the regen completes.
Activating an external theme
External themes (uploaded via Install theme) work the same way as built-ins:
- They appear as cards in the Themes list
- Clicking Activate triggers the same regenerate-all flow
- The external theme's CSS is in its bundle (uploaded along with the bundle.js); the Sync theme assets flow re-uploads it to
/theme-assets/<id>.cssfrom the bundle's embeddedcssText
Uninstall protection
If you try to uninstall the currently-active theme, the Uninstall button is disabled. Switch to a different theme first, then uninstall the previous one.
This prevents leaving the admin with no active theme, which would 404 the public site. The default theme is always available as a safe fallback (it stays bundled even when externals are uninstalled — see [Themes architecture]).
Continue
- Theme settings — customise without switching
- Sync theme assets — re-push the active theme's CSS without regenerating pages
- Installing external themes
- Built-in themes reference