---
title: 'Theme component'
description: 'The Theme component is a helper component that lets you create nested theming solutions.'
version: 11.2.2
generatedAt: 2026-05-11T08:17:55.969Z
checksum: 090b7d977ba4be5e2c4c04d199a30a4048416c59f443a56985df2f80629d9c40
---

# Theme component

## Description

The Theme component is a helper component that lets you create nested theming solutions.

**NB:** `<Theme>` wraps its children in a `div` by default. Use e.g. `element="span"` to change the wrapper element, or use `Theme.Context` to skip the wrapper entirely (see below).

```tsx
import { Theme, useTheme } from '@dnb/eufemia/shared'

const Component = () => {
  const themeName = useTheme()?.name
  return 'My Component'
}

render(
  <Theme name="sbanken">
    <App>
      <MyComponent />
    </App>
  </Theme>
)
```

From CSS you can use it as so:

- `.eufemia-theme__sbanken`
- `.eufemia-theme[data-name="sbanken"]` (alternative)

**CSS**

```css
.eufemia-theme__sbanken .additional-selector {
  --color-sea-green: var(--sb-color-purple-alternative);
}
```

**SCSS**

```scss
:global(.eufemia-theme__sbanken) {
  .additional-selector {
    --color-sea-green: var(--sb-color-purple-alternative);
  }
}
```

### React Hook `useTheme`

For accessing the theme context, you can use the `useTheme` Hook. It returns the theme context, with an addition of boolean constants like `isSbanken`.

```tsx
import { Theme, useTheme } from '@dnb/eufemia/shared'

const Component = () => {
  // Result: { name: 'sbanken', isUi: false, isSbanken: true, isEiendom: false }
  const theme = useTheme()
  const { name, isUi, isSbanken, isEiendom } = theme || {}
  return null
}

render(
  <Theme name="sbanken">
    <App>
      <MyComponent />
    </App>
  </Theme>
)
```

**NB:** If no context is given, the hook will return `null`.

### Theme.Context

You can use `Theme.Context` to provide theme properties to children without adding a wrapper element. This is useful in cases where you don't want to add an extra DOM element, but still want to provide theme context to the children.

```tsx
import { Theme } from '@dnb/eufemia/shared'

render(
  <Theme.Context>
    Children that receive theme context without an extra wrapper element.
  </Theme.Context>
)
```

### Use your component as the wrapper element

You can provide your component as the wrapper. This way no additional HTML Element will be created.

```tsx
import { Theme } from '@dnb/eufemia/shared'

const Component = ({ className ...props }) => {
  return <div className={className+' more-classes'} {...props} />
}

render(
  <Theme name="theme-name">
    <App>
      <Theme name="sbanken" element={Component}>
        ...
      </Theme>
    </App>
  </Theme>
)
```

## `surface` property

The `surface` property can be used to adjust the component's appearance based on the background. It accepts three values: `dark`, `light`, and `initial`.

- Use `dark` when the content is placed on a dark surface.
- Use `light` for light surfaces.
- Use `initial` to tell the components to use its default behavior.

```tsx
import { Theme } from '@dnb/eufemia/shared'

render(
  <Section surface="dark">
    Children will use the dark surface behavior (ondark).
    <Theme.Context surface="initial">
      Children will use their default surface behavior
    </Theme.Context>
  </Section>
)
```

### How `surface` works

The `surface` prop is passed through **React context**, not through a global CSS class. When you set `surface="dark"` on a `<Theme>`, `<Theme.Context>`, or on a supporting component like [Section](/uilib/components/section/), the value is stored in the Eufemia theme context. Individual components that support dark surfaces — such as [Button](/uilib/components/button/) or [Anchor](/uilib/components/anchor/) — read the surface value from context and apply their own component-level CSS class (e.g. `dnb-button--surface-dark`, `dnb-anchor--surface-dark`).

Wrap an area with `<Theme.Context>` or `<Section>` to propagate the surface context to all supporting components inside:

```jsx
<Theme.Context surface="dark">
  <Button>I adapt automatically</Button>
  <Anchor href="/path">So do I</Anchor>
</Theme.Context>
```

Use `surface="initial"` to reset components back to their default behavior inside a dark surface context:

```jsx
<Section surface="dark">
  <Button>Dark surface button</Button>
  <Theme.Context surface="initial">
    <Button>Default surface button</Button>
  </Theme.Context>
</Section>
```

## The `colorScheme` property (Dark mode)

The `Theme` component accepts a `colorScheme` prop that controls dark and light mode.

When set to `"auto"`, it follows the user's system color preference unless overridden by a parent theme or application setting. It uses the [`prefers-color-scheme`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/prefers-color-scheme) media query to detect the system preference.

Dark mode tokens are not included in the default theme import. Import the extra dark mode stylesheet before using `colorScheme`:

