Themes for Next.js, safe, no hydration errors.
npm install next-safe-themesThemes for Next.js, safe, no hydration errors.
* ✅ Any number of themes with a default one
* ✅ Sync with multiple tabs
* ✅ Supports Next.js app router
* ✅ No flash on load
* ✅ Server rendering
* ✅ No hydration errors
* ✅ Custom configurations
* ✅ useTheme hook
I can't find yet another theming library for Next.js besides next-themes.
Next-themes has hydration errors. It encourage developers to putsuppressHydrationWarning on the root HTML tag. And it encourage developers to
flash the theme switch after page loaded. I want my website to render correctly.
Thus, I created this library.
``sh`
npm i next-safe-themes
Follow these steps, to theme your website without hydration errors.
Update your src/middleware.ts like this.
`ts
import { createThemesMiddleware } from 'next-safe-themes/server/middleware'
const themesMiddleware = createThemesMiddleware(yourPreviousMiddleware)
export function middleware(request: NextRequest) {
return themesMiddleware(request)
}
`
Update your layout file like this.
`ts
import { headers } from "next/headers"
import { getTheme } from "next-safe-themes/server/theme"
import { htmlThemeProps } from "next-safe-themes/props"
import { ThemeProvider } from "next-safe-themes/client/provider"
export default async function Layout({ children }) {
// 1. get theme from middleware updated headers
const theme = getTheme(await headers())
// 2. render HTML attributes with the theme value
return
$3
Next-safe-themes provides a hook for you to write your custom theme switch.
`ts
const MyThemeSwitch = () => {
const [theme, setTheme] = useTheme()
return
Current theme is: {theme}
}
`Configuration
You can customize the generated HTML attributes. Pass this configuration object
as the second parameter to
htmlThemeProps and ThemeProvider.`ts
const themeConfig = {
dataTheme: true, // data-theme="light"
class: true, // class="light"
additionalClassPrefix: "scheme-", // class="scheme-light"
style: true, // style="color-scheme: light;"
}
`Do not specify all 4, normally you may need 2 of them according to your CSS
settings.
Pass the config to the functions like this.
`ts
export default async function Layout({ children }) {
return
...
{children}
}
``MIT License.