Dashboard beta

Match the Dashboard's color scheme

Follow the Dashboard's light or dark mode in your app, panels, and tiles with Sanity UI v4 or any other styling library.

Users switch the Dashboard between light and dark mode, or have it follow their operating system, from the account menu. Your app renders inside the Dashboard's page, so match its color scheme to fit in. Read the scheme with useTopic('preferences.color-scheme') from @sanity/sdk-react/dashboard.

Requirements

  • @sanity/sdk-react 3.9.0 or later.
  • An app configured with defineApplication, running under sanity dev or deployed with it.

Read the color scheme

preferences.color-scheme is 'light' or 'dark'. When the user chooses System, the Dashboard resolves it from the operating system, so your app always receives one of the two. The hook suspends until the Dashboard sends the first value, and re-renders your component whenever the user changes the setting.

Apply it to Sanity UI v4

This example uses @sanity/ui v4, which the Sanity UI template installs. Pass the scheme to the scheme prop of ThemeProvider. useTopic needs an App SDK instance, so render ThemeProvider inside SanityApp:

SanityApp renders its fallback before ThemeProvider mounts, so don't use @sanity/ui components in the fallback.

Apps created from the Sanity UI template wrap SanityApp in a ThemeProvider in src/SanityUI.tsx. Move the ThemeProvider inside SanityApp so it can read the scheme.

Apply it to other styling libraries

The same approach works with any styling library: read the scheme from the Dashboard, then pass it to whatever your library uses to switch modes. Follow these rules:

  • Read the scheme with useTopic, not from prefers-color-scheme or the library's own detection. The user's Dashboard setting can differ from their operating system.
  • Pass the scheme to the library's mode setting, such as a theme provider's mode or color scheme option.
  • Scope it to your app's root element. Your app renders into the Dashboard's page rather than its own document, so don't let the library change document.documentElement, document.body, or global styles. Turn off any global CSS reset the library applies, or use its scoped version.
  • Pass the value straight through instead of copying it into state. useTopic re-renders your component whenever the user changes the setting.

Plain CSS

Put the scheme on a root element as a data attribute, and define your colors for each scheme:

Render SchemeRoot inside SanityApp. The color-scheme property also switches browser-drawn elements such as scrollbars and form controls.

Tailwind CSS v4

Point Tailwind's dark variant at the same data attribute, then use dark: utilities inside SchemeRoot:

Match the color scheme in panels and tiles

Panel components, panel titles, and tiles each render in their own island, so add the theme to the Providers component that wraps them:

Next steps

Was this page helpful?