NextJS 14集成next-intl多语言出现hydration错误求助
NextJS 14 + next-intl 多语言配置后出现Hydration错误求助
我使用NextJS 14,按照next-intl官方文档完成多语言功能配置,步骤如下:
- 创建i18n.ts
- 更新next.config.mjs
- 创建middleware.ts
- 创建
[locale]目录,并在其中创建layout.tsx和page.tsx
完成配置后系统出现多个Hydration错误,查阅大量资料仍未解决,现求助。
配置代码
i18n.ts
import {notFound} from 'next/navigation'; import {getRequestConfig} from 'next-intl/server'; // 支持的语言列表 const locales = ['en', 'nl', 'de', 'tr']; export default getRequestConfig(async ({locale}) => { // 验证传入的locale是否合法 if (!locales.includes(locale as any)) notFound(); return { messages: (await import(`./languages/${locale}.json`)).default }; });
next.config.mjs
import createNextIntlPlugin from 'next-intl/plugin'; const withNextIntl = createNextIntlPlugin(); /** @type {import('next').NextConfig} */ const nextConfig = { images: { domains: [ "avatars.githubusercontent.com", "lh3.googleusercontent.com", "res.cloudinary.com", "images.unsplash.com" ] } }; export default withNextIntl(nextConfig);
middleware.ts
import createMiddleware from 'next-intl/middleware'; export default createMiddleware({ // 支持的语言列表 locales: ['en', 'nl', 'de', 'tr'], // 默认语言 defaultLocale: 'en' }); export const config = { // 匹配国际化路径 matcher: ['/', '/(en|nl|de|tr)/:path*'] };
[locale]/layout.tsx
import {NextIntlClientProvider} from 'next-intl'; import {getMessages} from 'next-intl/server'; export default async function LocaleLayout({children, params: {locale}}: { children: React.ReactNode; params: {locale: string}; }) { // 获取当前语言的消息 const messages = await getMessages({ locale }); return ( <html lang={locale}> <body> <NextIntlClientProvider messages={messages}> {children} </NextIntlClientProvider> </body> </html> ); }
[locale]/page.tsx(原代码)
import {useTranslations} from 'next-intl'; export default function Index() { const t = useTranslations('home_page'); return ( <h1>{t('slider_title')}</h1> ); }
错误信息
Hydration失败,初始UI与服务器渲染内容不匹配。
Hydrating过程中发生错误,由于错误在Suspense边界外触发,整个根组件将切换为客户端渲染。
解决方案
1. 修复客户端组件标记问题
useTranslations是next-intl的客户端钩子,只能在客户端组件中使用。NextJS 14中默认的page组件是服务器组件,直接使用客户端钩子会导致Hydration不匹配。修改page.tsx,添加'use client'指令:
'use client'; import {useTranslations} from 'next-intl'; export default function Index() { const t = useTranslations('home_page'); return ( <h1>{t('slider_title')}</h1> ); }
2. 显式传递Locale给getMessages
在layout.tsx中,显式将当前locale传递给getMessages,确保服务器获取到对应语言的消息:
const messages = await getMessages({ locale });
3. 验证语言文件完整性
确认languages目录下的en.json、nl.json、de.json、tr.json文件都存在,且JSON格式无语法错误,包含home_page.slider_title对应的翻译内容。
4. 清除缓存并重新构建
执行以下命令清除缓存并重新构建项目,避免旧缓存导致的渲染不一致:
npm run build && npm run start
5. 排查其他客户端代码
如果问题仍存在,检查项目中其他组件是否有在服务器渲染时调用客户端API(如window、document)的情况,这类代码需要用'use client'标记或包裹在Suspense组件中。
内容的提问来源于stack exchange,提问作者NikolayAndrv
相关产品推荐
相关产品推荐

