Skip to content

Theme Helper

To make managing the active theme easier, we provide a helper class to get, set and toggle the theme. Additionally, you can provide callbacks for when the theme gets changed!

script.ts
import {
class ThemeHelper

A helper to toggle, set and get the current StudioCMS UI theme.

ThemeHelper
} from '@studiocms/ui/utils/ThemeHelper.ts';
// Instanciate a new helper
const
const themeHelper: ThemeHelper
themeHelper
= new
new ThemeHelper(themeProvider?: HTMLElement): ThemeHelper

A helper to toggle, set and get the current StudioCMS UI theme.

@paramthemeProvider The element that should carry the data-theme attribute (replaces the document root)

ThemeHelper
();
// Get the current theme. (One of `dark`, `light` or `system`)
const
const theme: Theme
theme
=
const themeHelper: ThemeHelper
themeHelper
.
ThemeHelper.getTheme: <boolean>(resolveSystemTheme?: boolean | undefined) => Theme

Get the current theme.

@paramresolveSystemTheme Whether to resolve the system theme to the actual theme (dark or light)

@returnsThe current theme.

getTheme
();
// Get the current theme but resolve the actual theme if `system` is selected
const
const resolvedTheme: "dark" | "light"
resolvedTheme
=
const themeHelper: ThemeHelper
themeHelper
.
ThemeHelper.getTheme: <true>(resolveSystemTheme?: true | undefined) => "dark" | "light"

Get the current theme.

@paramresolveSystemTheme Whether to resolve the system theme to the actual theme (dark or light)

@returnsThe current theme.

getTheme
(true);
// Set the theme to light
const themeHelper: ThemeHelper
themeHelper
.
ThemeHelper.setTheme: (theme: Theme) => void

Sets the current theme.

@paramtheme The new theme. One of dark, light or system.

setTheme
('light');
// Toggle the theme
const themeHelper: ThemeHelper
themeHelper
.
ThemeHelper.toggleTheme: () => void

Toggles the current theme.

If the theme is set to system (or no theme is set via the root element), the theme is set depending on the user's color scheme preference (set in the browser).

toggleTheme
();
// Register an element that should act as a toggle
const
const toggleButton: any
toggleButton
=
any
document
.
any
querySelector
<
type HTMLButtonElement = /*unresolved*/ any
HTMLButtonElement
>('#toggle-button');
const themeHelper: ThemeHelper
themeHelper
.
ThemeHelper.registerToggle: (toggle: HTMLElement | null) => void

Register an element to act as a toggle! When clicked, it will toggle the theme.

@paramtoggle The HTML element that should act as the toggle

registerToggle
(
const toggleButton: any
toggleButton
);

Using the ThemeHelper class, you can listen to theme changes! This is useful when you have logic that needs to run whenever the color scheme changes, for example in a three.js canvas where you need to change an image (*cough cough* our login page *cough*).

script.ts
import {
class ThemeHelper

A helper to toggle, set and get the current StudioCMS UI theme.

ThemeHelper
} from '@studiocms/ui/utils/ThemeHelper.ts';
// Instanciate a new helper
const
const themeHelper: ThemeHelper
themeHelper
= new
new ThemeHelper(themeProvider?: HTMLElement): ThemeHelper

A helper to toggle, set and get the current StudioCMS UI theme.

@paramthemeProvider The element that should carry the data-theme attribute (replaces the document root)

ThemeHelper
();
// Add a callback that gets called when the theme changes
const themeHelper: ThemeHelper
themeHelper
.
ThemeHelper.onThemeChange: (callback: ThemeChangeCallback) => void

Allows for adding a callback that gets called whenever the theme changes.

@paramcallback The callback to be executed

onThemeChange
((
newTheme: Theme
newTheme
) => {
// Your logic here!
});

Here’s a live example: Change the theme via the option in the top-right corner of your screen. If you’re on mobile, open the navbar and scroll all the way down. After you’ve changed the theme, check the text below:

Theme hasn’t changed yet.

Since @studiocms/ui is compatible with Starlight’s theme system, this even picks up on those changes.

One of the few things the ThemeHelper does not do is saving the users theme preference. This is by design, since we don’t want to force websites operating in the EU (and other GDPR-enforcing countries) to have to add a cookie notice just for a UI library. Instead, implementation of this functionality is up to the developers themselves.

As a starting point, here’s a barebones example of how to implement this:

Script Tag
import {
class ThemeHelper

A helper to toggle, set and get the current StudioCMS UI theme.

ThemeHelper
, type
type Theme = "dark" | "light" | "system"
Theme
} from '@studiocms/ui/utils/ThemeHelper.ts';
const
const themeHelper: ThemeHelper
themeHelper
= new
new ThemeHelper(themeProvider?: HTMLElement): ThemeHelper

A helper to toggle, set and get the current StudioCMS UI theme.

@paramthemeProvider The element that should carry the data-theme attribute (replaces the document root)

ThemeHelper
();
const themeHelper: ThemeHelper
themeHelper
.
ThemeHelper.onThemeChange: (callback: ThemeChangeCallback) => void

Allows for adding a callback that gets called whenever the theme changes.

@paramcallback The callback to be executed

onThemeChange
((
newTheme: Theme
newTheme
:
type Theme = "dark" | "light" | "system"
Theme
) => {
any
localStorage
.
any
setItem
('theme-selection',
newTheme: Theme
newTheme
);
});

If you want to go even further, you can store this information in a cookie to retrieve it server-side.