```tsx
import { Theme } from '@dnb/eufemia/shared'

// Required: import dark mode tokens
import '@dnb/eufemia/style/themes/ui/ui-theme-dark-mode--isolated.min.css' // If style isolation is used

render(
  <Theme colorScheme="auto">
    <App />
  </Theme>
)
```

For guidance on choosing between base, `inverse`, and `ondark` token variants in your own components, see the [Design Tokens dark mode guide](/uilib/usage/customisation/theming/design-tokens/dark-mode).

## Persisting the theme with `getTheme` and `setTheme`

Eufemia provides `getTheme` and `setTheme` helpers that persist theme state (including `colorScheme`) to `localStorage` under the key `eufemia-theme`.

```tsx
import { getTheme, setTheme } from '@dnb/eufemia/shared/Theme'

// Read the current persisted theme
const theme = getTheme()
// { name: 'ui', colorScheme: 'auto', ... }

// Update one or more properties (merges with existing state)
setTheme({ colorScheme: 'dark' })

// With a callback
setTheme({ name: 'sbanken' }, (updatedTheme) => {
  console.log(updatedTheme)
})
```

`getTheme` also supports a `?eufemia-theme=<name>` URL query parameter, which overrides the persisted theme name. This is useful for testing or previewing themes via a link.

### Preventing dark mode flash (FOUC)

When using `colorScheme="system"`, the resolved color scheme depends on the user's system preference, which is only available in the browser. During server-side rendering (SSR), this can cause a brief flash of the wrong color scheme before React hydrates.

To prevent this, Eufemia provides blocking scripts that run synchronously before the browser paints. They read the stored preference from `localStorage` and apply the correct CSS classes immediately.

```tsx
import {
  ColorSchemeHeadScript,
  ColorSchemeBodyFirstScript,
  ColorSchemeBodyLastScript,
} from '@dnb/eufemia/shared/ColorSchemeScript'
```

Place them in your HTML template as follows:

```tsx
<html>
  <head>
    <ColorSchemeHeadScript />
  </head>
  <body>
    <ColorSchemeBodyFirstScript />
    {/* your app content */}
    <ColorSchemeBodyLastScript />
  </body>
</html>
```

- **`ColorSchemeHeadScript`** — Resolves the color scheme from `localStorage` (or falls back to the system preference) and stores it on `globalThis`. Place in `<head>`.
- **`ColorSchemeBodyFirstScript`** — Adds the resolved color-scheme class to `<body>`. Place as the first child of `<body>`.
- **`ColorSchemeBodyLastScript`** — Swaps color-scheme classes on server-rendered `Theme` elements so they match the resolved scheme. Place as the last child of `<body>`.

### Hide or show parts of your component (filter)

With this helper function you show or hide content based on inherited theme properties.

```tsx
import { Theme, VisibilityByTheme } from '@dnb/eufemia/shared'

render(
  <Theme name="...">
    
      Only shown in Sbanken theme
    

    
      Only hidden in Eiendom theme
    

    
      Only shown in Sbanken or Eiendom theme
    

    
      Only shown in Sbanken or Eiendom theme
    

    
      Only shown in Sbanken then or Eiendom theme – that also includes the
      fictive variant="blue".
    
  </Theme>
)
```

### Integrations

When integrating runtime theme switching, your app can be wrapped with this theme component.

## Properties


```json
{
  "props": {
    "name": {
      "doc": "The name of a branding theme. Can be `ui` (universal identity), `eiendom`, `sbanken` or `carnegie`.",
      "type": [
        "\"ui\"",
        "\"eiendom\"",
        "\"sbanken\"",
        "\"carnegie\""
      ],
      "status": "optional"
    },
    "size": {
      "doc": "Will define what sizes of components are used (WIP).",
      "type": "\"basis\"",
      "status": "optional"
    },
    "variant": {
      "doc": "(WIP).",
      "type": "string",
      "status": "optional"
    },
    "contrastMode": {
      "doc": "When a component supports a contrast style, it will be used instead for the dedicated area.",
      "type": "boolean",
      "status": "optional"
    },
    "colorScheme": {
      "doc": "Controls the color scheme. Use `auto` to follow system preference and switch automatically between light and dark, `light` for light mode, `dark` for dark mode, or `inherit` to inherit from a parent Theme. Defaults to `undefined`.",
      "type": [
        "\"auto\"",
        "\"light\"",
        "\"dark\"",
        "\"inherit\""
      ],
      "status": "optional"
    },
    "surface": {
      "doc": "Adjusts component appearance based on background. Use `dark` when content is placed on a dark surface, `light` for light, or `initial` to reset to the component's default behavior, ignoring any parent surface context. Defaults to `undefined`.",
      "type": [
        "\"dark\"",
        "\"light\"",
        "\"initial\""
      ],
      "status": "optional"
    }
  }
}
```
