Theming CMS content
When a CMS section carries its own colours, wrap it in a <Theme> boundary. If the palette is
one of a known set, pre-register the themes; if it is arbitrary editor input, build the theme at
runtime with createTheme.
Known brands: pre-register
When the CMS picks from a fixed list of brand themes — a marketing site with a handful of campaign palettes — register every theme on the provider and switch per section by name.
section.themeName is whatever the CMS stored — 'spring', 'autumn'. <Theme> sets a new
data-theme on its wrapper; the CSS variables for every registered theme are already on the
page, so each section repaints with no re-render. An unregistered name falls back to the parent
theme rather than throwing.
Arbitrary palettes: build at runtime
When an editor picks colours freely — a per-author blog, a white-label tenant — there is no fixed
list to register. Build a theme from the CMS payload with createTheme, memoised so it is not
rebuilt on every render.
The useMemo dependency is brand, so the theme rebuilds only when the tenant changes. Without
it, every render allocates a fresh theme object and the provider re-emits its <style> block.
Sanitise editor input
CMS colour values reach createTheme as untrusted strings. A token value lands in a CSS
variable; a malformed value yields a variable that does not parse — visually broken, not a
security hole, but worth catching early.
Run every CMS colour through a validator before it reaches createTheme, and fall back to a base
token when it fails. Restrict the editor to a colour picker that emits hex where you can — the
narrower the input, the smaller the validator.