reactjs Next.js i18n路由不适用于动态路由

enxuqcxy  于 2023-03-29  发布在  React
关注(0)|答案(1)|浏览(211)

我有一个Next应用程序,它只有两个路由:一个index.tsx和一个[slug].tsx。slug路由使用getStaticPropsgetStaticPaths从CMS获取页面。
我已经通过在我的next.config.js中添加以下内容启用了国际化路由:

i18n: {
  locales: ["en", "fr"],
  defaultLocale: "en",
}

index路由工作正常,如果我使用fr-FRAccept-Language头部访问/,我会被重定向到/fr子路由。不工作的是动态路由[slug].tsx。如果我直接访问它,而且在getStaticProps中打印我的locale会显示默认的en locale,而不是从我的Accept-Language头计算出来的locale。
我知道人们通常会忘记在getStaticPaths中生成locale路径,我不认为这是问题所在,下面是我如何生成它们的:

export const getStaticPaths: GetStaticPaths = async ({ locales }) => {
  const clients = await fetchClients();

  const paths = locales
    .map((locale) => clients.map((c) => ({ params: { slug: c.id }, locale })))
    .flat();

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

你知道怎么回事吗?谢谢!

wlwcrazw

wlwcrazw1#

自动语言检测目前只在根目录下工作。这个问题的评论和文档提到了这一点。
路径生成代码看起来是正确的。如果用户访问索引页,然后导航到子页,他们应该被重定向到正确的区域设置(如果没有翻译,则为默认设置)
您可以使用中间件来手动控制此行为。
首先,我们需要禁用localeDetection

i18n: {
  locales: ["en", "fr"],
  defaultLocale: "en",
  localeDetection: false,
}

然后,您可以创建一个新的中间件来检查Accept-Language头并将用户重定向到正确的页面。
这是Next.js文档中关于默认语言环境前缀的示例的略微修改版本。

// middleware.js
import { NextResponse } from "next/server";

// you can do this manually or use a library like accept-language-parser
import parser from "accept-language-parser";

const PUBLIC_FILE = /\.(.*)$/;

export async function middleware(req) {
  if (
    req.nextUrl.pathname.startsWith("/_next") ||
    req.nextUrl.pathname.includes("/api/") ||
    PUBLIC_FILE.test(req.nextUrl.pathname)
  ) {
    return;
  }

  const acceptLanguageHeader = req.headers.get("accept-language");
  const locale = parser.pick(["fr", "en"], acceptLanguageHeader);

  if (req.nextUrl.locale !== locale) {
    return NextResponse.redirect(
      new URL(`/${locale}${req.nextUrl.pathname}${req.nextUrl.search}`, req.url)
    );
  }
}

相关问题