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:
| File | Source | Uploaded to |
|---|---|---|
<theme-id>.css | Theme manifest's cssText (compiled SCSS / Tailwind), processed through compileCss(config) if available | /theme-assets/<theme-id>.css |
<theme-id>-menu.js | Manifest's jsText (when present) | /theme-assets/<theme-id>-menu.js |
<theme-id>-posts.js | Manifest'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
| Action | What it does | When to use |
|---|---|---|
| Sync theme assets | Uploads theme-assets/<id>.css + -menu.js + -posts.js | After CSS / JS file changes |
| Regenerate site → All HTML | Re-renders every published HTML page | After template / hooks / settings changes |
| Regenerate site → Home page only | Re-renders just /index.html | After home-mode changes |
| Regenerate site → Theme assets | Same as Sync (alias) | Same use cases |
| Regenerate site → Everything | Sync + All HTML + every plugin's regen target | After 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-Controlheaders tono-cachefor/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
- Theme settings — what triggers automatic syncs
- Switching themes — runs Sync as part of the switch
- Operations: troubleshooting — when public site CSS is stale