💦
DarkMode切替機能のハイドレーションミスマッチの対応策(Next.js + NextUI)
概要
Next.jsでNextUIのテーマ(DarkMode)切替機能を実装した際と限定していますが、
テーマ(DarkMode)切替機能を追加するとUIライブラリに関係なくブラウザのコンソールに出る警告
Warning: Extra attributes from the server: class,style
の対応策と注意点の記事になります。
テーマ(DarkMode)切替機能を追加するとブラウザに以下エラーが出力される
Edge(Chromium) console
app-index.tsx:25
Warning: Extra attributes from the server: class,style
at html
at RootLayout (Server)
at RedirectErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:74:9)
at RedirectBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/redirect-boundary.js:82:11)
at NotFoundErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/not-found-boundary.js:76:9)
at NotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/not-found-boundary.js:84:11)
at DevRootNotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/dev-root-not-found-boundary.js:33:11)
at ReactDevOverlay (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/react-dev-overlay/app/ReactDevOverlay.js:87:9)
at HotReload (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/react-dev-overlay/app/hot-reloader-client.js:321:11)
at Router (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/app-router.js:207:11)
at ErrorBoundaryHandler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/error-boundary.js:113:9)
at ErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/error-boundary.js:160:11)
at AppRouter (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/app-router.js:577:13)
at ServerRoot (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/app-index.js:112:27)
at Root (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/app-index.js:117:11)
原因
サーバーとクライアントの間でハイドレーションの不一致が起こるため
今回の例では、サーバーで生成したときは無かったclass, styleがRootLayout(Server)のhtmlタグに追加されてる為。
これはDarkModeなどのテーマを切り替えるような場合、使用しているUIライブラリに関係なく起こります。
対応策
根本的な解決策はないが、エラーの抑制をする事で対応する。
実行
app/layout.tsx
のhtmlタグにsuppressHydrationWarning={true}
を追加します。
app/layout.tsx
// 省略
export default function RootLayout({
// 省略
return (
+ <html lang="ja" suppressHydrationWarning={true}>
- <html lang="ja">
<body className={zen.className}>
<NextuiThemeProviders>
<Suspense fallback={<Loading />}>{children}</Suspense>
</NextuiThemeProviders>
</body>
</html>
);
}
Discussion