Next.js 多语言实战教程:用 next-intl 实现 6 种语言国际化 Next.js 多语言实战教程用 next-intl 实现 6 种语言国际化【免费下载链接】nelsonlai.devMy personal website built with TypeScript, Next.js, and TailwindCSS项目地址: https://gitcode.com/gh_mirrors/ho/nelsonlai.dev一位东京的访客打开 nelsonlai.dev页面自动显示成日语一位巴西读者手动切到葡语博客标题和按钮全部跟着变——背后不是维护了六个站点而是同一套代码加上 next-intl 的多语言支持i18n 国际化。下面这套流程可以直接搬进你自己的 Next.js 项目。方案总览四个角色各管一摊 先给一张分工表后文每一步都对应其中一个角色角色位置干什么翻译官 next-intl依赖库提供useTranslations等 API负责加载和使用文案语言路由src/i18n/routing.ts声明支持哪些语言、URL 前缀规则文案素材库src/i18n/messages/每种语言一个 JSON存放全部界面文案语言守门员src/i18n/middleware.ts拦截每个请求按语言做重定向第一步如何配置语言路由让网站认识这些语言打开src/i18n/routing.ts整个项目的多语言骨架就藏在这一段里export const routing defineRouting({ locales: [en, zh-TW, zh-CN, ja, es, pt-BR] as const, defaultLocale: en, localePrefix: as-needed, localeDetection: true, })四个字段各管一件事locales是语言清单as const让 TypeScript 记住每个取值localePrefix: as-needed表示默认语言英语的 URL 不带前缀访客访问/about就是英文其他语言写成/ja/about不浪费一层路径localeDetection: true读取浏览器的 Accept-Language为开场那个自动显示日文的效果买单。第二步快速搭建多语言翻译结构把文案收进素材库 所有界面文案收在src/i18n/messages/下的 6 个 JSON 文件里一个语言一个文件。组织方式按页面 → 模块 → 文案三级嵌套首页英雄区文案归在homepage.hero下账户页归account评论区归blog.comments。找任何一个词先想它出现在哪个页面就能很快定位到键名。加载逻辑在src/i18n/request.ts它通过动态 import 只拉取当前语言的那份 JSONloadMessages(locale)切到日语时不会把西语文案也塞进包里。想加一种新语言就是复制一份 en.json 逐键翻译再回到 routing 的locales里加上语言代码收尾。第三步语言切换实现一个下拉框让用户手动选语言自动检测只解决第一次进来用户中途想换语言还得靠手动。切换器在src/components/layout/locale-switcher.tsx核心就一个函数function handleLocaleChange(value: Locale | null) { if (!value) return router.replace(pathname, { locale: value }) }关键点是usePathname和useRouter不是直接引自 next/navigation而是从src/i18n/routing.ts里createNavigation(routing)重新导出的——它们感知语言前缀所以router.replace(pathname, { locale: value })只替换语言、保留当前路径你在/blog/php切到日语落地的是/ja/blog/php不会被打回首页。外层再套一层useTransition切换期间禁用下拉框防止连点。幕后工作中间件拦截请求hreflang 告诉搜索引擎 ️守门员上场。src/i18n/middleware.ts全文只有几行import createMiddleware from next-intl/middleware import { routing } from ./routing export const i18nMiddleware createMiddleware(routing)它在src/proxy.ts里被挂到所有页面请求上API、静态资源除外。职责是发现 URL 没写语言前缀时按浏览器语言把/about重定向到/ja/about发现前缀和已保存的偏好不一致时再纠正过来。这就是日语访客打开网站自动看到日文的完整链路。hreflang 写给搜索引擎看。中间件管人src/lib/metadata.ts管机器。每个页面的元数据都会列出该页在所有语言下的完整地址alternates: { canonical: localizedCanonical, languages: { x-default: getLocalizedPath(path, en), ...Object.fromEntries(routing.locales.map((l) [l, getLocalizedPath(path, l)])), }, },x-default指向默认语言版本。搜索引擎看到这组标签就知道/ja/blog/php是/blog/php的日语版不会当成重复内容来降权。字体跟着语言走。根布局src/app/[locale]/layout.tsx里html lang{locale}让浏览器和读屏软件知道当前语言同时引入 Noto Sans SC / Noto Sans TC 两套字体变量简繁中文各有合适字形不会退化成系统默认字体。细节打磨日期、复数和博客内容按语言处理日期useFormatter()拿到的是语言感知的格式化器format.dateTime(date)在日语下输出「2026年8月23日」、在英文下输出 Aug 23, 2026同一份数据零 if-else。复数ICU 语法直接写进 JSON——{count, plural, 1 {comment} other {comments}}组件里一句t(blog.comments.comments, { count: n })自动选单复数西语、葡语的复数规则也不用操心。动态内容博客这类按语言创作的内容不走翻译文件。src/content/blog/按语言目录分放en、ja、es 各一套 mdxsrc/lib/content.ts里用post.locale locale过滤列表页永远只展示当前语言的文章。自检清单验证多语言真的生效 ✅上线前逐项过一遍浏览器语言设为日语访问不带前缀的首页确认被重定向到/ja在任意深层页面比如某篇博客用切换器换语言确认只换前缀、不丢路径查看源码html lang与当前语言一致页面里能找到完整的 hreflang 标签组核对 6 个 JSON 的键是否一一对应防止某个语言漏翻检查日期和1 comment / 3 comments这类文案在每种语言下都正确一句话收尾四份文件加六个 JSON就是网站通向 6 种语言的完整基建路由定规则、素材库存文案、守门员管入口、切换器管体验。今天就先做一件事——建好src/i18n/目录和第一个 messages JSON把导航栏文案搬进去剩下的照清单往下走就行。【免费下载链接】nelsonlai.devMy personal website built with TypeScript, Next.js, and TailwindCSS项目地址: https://gitcode.com/gh_mirrors/ho/nelsonlai.dev创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考