Leave Yamada UI a star

Star
Yamada UIYamada UIv1.6.4

Switching Themes

Yamada UI provides the functionality for users to switch themes.

Setup

To switch themes, users must do the following two things:

  1. Prepare multiple themes
  2. Add ThemeSchemeScript to the application.

Prepare multiple themes

This time, we will prepare several themes with colors changed from the default theme.

Pass an object to themeSchemes. The keys of this object will be the themeScheme required to switch themes.

import { extendTheme } from "@yamada-ui/react"
export const theme = extendTheme({
themeSchemes: {
pink: {
semantics: {
colors: { primary: "pink.500" },
colorSchemes: { primary: "pink" },
},
},
purple: {
semantics: {
colors: { primary: "purple.500" },
colorSchemes: { primary: "purple" },
},
},
green: {
semantics: {
colors: { primary: "green.500" },
colorSchemes: { primary: "green" },
},
},
},
})()
Copied!

If you want to use any of the themes passed in themeSchemes by default, set the initial value in the config's initialThemeScheme.

import { extendTheme, extendConfig } from "@yamada-ui/react"
export const theme = extendTheme({
themeSchemes: {
pink: {
semantics: {
colors: { primary: "pink.500" },
colorSchemes: { primary: "pink" },
},
},
purple: {
semantics: {
colors: { primary: "purple.500" },
colorSchemes: { primary: "purple" },
},
},
green: {
semantics: {
colors: { primary: "green.500" },
colorSchemes: { primary: "green" },
},
},
},
})()
export const config = extendConfig({
initialThemeScheme: "pink",
})
Copied!

Add ThemeSchemeScript

To switch themes correctly, you need to add ThemeSchemeScript within the head or body.

The reason is that theme switching is implemented using localStorage or cookies, and it is necessary to synchronize correctly at the time of page loading.

For Create React App

index.tsx

import { createRoot } from "react-dom/client"
import { App } from "./app"
import { UIProvider, getThemeSchemeScript } from "@yamada-ui/react"
import { theme, config } from "./theme"
const injectThemeSchemeScript = () => {
const scriptContent = getThemeSchemeScript({
initialThemeScheme: config.initialThemeScheme,
})
const script = document.createElement("script")
script.textContent = scriptContent
document.head.appendChild(script)
}
injectThemeSchemeScript()
const container = document.getElementById("app")
const root = createRoot(container!)
root.render(
<UIProvider theme={theme} config={config}>
<App />
</UIProvider>,
)
Copied!

For Next.js

_document.tsx

import { Html, Head, Main, NextScript } from "next/document"
import { ThemeSchemeScript } from "@yamada-ui/react"
import { config } from "../theme"
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<ThemeSchemeScript initialThemeScheme={config.initialThemeScheme} />
<Main />
<NextScript />
</body>
</Html>
)
}
Copied!

Depending on the project, you may need to retrieve values from cookies. In that case, use createThemeSchemeManager("cookie").

_document.tsx

import { Html, Head, Main, NextScript } from "next/document"
import { ThemeSchemeScript } from "@yamada-ui/react"
import { config } from "../theme"
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<ThemeSchemeScript
type="cookie"
nonce="testing"
initialThemeScheme={config.initialThemeScheme}
/>
<Main />
<NextScript />
</body>
</Html>
)
}
Copied!

_app.tsx

import type { AppProps } from "next/app"
import { UIProvider, createThemeSchemeManager } from "@yamada-ui/react"
import { config } from "../theme"
const themeSchemeManager = createThemeSchemeManager("cookie")
export default function App({ Component, pageProps }: AppProps) {
return (
<UIProvider
theme={theme}
config={config}
themeSchemeManager={themeSchemeManager}
>
<Component {...pageProps} />
</UIProvider>
)
}
Copied!

Add themeSchemeManager

For sites rendered on the server side, such as Next.js, you may want to include the theme schema in the request to avoid changing the theme during hydration.

Prepare getServerSideProps

To standardize getServerSideProps across multiple pages, define getServerSideCommonProps.

import { GetServerSidePropsContext } from "next"
export const getServerSideCommonProps = ({
req,
}: GetServerSidePropsContext) => {
return {
props: {
cookies: req.headers.cookie ?? "",
},
}
}
Copied!

Set cookies in themeSchemeManager

Set ssr and cookies in createThemeSchemeManager.

_app.tsx

import type { AppProps } from "next/app"
import { UIProvider, createThemeSchemeManager } from "@yamada-ui/react"
export default function App({ Component, pageProps }: AppProps) {
const { cookies } = pageProps
const themeSchemeManager = createThemeSchemeManager("ssr", cookies)
return (
<UIProvider themeSchemeManager={themeSchemeManager}>
<Component {...pageProps} />
</UIProvider>
)
}
Copied!

Add getServerSideProps

Add the previously created getServerSideCommonProps to each page.

index.tsx

import { getServerSideCommonProps } from "../get-server-side-props.ts"
import { Button } from "@yamada-ui/react"
export default function Index() {
return <Button>Click me!</Button>
}
export const getServerSideProps = getServerSideCommonProps
Copied!

Switching Themes

To switch themes, use changeThemeScheme. If you want to revert to the original themeScheme, pass base.

Editable example

const { themeScheme, changeThemeScheme } = useTheme()

return (
  <>
    <Text>The current scheme is "{themeScheme}"</Text>

    <Wrap mt="md" gap="md">
      <Button onClick={() => changeThemeScheme("base")}>Base Theme</Button>

      <Button colorScheme="pink" onClick={() => changeThemeScheme("pink")}>
        Pink Theme
      </Button>

      <Button colorScheme="purple" onClick={() => changeThemeScheme("purple")}>
        Purple Theme
      </Button>

      <Button colorScheme="green" onClick={() => changeThemeScheme("green")}>
        Green Theme
      </Button>
    </Wrap>
  </>
)
Copied!

Edit this page on GitHub

PreviousComponent StylesNextConfigure