Next.js 16 + next-intl App Router 国际化实现指南
引言
✨ 随着全球化的发展,为网站添加国际化支持已经成为现代前端开发的标配。本文将基于真实项目代码,详细介绍如何在 Next.js 16 项目中使用 next-intl 实现基于 App Router 的国际化功能。
技术栈
- Next.js: 16.0.5 (App Router)
- next-intl: 4.5.7 (国际化核心库)
- TypeScript: 类型安全保障
一、项目国际化架构概述
App Router 路由方案
本项目采用 Next.js 13 及以上版本引入的 App Router 架构,通过动态路由 [locale] 实现国际化。这种方案的优势在于:
- 支持 SEO 友好的语言前缀路由(如
/zh/page、/en/page) - 提供服务端组件和客户端组件的灵活组合
- 内置数据流和布局系统,简化国际化实现
项目目录结构
项目采用清晰的模块化结构,将国际化相关代码集中在 src/i18n 目录下,便于维护和扩展:
src/
├── app/
│ ├── [locale]/ # 动态语言路由
│ │ ├── layout.tsx # 语言特定布局
│ │ └── page.tsx # 语言特定页面
│ ├── layout.tsx # 根布局
│ └── page.tsx # 根页面(重定向用)
├── components/
│ └── LocaleSwitcher.tsx # 语言切换组件
└── i18n/ # 国际化核心目录
├── config.ts # 语言配置
├── navigation.ts # 导航配置
├── request.ts # 翻译加载配置
├── routing.ts # 路由配置
└── messages/ # 翻译文件目录
├── en/ # 英文翻译
│ ├── index_page.json
│ └── locale_switcher.json
└── zh/ # 中文翻译
├── index_page.json
└── locale_switcher.json
二、核心配置文件
1. 语言配置 (config.ts)
定义支持的语言和默认语言:
// src/i18n/config.ts
export type Locale = (typeof locales)[number];
export const locales = ['zh', 'en'] as const; // 支持的语言:中文、英文
export const defaultLocale: Locale = 'zh'; // 默认语言:中文
2. 路由配置 (routing.ts)
配置国际化路由规则:
// src/i18n/routing.ts
import {
defineRouting } from 'next-intl/routing';
import {
defaultLocale, locales } from './config';
export const routing = defineRouting({
locales,
defaultLocale
});
3. 导航配置 (navigation.ts)
创建支持国际化的导航工具:
// src/i18n/navigation.ts
import {
createNavigation } from 'next-intl/navigation';
import {
routing } from './routing';
// 创建国际化导航工具集
export const {
Link, getPathname, redirect, usePathname, useRouter } =
createNavigation(routing);
4. 翻译加载配置 (request.ts)
实现动态加载翻译文件的核心逻辑:
// src/i18n/request.ts
import {
hasLocale } from 'next-intl';
import {
getRequestConfig } from 'next-intl/server';
import {
routing } from './routing';
/**
* 翻译模块配置接口
*/
export interface TranslationModuleConfig {
namespace: string; // 翻译键的命名空间
fileName: string; // 文件名
}
// 定义所有翻译模块
const TRANSLATION_MODULES: readonly TranslationModuleConfig[] = [
{
namespace: 'index_page', fileName: 'index_page' },
{
namespace: 'locale_switcher', fileName: 'locale_switcher' },
];
// 动态加载单个翻译模块
const importTranslationModule = async (
locale: string,
moduleConfig: TranslationModuleConfig
) => {
try {
const modulePath = `./messages/${
locale}/${
moduleConfig.fileName}.json`

最低0.47元/天 解锁文章
1527

被折叠的 条评论
为什么被折叠?



