You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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配置规范

  1. RootLayout保持为服务器组件:不要给RootLayout添加'use client'指令,确保服务器能正常渲染根HTML结构。
  2. ChakraProvider必须放在客户端组件内:ChakraProvider依赖客户端状态管理,所以必须标记为'use client',避免服务器端执行客户端逻辑。
  3. 颜色模式的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>
  );
}
  1. 避免服务器端执行客户端API:所有依赖window、document等客户端环境的代码,必须放在useEffect、useIsClient或其他客户端专属钩子中,确保服务器渲染时不会执行这些代码。

内容的提问来源于stack exchange,提问作者Süleyman TAŞÇI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:58:10