为什么国际化在 NextJS 13 上无法使用 app/ 上的 [locale] 子文件夹进行工作

crg*_*g63 9 javascript internationalization reactjs next.js next.js13

如何让 i18n 在 Next 13 上运行?

我已经创建了一个嵌套[locale]/文件夹app/,但它只给出了 404

查看我的next.config.js

const nextConfig = {
  experimental: {
    appDir: true,
  },
  i18n: {
    defaultLocale: 'fr,
    locales: ['fr', 'en'],
    localeDetection: true
  }
}
Run Code Online (Sandbox Code Playgroud)

您是否找到了使用 React Server 组件支持 i18n 的方法?

编辑:

beta.nextjs文档上它说:

我们目前不打算在应用程序中包含以下功能: 国际化 (i18n)

我还发现了一个有关它的未解决问题,但尚未提供任何解决方法。

Fil*_*wal 7

[编辑] Next.js 文档中现在有一个指南。

Middleware是Next.js 13中针对i18n的解决方案。直到有官方推荐的方式。

  1. 要在 Next.js 13 中使用带有/app目录的中间件,您必须创建/page目录(即使您的所有页面都位于/app目录中)和.keep其中的文件。关于它的 Github 问题
  2. [locale]在目录中创建动态路由app并将所有其他路由放在那里。
  3. 设置中间件,以便将所有流量从没有locale参数的路由重定向到有参数的路由(fe 基于Accept-language客户端的标头或位置)。
  4. 从paramslocale获取页面上的值。

middleware.tsEric Howey 文章启发的最小内容:

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

// Regex to check whether something has an extension, e.g. .jpg
const PUBLIC_FILE = /\.(.*)$/;

export function middleware(request: NextRequest) {
  const { nextUrl, headers } = request;
  // Cloned url to work with
  const url = nextUrl.clone();
  // Client language, defaults to en
  const language =
    headers
      .get("accept-language")
      ?.split(",")?.[0]
      .split("-")?.[0]
      .toLowerCase() || "en";

  try {
    // Early return if it is a public file such as an image or an api call
    if (PUBLIC_FILE.test(nextUrl.pathname) || nextUrl.pathname.includes("/api")) {
      return undefined;
    }

    // Proceed without redirection if on a localized path
    if (
      nextUrl.pathname.startsWith("/en") ||
      nextUrl.pathname.startsWith("/de") ||
      nextUrl.pathname.startsWith("/fr")
    ) {
      return undefined;
    }

    if (language === "fr") {
      url.pathname = `/fr${nextUrl.pathname}`;
      return NextResponse.redirect(url);
    }

    if (language === "de") {
      url.pathname = `/de${nextUrl.pathname}`;
      return NextResponse.redirect(url);
    }

    if (!["de", "fr"].includes(language)) {
      url.pathname = `/en${nextUrl.pathname}`;
      return NextResponse.redirect(url);
    }

    return undefined;
  } catch (error) {
    console.log(error);
  }
}
Run Code Online (Sandbox Code Playgroud)