Skip to main content

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 testing.

This page walks through what happens when you switch and how to recover if it goes wrong.

The switch flow​

  1. Open Themes in the sidebar.
  2. Click the Activate button on an inactive theme's card.
  3. A confirmation modal explains the switch will:
    • Update settings.activeThemeId in 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.)
  4. Click Switch & regenerate to confirm.
  5. 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-sitemaps re-emits sitemaps with the new theme's URL conventions)
  6. 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>.css is 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 imageFormats catalog.
  • ✗ 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 magazine theme registers magazine/hero-split, magazine/most-read, magazine/promo-card
  • The corporate theme registers corporate/hero-overlay, corporate/services-grid, etc.
  • The default theme 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:

  1. Open the affected post.
  2. The block shows as "unknown block" in the editor — delete it or replace with a corporate-equivalent.
  3. 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>.css is 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:

  1. Themes → Regenerate site → Everything — re-runs the full regen with the now-active theme
  2. 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>.css from the bundle's embedded cssText

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​