有没有办法在 Next.js 14 的 [lang] 文件夹内使用 not-found.tsx ?

问题描述 投票:0回答:1

我的 Next.js 14 项目有问题,该项目使用应用程序路由器。我使用 [lang] 文件夹来本地化我的应用程序。因此,我拥有所有页面,包括 [lang] 文件夹内的 page.tsx 和 layout.tsx。这样,我就可以将语言环境传递到我的所有页面,如下所示:

export default function Home({ params }: { params: { lang: string } }) {
  const s = dictionary[params.lang];

  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <p>{s.home.title}</p>
    </main>
  );
}

这是我的 middleware.ts 文件:

let locales = ["en", "de"];
export let defaultLocale = "en";

function getLocale(request: Request): string {
  const headers = new Headers(request.headers);
  const acceptLanguage = headers.get("accept-language");
  if (acceptLanguage) {
    headers.set("accept-language", acceptLanguage.replaceAll("_", "-"));
  }
  const headersObject = Object.fromEntries(headers.entries());
  const languages = new Negotiator({ headers: headersObject }).languages();

  return match(languages, locales, defaultLocale);
}

// Without /locale in path
export function middleware(request: NextRequest) {
  let locale = getLocale(request) ?? defaultLocale;
  const pathname = request.nextUrl.pathname;

  const newUrl = new URL(`/${locale}${pathname}`, request.nextUrl);
  return NextResponse.rewrite(newUrl);
}

export const config = {
  matcher: [
    // Skip all internal paths (_next)
    "/((?!_next|api|favicon.ico|robots.txt|sitemap.xml).*)",
    // Optional: only run on root (/) URL
    // '/'
  ],
};

我的文件夹结构是:

my-app/
├─ ...
├─ public/
│  ├─ favicon.ico
│  ├─ robots.txt
├─ src/
│  ├─ app/
│  │  ├─ [lang]/
│  │  │  ├─ page.tsx
│  │  │  ├─ layout.tsx
│  │  │  ├─ not-found.tsx
│  ├─ api/
├─ ...

问题是,当我将 not-found.tsx 放入 [lang] 文件夹中时,它不起作用。在未知的路线上我得到默认的 404 页面。但是,当我将它直接放在 [lang] 之外的应用程序文件夹中时,它确实可以工作,但我没有获得语言环境,并且获得没有布局的页面。解决方法是在应用程序目录中创建另一个layout.tsx,但同样无法对其进行本地化,这只是糟糕的用户体验。

我尝试将 not-found.tsx 复制到 [lang] 文件夹中,以便能够获取应用程序区域设置来本地化我的内容。根据 Next.js 文档,这应该是开箱即用的。

有人遇到过这样的问题吗

next.js http-status-code-404 i18next lang
1个回答
0
投票

这个答案记录了我对同一问题的解决方案,您可能会发现它合适或不合适。

  1. 首先,将

    not-found.tsx
    定位在
    app/[lang]/not-found.tsx

  2. 在根目录下,创建一个

    app/layout.tsx
    ,除了返回其
    children
    属性之外,不执行任何操作:

import { type ReactNode } from "react";

export default function GlobalLayout({ children }: { children: ReactNode }) {
  return children;
}
  1. 创建根
    not-found.tsx
    :

这里您有两个选择:

  • 创建一个通用页面,告诉您的应用程序未本地化为该语言。或
  • 重定向到默认语言:
"use client";

import { redirect, usePathname } from "next/navigation";

import { defaultLocale } from "@/config/constants";

export default function NotFound() {
  const pathname = usePathname();

  redirect(`/${defaultLocale}${pathname}`);
}
© www.soinside.com 2019 - 2024. All rights reserved.