Upgrading plugins for dark mode
This guide covers upgrading a plugin from datocms-react-ui / datocms-plugin-sdk v2.1.5 (the last release without dark-mode support) to the new version that introduces semantic color tokens and full theme-aware rendering.
What changes
New semantic color tokens
Canvas has always injected a small set of CSS variables onto its wrapper div (--accent-color, --primary-color, --light-color, --dark-color). Newer versions expand that to full semantic palette. The host computes every token for the active theme and sends them via the new ctx.cssDesignTokens field; Canvas applies them verbatim.
All built-in components (Button, TextInput, Section, Dropdown, Toolbar, …) have been updated to use these tokens and now adapt to the active theme automatically.
New ctx.colorScheme
The new ctx.colorScheme property is either 'light' or 'dark'. For non-CSS decisions (image sources, syntax-highlighting presets, third-party widget themes) branch on ctx.colorScheme directly:
<img src={ctx.colorScheme === 'dark' ? logoDark : logoLight} />The SDK also reflects this onto document.documentElement in two ways:
data-color-schemeattribute: use it in CSS selectors like[data-color-scheme="dark"] .my-panelcolor-schemeCSS property: enableslight-dark()and makes native form controls/scrollbars match.
Deprecated: ctx.theme and the legacy CSS variables
ctx.theme is still present and its shape is unchanged, but the host now pins it to light-mode values only, regardless of what theme the user has selected. The CSS variables derived from it (--accent-color, --primary-color, --light-color, --dark-color, --semi-transparent-accent-color) likewise always emit light values. The older structural CSS variables emitted by Canvas (--base-body-color, --border-color, --alert-color, etc.) are also deprecated.
Upgrade steps
Option 1: Let an AI agent do it
The migration is entirely mechanical: bump the dependency, swap CSS variable names, replace hardcoded colors with semantic tokens. There are no judgment calls that require human review.
Copy the prompt below and paste it into Codex, Claude Code, or any other AI coding agent, and it will handle the full upgrade and verify the result in dark mode.
Option 2: Do it manually
Update your dependencies:
npm install datocms-react-ui@latest datocms-plugin-sdk@latestThen open the DatoCMS app in dark mode and open your plugin — it will now render with dark colors. Things to audit:
Hardcoded colors in your CSS —
color: #333,background: white, etc. They won't follow the theme and contrast will break.Hardcoded SVG fills in custom icons — switch to
fill="currentColor"so they inherit the surrounding text color.Custom CSS mixed with library components — verify the combinations look right in both light and dark.
Inlined
styleprops with color values — treat the same as hardcoded CSS.3. Replace deprecated CSS variables (optional now, required later)
Migration
If your plugin reads
ctx.themedirectly to build colors or styles, migrate toctx.cssDesignTokens.Replace the legacy CSS variables with the new semantic equivalents from the table below.
| Legacy CSS variable | Replace with |
|---|---|
| --base-body-color | --color--ink |
| --light-body-color | --color--ink-subtle |
| --placeholder-body-color | --color--ink-placeholder |
| --light-bg-color | --color--surface-muted |
| --lighter-bg-color | --color--surface-muted |
| --disabled-bg-color | --color--disabled--surface |
| --border-color | --color--border |
| --darker-border-color | --color--border-hover |
| --alert-color (as text) | --color--danger-soft--ink |
| --alert-color (as background) | --color--danger-soft--surface |
| --warning-color | --color--warning-soft--ink |
| --notice-color | --color--success-soft--ink |
| --warning-bg-color | --color--warning-soft--surface |
| --add-color (as background) | --color--diff-added--surface |
| --remove-color (as background) | --color--diff-removed--surface |
| --accent-color (as background) | --color--primary--surface-secondary |
| --accent-color (as text) | --color--ink-link |
| --primary-color | --color--primary--surface |
| --light-color | --color--primary-soft--surface |
| --dark-color | --color--primary--surface (or --color--primary--ink if used as text) |
| --semi-transparent-accent-color | --color--focus--outline (focus rings) |
--alert-color, --add-color, and --remove-color were used as both foreground and background in the wild. Pick the semantic token that matches your actual usage.
Migrate the accent group even if you only support light mode today. --accent-color, --primary-color, --light-color, --dark-color, and --semi-transparent-accent-color are derived from ctx.theme, which is now pinned to light values only. They will be removed in a future major.