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

如何在NextJS中实现动态本地化?按需配置路由语言支持

Next.js动态路由实现差异化语言支持方案

Next.js默认的全局i18n配置没法给单个路由指定支持的语言,导致像/en/route2这种本不该支持的路由也能访问。结合你用getServerSideProps的场景,按下面的步骤来解决:

1. 保留全局i18n基础配置

先在next.config.js里把所有可能用到的语言都列进去,全局配置是基础,后续在路由层面做拦截:

// next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'zh-CN'],
    defaultLocale: 'zh-CN',
  },
}

2. 定义路由-语言权限映射

新建一个配置文件(比如src/utils/localeRouteRules.js),明确每个路由能支持的语言列表:

// src/utils/localeRouteRules.js
export const allowedLocalesByRoute = {
  '/route1': ['zh-CN', 'en'], // route1支持中英文
  '/route2': ['zh-CN'], // route2仅支持中文
  // 其他路由按需添加
}

3. 用getServerSideProps做路由语言校验

封装一个公共校验函数,在每个页面的getServerSideProps里先执行校验,不匹配就重定向到默认语言路由或者返回404:

封装公共校验逻辑

// src/utils/checkLocaleAccess.js
import { allowedLocalesByRoute } from './localeRouteRules'
import { redirect } from 'next/navigation'

export function checkLocaleAccess(ctx) {
  const { locale, asPath, i18n } = ctx
  // 提取不带语言前缀和查询参数的基础路由
  const baseRoute = asPath.split('?')[0].replace(`/${locale}`, '') || '/'
  
  // 获取当前路由允许的语言列表,未配置则默认允许所有语言
  const allowedLocales = allowedLocalesByRoute[baseRoute] || i18n.locales

  if (!allowedLocales.includes(locale)) {
    // 不支持当前语言,直接重定向到默认语言的对应路由
    redirect(`/${i18n.defaultLocale}${baseRoute}`)
    // 若需直接返回404,替换为:
    // return { notFound: true }
  }
}

在页面中使用校验函数

比如pages/route1.js:

export async function getServerSideProps(ctx) {
  // 先校验语言权限,不通过直接重定向
  checkLocaleAccess(ctx)

  // 正常编写数据获取逻辑
  const data = await fetch('your-api-url/route1').then(res => res.json())
  return { props: { data } }
}

pages/route2.js同理,调用checkLocaleAccess(ctx)后,访问/en/route2会自动跳转到/zh-CN/route2。

4. 动态路由的适配处理

如果是动态路由(比如pages/posts/[id].js),调整配置和校验逻辑:

// src/utils/localeRouteRules.js
export const allowedLocalesByRoute = {
  '/posts/[id]': ['zh-CN', 'en'], // 所有文章详情页支持中英文
  // ...其他路由
}

修改校验函数里的路由匹配逻辑,用正则匹配动态路由模板:

// src/utils/checkLocaleAccess.js
function matchDynamicRoute(baseRoute) {
  return Object.keys(allowedLocalesByRoute).find(routePattern => {
    // 将动态路由模板转为正则,比如/posts/[id] → /posts/[^/]+
    const regexPattern = routePattern.replace(/\[.*?\]/g, '[^/]+')
    return new RegExp(`^${regexPattern}$`).test(baseRoute)
  })
}

// 替换原allowedLocales获取逻辑
const matchedRoute = matchDynamicRoute(baseRoute)
const allowedLocales = matchedRoute ? allowedLocalesByRoute[matchedRoute] : ctx.i18n.locales

5. 导航链接的优化

确保前端生成的导航链接只包含当前路由支持的语言,比如在语言切换组件中:

import { useRouter } from 'next/router'
import { allowedLocalesByRoute } from '../utils/localeRouteRules'

function LanguageSwitcher() {
  const router = useRouter()
  const baseRoute = router.asPath.split('?')[0].replace(`/${router.locale}`, '') || '/'
  const allowedLocales = allowedLocalesByRoute[baseRoute] || router.locales

  return (
    <div className="lang-switch">
      {allowedLocales.map(lang => (
        <a 
          key={lang} 
          href={router.pathname} 
          locale={lang} 
          className={router.locale === lang ? 'active' : ''}
        >
          {lang === 'en' ? 'English' : '中文'}
        </a>
      ))}
    </div>
  )
}

这样用户看不到当前路由不支持的语言选项,从源头避免错误访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:27:06