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

如何在Next.js中实现国家/语言双码子路径路由方案?

Next.js 实现包含国家码+语言码的子路径路由方案

方案一:自定义路由重写(next.config.js)

直接在next.config.js中配置路由重写规则,将/[country]/[lang]/:path*格式的请求转发到对应页面,同时传递国家码和语言码参数:

// next.config.js
module.exports = {
  async rewrites() {
    return [
      {
        source: '/:country/:lang/:path*',
        destination: '/:path*?country=:country&lang=:lang',
      },
      // 根路径重定向到默认国家+语言组合
      {
        source: '/',
        destination: '/us/en',
        permanent: true,
      },
    ];
  },
};

页面中通过useRouter获取参数:

// pages/category/[id].js
import { useRouter } from 'next/router';

export default function CategoryPage() {
  const router = useRouter();
  const { country, lang, id } = router.query;

  // 根据country和lang请求对应地区的商品数据、库存信息
  // ...
}

方案二:使用中间件(Middleware)处理路由校验与参数注入

通过Next.js中间件拦截请求,校验国家码和语言码的合法性,将参数注入到请求上下文,同时处理非法路径的重定向:

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

// 定义合法的国家码、语言码列表
const VALID_COUNTRIES = ['us', 'de', 'fr', 'jp'];
const VALID_LANGUAGES = ['en', 'de', 'fr', 'ja'];

export function middleware(request: NextRequest) {
  const pathParts = request.nextUrl.pathname.split('/').filter(Boolean);
  
  // 检查路径是否包含合法的国家码+语言码组合
  if (pathParts.length >= 2) {
    const [country, lang] = pathParts;
    if (VALID_COUNTRIES.includes(country) && VALID_LANGUAGES.includes(lang)) {
      // 将参数注入请求头,页面可通过headers()获取
      const requestHeaders = new Headers(request.headers);
      requestHeaders.set('x-country-code', country);
      requestHeaders.set('x-language-code', lang);

      return NextResponse.next({
        request: {
          headers: requestHeaders,
        },
      });
    }
  }

  // 非法路径重定向到默认国家+语言组合
  return NextResponse.redirect(new URL('/us/en', request.url));
}

// 指定匹配所有路由规则
export const config = {
  matcher: ['/:path*'],
};

页面中获取参数:

// pages/category/[id].js
import { headers } from 'next/headers';

export default function CategoryPage() {
  const headersList = headers();
  const country = headersList.get('x-country-code');
  const lang = headersList.get('x-language-code');

  // 业务逻辑处理(如请求地区专属商品数据)
  // ...
}

方案三:封装本地化路由组件

创建自定义的LocalizedLink组件和useLocalization hook,统一管理路径中的国家码和语言码,避免重复拼接:

// components/LocalizedLink.js
import Link from 'next/link';

export default function LocalizedLink({ country, lang, href, ...props }) {
  const localizedHref = `/${country}/${lang}${href}`;
  return <Link href={localizedHref} {...props} />;
}
// hooks/useLocalization.js
import { useRouter } from 'next/router';

export function useLocalization() {
  const router = useRouter();
  const pathParts = router.asPath.split('/').filter(Boolean);
  
  // 从路径中提取国家码和语言码,默认值兜底
  const country = pathParts[0] || 'us';
  const lang = pathParts[1] || 'en';

  // 生成带国家码和语言码的路径方法
  const getLocalizedPath = (path) => `/${country}/${lang}${path}`;

  return { country, lang, getLocalizedPath };
}

页面中使用示例:

// pages/category/[id].js
import { useLocalization } from '../hooks/useLocalization';
import LocalizedLink from '../components/LocalizedLink';

export default function CategoryPage() {
  const { country, lang } = useLocalization();

  return (
    <div>
      <h2>当前地区:{country} | 当前语言:{lang}</h2>
      <LocalizedLink country={country} lang={lang} href="/products">
        查看商品列表
      </LocalizedLink>
    </div>
  );
}

静态生成(SSG)适配

如果使用静态生成,需要在getStaticPaths中预生成所有合法的国家码+语言码组合路径:

// pages/category/[id].js
export async function getStaticPaths() {
  const countries = ['us', 'de', 'fr'];
  const languages = ['en', 'de', 'fr'];
  // 实际项目中从API获取所有分类ID
  const categoryIds = ['1', '2', '3', '4'];

  const paths = [];
  for (const country of countries) {
    for (const lang of languages) {
      for (const id of categoryIds) {
        paths.push({
          params: { id },
          // 配合rewrites规则,生成对应路径
          locale: `${country}-${lang}`
        });
      }
    }
  }

  return { paths, fallback: 'blocking' };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:05:24