Next.js 的多语言(i18n)支持如何实现

734 阅读2分钟

简介

多语言支持(i18n, internationalization)是构建全球化应用的重要功能。Next.js 15 提供了内置支持,结合 app 目录结构,可以实现更清晰的模块化设计。我们将通过这个教程,实现动态语言切换、多语言路由和 SEO 支持。


1. 初始化 Next.js 项目

使用以下命令初始化 Next.js 项目并安装依赖:

npx create-next-app@latest nextjs-i18n-demo --typescript --experimental-app-dir
cd nextjs-i18n-demo
npm install next-translate

2. 配置 Next.js 的 i18n 功能

在根目录的 next.config.js 文件中添加 i18n 配置:

/** @type {import('next').NextConfig} */
const nextConfig = {
  i18n: {
    locales: ['en', 'zh', 'es'], // 支持的语言
    defaultLocale: 'en',         // 默认语言
  },
};

module.exports = nextConfig;

3. 创建翻译文件

翻译文件存放在 public/locales 目录下:

目录结构

public/
  locales/
    en/
      common.json
    zh/
      common.json
    es/
      common.json

示例内容

public/locales/en/common.json

{
  "welcome": "Welcome to our site!",
  "description": "This is a multilingual site powered by Next.js."
}

public/locales/zh/common.json

{
  "welcome": "欢迎来到我们的网站!",
  "description": "这是一个由 Next.js 驱动的多语言网站。"
}

public/locales/es/common.json

{
  "welcome": "¡Bienvenido a nuestro sitio!",
  "description": "Este es un sitio multilingüe impulsado por Next.js."
}

4. 使用翻译 Hook

使用 next-translate 提供的翻译 Hook 加载多语言内容。

路径/app/hooks/useTranslation.ts

import useTranslation from 'next-translate/useTranslation';

export const useCommonTranslation = () => {
  return useTranslation('common'); // 关联 common.json
};

5. 在 app 目录中加载翻译

app 目录中直接加载翻译并显示内容。

路径/app/page.tsx

import { useCommonTranslation } from './hooks/useTranslation';

export default function HomePage() {
  const { t } = useCommonTranslation();

  return (
    <div>
      <h1>{t('welcome')}</h1>
      <p>{t('description')}</p>
    </div>
  );
}

6. 实现语言切换功能

语言切换按钮组件

路径/app/components/LanguageSwitcher.tsx

'use client';

import { useRouter } from 'next/navigation';

export default function LanguageSwitcher() {
  const router = useRouter();
  const currentPath = window.location.pathname;

  const switchLanguage = (lang: string) => {
    const pathWithLocale = `/${lang}${currentPath}`;
    router.push(pathWithLocale);
  };

  return (
    <div>
      <button onClick={() => switchLanguage('en')}>English</button>
      <button onClick={() => switchLanguage('zh')}>中文</button>
      <button onClick={() => switchLanguage('es')}>Español</button>
    </div>
  );
}

在页面中使用

路径/app/page.tsx

import LanguageSwitcher from './components/LanguageSwitcher';

export default function HomePage() {
  return (
    <div>
      <LanguageSwitcher />
      {/* 其他内容 */}
    </div>
  );
}

7. 多语言路由支持

设置多语言路由

Next.js 的 app 目录天然支持嵌套路由,以下是动态路由的实现:

路径/app/[locale]/page.tsx

import { GetStaticProps } from 'next';
import { useCommonTranslation } from '../hooks/useTranslation';

export const getStaticProps: GetStaticProps = async ({ params }) => {
  const { locale } = params;
  const translation = await import(`../../public/locales/${locale}/common.json`);
  return {
    props: {
      translation: translation.default,
    },
  };
};

export default function LocalePage() {
  const { t } = useCommonTranslation();

  return (
    <div>
      <h1>{t('welcome')}</h1>
      <p>{t('description')}</p>
    </div>
  );
}

8. SEO 和语言特定的 URL

Next.js 自动生成语言特定的 hreflang 标签来帮助 SEO。如果需要覆盖默认行为,可以在 app 目录中通过自定义元数据配置。

路径/app/[locale]/head.tsx

export default function Head({ params }: { params: { locale: string } }) {
  const { locale } = params;
  const alternateUrls = {
    en: 'https://example.com/en',
    zh: 'https://example.com/zh',
    es: 'https://example.com/es',
  };

  return (
    <>
      <title>{`Welcome - ${locale.toUpperCase()}`}</title>
      <link rel="alternate" hrefLang="en" href={alternateUrls.en} />
      <link rel="alternate" hrefLang="zh" href={alternateUrls.zh} />
      <link rel="alternate" hrefLang="es" href={alternateUrls.es} />
    </>
  );
}

9. 总结

在本教程中,我们基于 Next.js 15 和 app 目录结构实现了多语言支持,内容包括:

  1. 配置 Next.js 内置的 i18n 支持。
  2. 创建 JSON 文件管理翻译内容。
  3. 使用翻译 Hook 显示内容。
  4. 添加语言切换功能。
  5. 为多语言路由设置动态支持,并优化 SEO。

文件和目录结构总结

  • 翻译 Hook/app/hooks/useTranslation.ts
  • 语言切换按钮组件/app/components/LanguageSwitcher.tsx
  • 多语言路由文件/app/[locale]/page.tsx

通过以上步骤,你的应用已经支持全球化用户体验,并为多语言 SEO 打下坚实基础。如有问题,欢迎讨论!