結論
もし他のサイトで書いてあることをやって直らないのであれば--webpackを使って開発サーバーを Webpack で起動する
始まり
普段のようにサーバーを起動すると以下のようなエラーがでてくる。
Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:
- A server/client branch `if (typeof window !== 'undefined')`.
- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.
- Date formatting in a user's locale which doesn't match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.
It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.
See more info here: https://nextjs.org/docs/messages/react-hydration-error
...
<RedirectBoundary>
<RedirectErrorBoundary router={{...}}>
<Head>
<__next_root_layout_boundary__>
<SegmentViewNode type="layout" pagePath="layout.tsx">
<SegmentTrieNode>
<link>
<script>
<script>
<script>
<script>
<script>
<script>
<script>
<RootLayout>
<html lang="ja" className="roboto_589..." suppressHydrationWarning={true}>
<body suppressHydrationWarning={true}>
<Provider>
<ChakraProvider value={{$$chakra:true, ...}}>
<EmotionGlobal>
<EmotionGlobal>
<ColorModeProvider>
<J attribute="class" disableTransitionOnChange={true}>
<V attribute="class" disableTransitionOnChange={true}>
+ <script
+ suppressHydrationWarning={true}
+ nonce=""
+ dangerouslySetInnerHTML={{__html:"((e, i, s,..."}}
+ >
- <style data-emotion="css-global ad1llf" data-s="">
...
...
components/ui/color-mode.tsx (17:5) @ ColorModeProvider
15 | export function ColorModeProvider(props: ColorModeProviderProps) {
16 | return (
> 17 | <ThemeProvider attribute="class" disableTransitionOnChange {...props} />
| ^
18 | )
19 | }
20 |
リロードすると一応エラーは出てこなくはなりますがいかんせん毎回これがでてはどうしようもありません
そこでこのエラーを解消する方法を調べて見ることにしました
試した解決方法
supressHydrationWarning を<html />だけではなく<body />にもかく
<html
lang="ja"
className={`${roboto.variable} ${notosansjp.variable}`}
suppressHydrationWarning
>
<body suppressHydrationWarning>
結構これを書いている記事もあったのですが直りませんでした
マウントしてからレンダリングする
具体的には以下のコードを使いました
export function ColorModeProvider(props: ColorModeProviderProps) {
const [mounted, setMounted] = useState<boolean>(false);
useEffect(() => {
setMounted(true);
return () => setMounted(false);
}, []);
if (!mounted) {
return null;
}
return (
<ThemeProvider attribute="class" disableTransitionOnChange {...props} />
);
}
一応これで直るは直るんですけどSSRが全部真っ白な画面になるので再読み込みボタンを押すために真っ白な画面が出てきてユーザーの目を潰すことになります
一応シークレットモードで動かしてみる
普通に Hydration Error がでてきたので拡張機能は原因ではありませんでした
Re: 結論
Chakra UI は --turbo オプションを付けないでとかいてあります。
しかし Next.js 16 ではデフォルトのバンドラーとしてTurbopackを使うようになりました
なのでpackage.jsonのdevのところにnext dev --webpackと書いて Webpack で起動してみてください
以下に Turbopack と Hydration Error についてのっています
余談
私のサイトは別に Next.js を絶対に使わないといけないわけでもないし Chakra UI もデザインは好きでしたがこのようなことがありますし Next.js から React Router v7 もしくは Chakra UI から Shadcn UI にのりかえる予定です