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

Next.js 12.2.5实现类Apple的区域子路径路由(仅显示地区码)

解决方案:Next.js 12.2.5 实现地区码式国际化子路径路由

1. 直接将地区码作为 i18n 配置的 locales 值

Next.js 的 i18n 路由支持自定义 locale 标识,你可以直接把 au、in 这类地区码作为配置项,替代完整的 en-AU 格式。

在 next.config.js 中修改配置:

module.exports = {
  i18n: {
    locales: ['au', 'in', 'en'], // 用地区码作为locale值
    defaultLocale: 'en',
    localeDetection: true, // 保留自动检测浏览器locale的功能
  },
}

这样路由就会直接显示为 ${mydomain}/au、${mydomain}/in/faq 这类格式,完全符合你的需求。

2. 适配浏览器 locale 到地区码的自动重定向

默认的 localeDetection 会匹配浏览器的完整 locale(比如 en-AU),我们需要将其映射到对应的地区码,避免出现 /en-AU 这类路由。可以通过 Next.js 中间件实现:

  1. 先安装依赖包:
npm install @formatjs/intl-localematcher negotiator
  1. 在项目根目录创建 middleware.js:
import { NextResponse } from 'next/server'
import { match } from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'

// 定义支持的地区码
const supportedLocales = ['au', 'in', 'en']
// 建立完整locale到地区码的映射
const localeToRegionMap = {
  'en-AU': 'au',
  'en-IN': 'in',
  'en-US': 'en',
  'en-GB': 'en',
  // 可根据需求添加更多映射规则
}

export function middleware(request) {
  const pathname = request.nextUrl.pathname

  // 检查当前路由是否已包含地区码
  const hasValidLocale = supportedLocales.some(
    locale => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
  )

  if (!hasValidLocale) {
    // 获取浏览器首选locale
    const headers = { 'accept-language': request.headers.get('accept-language') || '' }
    const browserLanguages = new Negotiator({ headers }).languages()
    
    // 匹配到对应的地区码
    let targetLocale = match(browserLanguages, supportedLocales, 'en')
    // 如果浏览器返回完整locale,优先用映射规则替换
    const primaryBrowserLocale = browserLanguages[0]
    if (localeToRegionMap[primaryBrowserLocale]) {
      targetLocale = localeToRegionMap[primaryBrowserLocale]
    }

    // 重定向到带地区码的路由
    return NextResponse.redirect(
      new URL(`/${targetLocale}${pathname}`, request.url)
    )
  }
}

// 排除不需要处理的路由(如静态资源、API)
export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}

3. 本地化内容的处理

虽然路由显示的是地区码,但你可以在代码内部将其映射到对应的完整 locale,处理日期、货币这类地区化格式,或者加载对应地区的翻译文件:

import { useRouter } from 'next/router'
// 导入各地区的翻译文件
import auTranslations from '../locales/au/common.json'
import inTranslations from '../locales/in/common.json'
import enTranslations from '../locales/en/common.json'

const translationMap = {
  au: auTranslations,
  in: inTranslations,
  en: enTranslations,
}

// 地区码到完整locale的映射,用于格式化数据
const fullLocaleMap = {
  au: 'en-AU',
  in: 'en-IN',
  en: 'en-US',
}

export default function FaqPage() {
  const router = useRouter()
  const currentTranslations = translationMap[router.locale]
  const currentFullLocale = fullLocaleMap[router.locale]

  // 示例:格式化澳大利亚地区的货币
  const formattedPrice = new Intl.NumberFormat(currentFullLocale, {
    style: 'currency',
    currency: router.locale === 'au' ? 'AUD' : 'INR',
  }).format(99)

  return (
    <div>
      <h1>{currentTranslations.faqTitle}</h1>
      <p>{currentTranslations.priceText}: {formattedPrice}</p>
    </div>
  )
}

4. 注意事项

  • Next.js 12.2.5 完全支持自定义 locale 标识,用地区码作为 locales 值不会有兼容性问题。
  • 如果需要同一地区支持多语言(比如印度的英文和印地语),可以调整配置为 ['au', 'in-en', 'in-hi'],再通过中间件将 /in 重定向到默认语言的子路由(如 /in-en)。
  • 静态生成(SSG)或服务器端渲染(SSR)时,getStaticProps/getServerSideProps 的 context.locale 会返回配置的地区码,直接使用即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:15:33