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

Next.js项目中如何根据本地化语言变更URL路径

实现Next.js多语言URL路径本地化

1. 配置Next.js国际化基础

在项目根目录的next.config.js中配置多语言支持,指定可用语言、默认语言,同时禁用自动语言检测避免干扰手动切换:

/** @type {import('next').NextConfig} */
const nextConfig = {
  i18n: {
    locales: ['en', 'fr'],
    defaultLocale: 'en',
    localeDetection: false,
  },
}

module.exports = nextConfig

2. 建立路由-语言映射表

在项目中创建locales/routes.js文件,存储不同语言对应的页面路径:

export const routeMap = {
  en: {
    privacyPolicy: '/privacy-policy',
  },
  fr: {
    privacyPolicy: '/politique-de-confidentialite',
  },
}

3. 搭建动态路由页面

根据你使用的路由方案(Pages Router/App Router),创建对应动态页面来匹配多语言路径:

Pages Router 实现(pages/[locale]/[slug].js)

import { useRouter } from 'next/router'
import { routeMap } from '../../locales/routes'
import PrivacyPolicyContent from '../../components/PrivacyPolicyContent'

export default function DynamicPage() {
  const router = useRouter()
  const { locale, slug } = router.query

  // 校验当前路径是否属于对应语言的合法路由
  const isValidRoute = Object.values(routeMap[locale]).includes(`/${slug}`)
  if (!isValidRoute) {
    return <div>404 - 页面不存在</div>
  }

  // 根据路由匹配对应页面组件
  let PageComponent
  if (slug === routeMap[locale].privacyPolicy.slice(1)) {
    PageComponent = PrivacyPolicyContent
  }

  return PageComponent ? <PageComponent locale={locale} /> : <div>404</div>
}

// 预生成静态路径(SSG)
export async function getStaticPaths() {
  const paths = []
  Object.keys(routeMap).forEach(locale => {
    Object.values(routeMap[locale]).forEach(route => {
      paths.push({
        params: { locale, slug: route.slice(1) },
      })
    })
  })
  return { paths, fallback: false }
}

export async function getStaticProps({ params }) {
  return {
    props: {
      locale: params.locale,
    },
  }
}

App Router 实现(app/[locale]/[slug]/page.js)

import { routeMap } from '@/locales/routes'
import PrivacyPolicyContent from '@/components/PrivacyPolicyContent'
import { notFound } from 'next/navigation'

export default function Page({ params }) {
  const { locale, slug } = params

  const isValidRoute = Object.values(routeMap[locale]).includes(`/${slug}`)
  if (!isValidRoute) {
    notFound()
  }

  let PageComponent
  if (slug === routeMap[locale].privacyPolicy.slice(1)) {
    PageComponent = PrivacyPolicyContent
  }

  return PageComponent ? <PageComponent locale={locale} /> : notFound()
}

// 预生成静态路径
export async function generateStaticParams() {
  const paths = []
  Object.keys(routeMap).forEach(locale => {
    Object.values(routeMap[locale]).forEach(route => {
      paths.push({
        locale,
        slug: route.slice(1),
      })
    })
  })
  return paths
}

4. 编写多语言内容组件

创建components/PrivacyPolicyContent.js,根据传入的语言参数渲染对应内容:

export default function PrivacyPolicyContent({ locale }) {
  const content = {
    en: {
      title: 'Privacy Policy',
      text: 'This is our privacy policy in English...',
    },
    fr: {
      title: 'Politique de confidentialité',
      text: 'Ceci est notre politique de confidentialité en français...',
    },
  }

  return (
    <div>
      <h1>{content[locale].title}</h1>
      <p>{content[locale].text}</p>
    </div>
  )
}

5. 实现语言切换功能

添加语言切换按钮,根据当前路径跳转至对应语言的目标路径:

Pages Router 切换组件

import { useRouter } from 'next/router'
import { routeMap } from '../locales/routes'

export default function LanguageSwitcher() {
  const router = useRouter()
  const { locale, pathname } = router

  // 获取目标语言对应的路径
  const getTargetPath = (targetLocale) => {
    const currentRoute = Object.entries(routeMap[locale]).find(([_, route]) => route === pathname)
    return currentRoute ? routeMap[targetLocale][currentRoute[0]] : '/'
  }

  return (
    <div>
      <button onClick={() => router.push(`/en${getTargetPath('en')}`)}>English</button>
      <button onClick={() => router.push(`/fr${getTargetPath('fr')}`)}>Français</button>
    </div>
  )
}

App Router 切换组件

import { usePathname, useRouter } from 'next/navigation'
import { routeMap } from '@/locales/routes'

export default function LanguageSwitcher() {
  const pathname = usePathname()
  const router = useRouter()
  const currentLocale = pathname.split('/')[1]

  const getTargetPath = (targetLocale) => {
    const currentSlug = pathname.split('/')[2]
    const routeKey = Object.entries(routeMap[currentLocale]).find(([_, route]) => route.slice(1) === currentSlug)?.[0]
    return routeKey ? `/${targetLocale}${routeMap[targetLocale][routeKey]}` : `/${targetLocale}`
  }

  return (
    <div>
      <button onClick={() => router.push(getTargetPath('en'))}>English</button>
      <button onClick={() => router.push(getTargetPath('fr'))}>Français</button>
    </div>
  )
}

完成以上配置后,访问/en/privacy-policy将显示英文隐私政策,访问/fr/politique-de-confidentialite将显示法文版本,点击语言切换按钮会自动跳转至对应语言的URL路径,页面内容同步切换。

内容的提问来源于stack exchange,提问作者A.S.Abir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 06:08:10