Skip to main content

Sync theme assets

The Sync theme assets action re-uploads the active theme's CSS + companion JS files to /theme-assets/ on Flexweg from the manifest's bundled cssText (with any compileCss(config) overrides applied).

It's a one-click operation when you need to:

  • Refresh the public CSS after editing theme settings
  • Recover from a partial deploy where theme-assets/ weren't uploaded
  • Re-emit the menu / posts loader scripts after they were deleted

The button lives in Themes → Sync theme assets at the top of the page.

What gets synced​

For the active theme:

FileSourceUploaded to
<theme-id>.cssTheme manifest's cssText (compiled SCSS / Tailwind), processed through compileCss(config) if available/theme-assets/<theme-id>.css
<theme-id>-menu.jsManifest's jsText (when present)/theme-assets/<theme-id>-menu.js
<theme-id>-posts.jsManifest's jsTextPosts (when present)/theme-assets/<theme-id>-posts.js

Themes that don't ship jsText or jsTextPosts skip those uploads. The default / magazine / corporate themes all ship both.

Why a sync action exists​

Theme settings (style overrides, font swaps) regenerate the CSS — but the regenerated CSS is uploaded automatically on save. So when does a manual sync help?

Cases:

  • After uploading a new admin build → the bundled CSS for built-in themes may have changed (bug fixes, new features). Sync ensures the public site uses the latest CSS.
  • Theme settings page is hidden (the active theme has no settings page) but you've manually edited the theme's source code → sync pushes your changes
  • /theme-assets/ was wiped by an erroneous Flexweg cleanup → sync re-creates them
  • A new theme was just installed → activating runs Sync automatically, but you can re-trigger if needed

What happens when you click​

The admin runs:

async function syncThemeAssets(themes, themeConfigs, log) {
for (const theme of themes) {
if (!theme.cssText) continue;

const cssPath = `theme-assets/${theme.id}.css`;
let cssContent = theme.cssText;

// Apply compileCss(config) override if the theme has one
if (theme.compileCss && theme.settings) {
const stored = themeConfigs?.[theme.id];
const resolvedConfig = {
...theme.settings.defaultConfig,
...(stored ?? {}),
};
cssContent = theme.compileCss(resolvedConfig);
}

await uploadFile({ path: cssPath, content: cssContent });

if (theme.jsText) {
await uploadFile({
path: `theme-assets/${theme.id}-menu.js`,
content: theme.jsText,
});
}
if (theme.jsTextPosts) {
await uploadFile({
path: `theme-assets/${theme.id}-posts.js`,
content: theme.jsTextPosts,
});
}
}
}

This iterates all loaded themes (active + inactive), uploading each one's assets. Inactive themes' CSS files exist on Flexweg as well — they're not referenced by any current published page, but they're available in case you switch back.

The admin shows a progress log with one entry per file. Errors are funneled through the toast system (and FlexwegApiErrors rethrown so the calling code can react).

Sync vs Regenerate​

ActionWhat it doesWhen to use
Sync theme assetsUploads theme-assets/<id>.css + -menu.js + -posts.jsAfter CSS / JS file changes
Regenerate site → All HTMLRe-renders every published HTML pageAfter template / hooks / settings changes
Regenerate site → Home page onlyRe-renders just /index.htmlAfter home-mode changes
Regenerate site → Theme assetsSame as Sync (alias)Same use cases
Regenerate site → EverythingSync + All HTML + every plugin's regen targetAfter theme switch or major settings change

If you're unsure, Everything is always safe (idempotent — running it multiple times produces the same result). It's slower for large sites but doesn't break anything.

Cache implications​

Browsers may cache /theme-assets/<id>.css aggressively (HTTP caching, CDN caching). After a sync, your visitors may keep seeing the old CSS until:

  • Their browser cache TTL expires
  • They hard-refresh (Cmd+Shift+R / Ctrl+F5)
  • The CDN cache expires (configure your CDN's TTL appropriately)

The CMS does not version the theme CSS URL with a hash (would require regenerating every published page). For most cases, browser/CDN caches respect short TTLs and refresh within minutes. For sites where this is a hard problem (you need instant CSS updates):

  • Set Flexweg's Cache-Control headers to no-cache for /theme-assets/* (if your plan supports custom headers)
  • Append ?v=<timestamp> to the link in BaseLayout (would require theme code change)
  • Or live with the eventual consistency (~few minutes)

Continue​