Next.js 15 搭配 Chakra UI 3 使用RootLayout时Hydration失败问题求助
Next.js 15 + Chakra UI 3 Hydration 不匹配错误解决办法及SSR配置规范
你遇到的Hydration错误是当前Chakra UI 3与Next.js 15 Turbopack存在兼容性问题导致的,官方正在修复,以下是临时修复方案和标准SSR配置建议:
临时修复方案
- 暂时停用Turbopack:使用
next dev启动开发服务器,避开兼容性问题,等待Chakra UI官方发布修复版本。 - 用Suspense包裹客户端Provider:在RootLayout中给Chakra的Provider组件加上Suspense边界,让客户端完成 hydration 后再渲染客户端组件,避免服务器与客户端HTML不匹配。修改后的RootLayout代码如下:
import { Provider } from '@/components/ui/provider'; import { Suspense } from 'react'; export default function RootLayout({ children }) { return ( <html suppressHydrationWarning> <body> <Suspense fallback={null}> <Provider>{children}</Provider> </Suspense> </body> </html> ); }
- 检查ColorModeProvider实现:如果你的ColorModeProvider中直接使用了
window或localStorage等客户端API,需要将这类逻辑移到useEffect或Next.js提供的useIsClient钩子中执行,确保服务器渲染时不会执行客户端专属代码。示例:
'use client'; import { useIsClient } from 'next/client'; import { useEffect, useState } from 'react'; export function ColorModeProvider({ children }) { const isClient = useIsClient(); const [colorMode, setColorMode] = useState('light'); useEffect(() => { if (isClient) { const savedMode = localStorage.getItem('chakra-color-mode'); if (savedMode) setColorMode(savedMode); } }, [isClient]); // 其他颜色模式逻辑... return <div>{children}</div>; }
标准Next.js + Chakra UI SSR配置规范
- RootLayout保持为服务器组件:不要给RootLayout添加
'use client'指令,确保服务器能正常渲染根HTML结构。 - ChakraProvider必须放在客户端组件内:ChakraProvider依赖客户端状态管理,所以必须标记为
'use client',避免服务器端执行客户端逻辑。 - 颜色模式的SSR兼容处理:从Cookie读取初始颜色模式,而不是仅依赖localStorage,这样服务器端能渲染出与客户端一致的初始HTML。示例:
// 在RootLayout中读取Cookie(服务器组件) import { cookies } from 'next/headers'; import { Provider } from '@/components/ui/provider'; import { Suspense } from 'react'; export default function RootLayout({ children }) { const cookieStore = cookies(); const initialColorMode = cookieStore.get('chakra-color-mode')?.value || 'light'; return ( <html suppressHydrationWarning> <body> <Suspense fallback={null}> <Provider initialColorMode={initialColorMode}>{children}</Provider> </Suspense> </body> </html> ); }
然后在Provider中传递初始值给ColorModeProvider:
'use client'; import { ChakraProvider, defaultSystem } from '@chakra-ui/react'; import { ColorModeProvider } from './color-mode'; export function Provider({ initialColorMode, children }) { return ( <ChakraProvider value={defaultSystem}> <ColorModeProvider initialColorMode={initialColorMode}> {children} </ColorModeProvider> </ChakraProvider> ); }
- 避免服务器端执行客户端API:所有依赖
window、document等客户端环境的代码,必须放在useEffect、useIsClient或其他客户端专属钩子中,确保服务器渲染时不会执行这些代码。
内容的提问来源于stack exchange,提问作者Süleyman TAŞÇI
相关产品推荐
相关产品推荐

