Skip to content
+

InitColorSchemeScript

The InitColorSchemeScript component eliminates dark mode flickering in server-side-rendered applications.

Introduction

The InitColorSchemeScript component is used to remove the dark mode flicker that can occur in server-side-rendered (SSR) applications. This script runs before React to attach an attribute based on the user preference so that the correct color mode is applied on first render.

For the best user experience, you should implement this component in any server-rendered Material UI app that supports both light and dark modes.

Basics

First, enable CSS variables with colorSchemeSelector: 'data' in your theme.

import { ThemeProvider, createTheme } from '@mui/material/styles';

const theme = createTheme({
  cssVariables: {
    colorSchemeSelector: 'data',
  },
});

function App() {
  return <ThemeProvider theme={theme}>{/* Your app */}</ThemeProvider>;
}

Then, render the InitColorSchemeScript component as the first child of the <body> tag.

The sections below detail where to render the InitColorSchemeScript component when working with Next.js.

Next.js App Router

Place the InitColorSchemeScript component in the root layout file:

src/app/layout.tsx
import InitColorSchemeScript from '@mui/material/InitColorSchemeScript';

export default function RootLayout(props: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <InitColorSchemeScript />
        {props.children}
      </body>
    </html>
  );
}

Next.js Pages Router

Place the InitColorSchemeScript component in a custom _document file:

pages/_document.tsx
import { Html, Head, Main, NextScript } from 'next/document';
import InitColorSchemeScript from '@mui/material/InitColorSchemeScript';

export default function MyDocument(props) {
  return (
    <Html lang="en">
      <Head>{/* tags */}</Head>
      <body>
        <InitColorSchemeScript />
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

Customization

Class attribute

To attach classes to DOM elements, set the attribute prop to "class".

<InitColorSchemeScript attribute="class" />

This sets the class name on the color scheme node (which defaults to <html>) according to the user's system preference.

<html class="dark"></html>

Arbitrary attribute

To attach arbitrary attributes to DOM elements, use %s as a placeholder on the attribute prop.

<InitColorSchemeScript attribute="[data-theme='%s']" /> // <html data-theme="dark">
<InitColorSchemeScript attribute=".mode-%s" /> // <html class="mode-dark">

Default mode

Set the defaultMode prop to specify the default mode when the user first visits the page.

For example, if you want users to see the dark mode on their first visit, set the defaultMode prop to "dark".

<InitColorSchemeScript defaultMode="dark" />

Caveats

Attribute

When customizing the attribute prop, make sure to set the colorSchemeSelector in the theme to match the attribute you are using.

const theme = createTheme({
  cssVariables: {
    colorSchemeSelector: 'same value as the `attribute` prop',
  },
});

Default mode

When customizing the defaultMode prop, make sure to do the same with the ThemeProvider component:

<ThemeProvider theme={theme} defaultMode="dark">

API

See the documentation below for a complete reference to all of the props and classes available to the components mentioned here.