Plugin SDK

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-scheme attribute: use it in CSS selectors like [data-color-scheme="dark"] .my-panel

  • color-scheme CSS property: enables light-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:

Terminal window
npm install datocms-react-ui@latest datocms-plugin-sdk@latest

Then 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 CSScolor: #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 style props with color values — treat the same as hardcoded CSS.3. Replace deprecated CSS variables (optional now, required later)

Migration
  1. If your plugin reads ctx.theme directly to build colors or styles, migrate to ctx.cssDesignTokens.

  2. Replace the legacy CSS variables with the new semantic equivalents from the table below.

Legacy CSS variableReplace 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)
A few edge cases

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

Last updated: