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

使用next-intl出现hydration错误,请求排查配置问题

Next-intl 配置问题:Hydration 错误修复

问题描述

首次使用next-intl库,配置后出现以下hydration错误:

In HTML, cannot be a child of , This will cause a hydration error

该错误仅在访问NotFound页面或返回旧页面时触发。

项目文件夹结构:

  • 根目录下app文件夹,包含:
    • layout/RootLayout.tsx(根布局文件)
    • 根级not-found.tsx
    • [locale]本地化路由目录,内部有not-found.tsx(复用根级NotFound页面)

错误原因

核心问题是NotFound页面手动嵌套了RootLayout。在Next.js App Router机制中,not-found.tsx作为错误页面会自动被根布局RootLayout包裹,无需手动引入。当你在NotFoundPage中再次渲染RootLayout时,页面会生成双重<html>结构——外层RootLayout的<body>内部又嵌套了一个完整的<html>标签,直接触发hydration错误。

解决方案

1. 修改根级not-found.tsx代码

移除RootLayout的嵌套,只保留页面内容:

import React from 'react';
import { useTranslations } from 'next-intl';

const NotFoundPage = () => {
  const language = useTranslations('notFound');
  return (
    <div className='not-found-page'>
      <div className='not-found-container'>
        <h1>{language('title')}</h1>
        <h2>{language('content')}</h2>
        <p>{language('description')}</p>
      </div>
    </div>
  );
};

export default NotFoundPage;

2. 保留本地化路由的not-found.tsx内容

[locale]/not-found.tsx无需修改,继续复用根级NotFound页面即可:

export { default } from '@/app/not-found';

3. 确认RootLayout的正确性

你的RootLayout.tsx代码本身是正确的,它会自动作为所有页面(包括NotFound、Error等特殊页面)的外层布局,无需在子页面中手动引入:

import React from 'react';
import localFont from 'next/font/local';
import { NextIntlClientProvider } from 'next-intl';
import { getMessages } from 'next-intl/server';
import { ReactNode } from 'react';
import { ToastProvider } from '@/providers/toaster-provider';
import BackToTopProvider from '@/providers/back-to-top-provider';
import { AuthProvider } from '@/contexts/AuthContext';
import type { Metadata } from 'next';

const lora = localFont({
  src: '../fonts/Lora.ttf',
  variable: '--font-lora',
  weight: '400 500 600 700 800',
});

const notoSans = localFont({
  src: '../fonts/NotoSansSC.ttf',
  variable: '--font-noto-sans',
  weight: '400 500 600 700 800',
});

export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
};

type Props = {
  children: ReactNode;
  locale: string;
};

export default async function RootLayout({ children, locale }: Props) {
  const messages = await getMessages({ locale });

  return (
    <html lang={locale}>
      <body className={`${lora.variable} ${notoSans.variable}`}>
        <NextIntlClientProvider messages={messages}>
          <AuthProvider>
            <BackToTopProvider>
              <ToastProvider />
              {children}
            </BackToTopProvider>
          </AuthProvider>
        </NextIntlClientProvider>
      </body>
    </html>
  );
}

后续验证

  • 重启开发服务器,清理缓存(可执行npm run dev -- --clean)
  • 访问NotFound页面,确认hydration错误消失
  • 检查其他页面是否存在类似手动嵌套RootLayout的情况,避免重复触发错误

内容的提问来源于stack exchange,提问作者Khuong Viet Tai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:53:18