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

迁移至Next.js时React-i18next报错:文本与服务端渲染HTML不匹配

解决Next.js与react-i18next服务端渲染内容不匹配问题

核心问题分析

你遇到的Text content does not match server-rendered HTML错误,本质是服务端渲染时使用的语言和客户端hydrate时的语言不一致:

  • 服务端无法读取客户端的localStorage或cookie,只能用fallbackLng(en)渲染页面
  • 客户端加载后,通过LanguageDetector读取到用户之前选择的语言,切换后导致页面内容和服务端输出的HTML不匹配
  • 另外,你将i18n初始化代码放到next.config.js是错误的,该文件是Next.js的配置文件,不能用来初始化i18next

分步解决方案

1. 恢复i18n初始化文件

将原来的i18n代码恢复到单独的i18n.js文件,不要修改next.config.js:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';

const Languages = ['ar', 'en', 'fr']

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: "en",
    react: {
      useSuspense: true,
    },
    supported: ["en", "fr", "ar"],
    detection: {
      // 调整检测顺序,服务端优先从请求头/路由获取,客户端用localStorage/cookie
      order: ['path', 'cookie', 'htmlTag', 'localStorage', 'subdomain'],
      caches: ['localStorage'],
    },
    debug: false,
    whitelist: Languages,
    interpolation: {
      escapeValue: false,
    },
    nsSeparator: false,
    keySeparator: false,
    backend: {
      loadPath: '/static/locales/{{lng}}/{{ns}}.json',
    },
  });

export default i18n;

2. 修改_app.js,确保服务端与客户端语言一致

在_app.js中,从服务端请求中获取语言并传递给客户端,保证两端语言统一:

import React from 'react';
import { Provider } from 'react-redux';
import { useStore } from '../store';
import '../styles/globals.css';
import Layout from '../hocs/Layout';
import '../i18n'; // 引入正确的i18n初始化文件
import i18n from '../i18n';
import cookies from 'js-cookie';

function App({Component, pageProps, initialLanguage}) {
  const store = useStore(pageProps.initialReduxState);

  // 客户端初始化时同步服务端传递的语言
  React.useEffect(() => {
    if (initialLanguage) {
      i18n.changeLanguage(initialLanguage);
      cookies.set('i18next', initialLanguage);
    }
  }, [initialLanguage]);

  return (
    <Provider store={store}>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </Provider>
  );
};

// 服务端获取用户语言,传递给客户端
App.getInitialProps = async ({ ctx }) => {
  let initialLanguage = 'en';
  // 从cookie读取用户已选择的语言
  const cookieLanguage = ctx.req?.cookies?.i18next;
  if (cookieLanguage && ['en', 'fr', 'ar'].includes(cookieLanguage)) {
    initialLanguage = cookieLanguage;
  }
  return { initialLanguage };
};

export default App;

3. 调整LoginHeader的语言切换逻辑

修改语言切换按钮,确保切换时同步更新cookie,让服务端能正确识别:

// 在LoginHeader的语言按钮点击事件中
<button 
  onClick={() => {
    i18next.changeLanguage(code);
    cookies.set('i18next', code);
  }}
  className='loginHeader__lang__btn'
>
  {name}
</button>

4. 配置Next.js国际化路由(可选但推荐)

在next.config.js中添加国际化配置,让服务端能通过路由参数直接获取语言:

module.exports = {
  i18n: {
    locales: ['en', 'fr', 'ar'],
    defaultLocale: 'en',
  },
};

额外注意事项

  • 确保react-i18next和i18next的版本与Next.js兼容
  • 开启useSuspense: true后,需要用Suspense组件包裹使用t()的组件,或者在页面级别添加加载状态
  • 服务端渲染时避免直接操作document,可以在_document.js中根据服务端传递的语言设置dir属性

内容的提问来源于stack exchange,提问作者Moammer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:45:45