Next.js 和 Sanity 将语言环境切换为默认 URL

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

我使用 Sanity CMS 在 Next js 上开发了一个网站。 AppRouter技术。我的网站支持英语和德语。问题是主域上没有主页,因为文件夹结构如下:app/[lang]/page.tsx.

因此,主页始终位于 mysite.com/en 或 mysite.com/de。是否可以以某种方式重新配置项目,以便主页位于 mysite.com 而不带斜线?你知道我如何将地址“/en”切换为“/”吗?

我已经这样设置了内化:

// i18n.config.ts

const languages = [
  { id: 'de', title: 'German' },
  { id: 'en', title: 'English', isDefault: true },
];

const i18n = {
  languages,
  base: languages.find((item) => item.isDefault)?.id,
};

export { i18n };
// middleware.ts

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

import { i18n } from "@/i18n.config";

import { match as matchLocale } from "@formatjs/intl-localematcher";
import Negotiator from "negotiator";

function getLocale(request: NextRequest): string | undefined {
  const negotiatorHeaders: Record<string, string> = {};
  request.headers.forEach((value, key) => (negotiatorHeaders[key] = value));

  const locales: string[] = i18n.languages.map(lang => lang.id);
  const languages = new Negotiator({ headers: negotiatorHeaders }).languages();

  const locale = matchLocale(languages, locales, i18n.base || "id");
  return locale;
}

export function middleware(request: NextRequest) {
  const pathname = request.nextUrl.pathname;
  const pathnameIsMissingLocale = i18n.languages.every(
    locale =>
      !pathname.startsWith(`/${locale.id}/`) && pathname !== `/${locale.id}`
  );

  if (pathnameIsMissingLocale) {
    const locale = getLocale(request);
    return NextResponse.redirect(
      new URL(
        `/${locale}${pathname.startsWith("/") ? "" : "/"}${pathname}`,
        request.url
      )
    );
  }
}

export const config = {
  // Matcher ignoring `/_next/` and `/api/`
  matcher: [
    "/((?!api|_next/static|admin|structure|robots|sitemap|_next/image|favicon.ico).*)"
  ]
};
next.js localization internationalization sanity react-i18next
1个回答
0
投票

如果您的网站主页重定向到带有区域设置的路径,那是没有问题的,因为这支持国际化,但我会尝试根据我的理解提供解决方案。 您可以更改您的

if
语句,以便当路径名是主页时,您不会向其添加区域设置,但这会带来不便,您必须在
app/page.tsx
创建一个单独的页面(请注意,没有
[lang] 
),您可以使用该页面的默认语言:英语。

  if (pathnameIsMissingLocale && pathname !== "/") {
    const locale = getLocale(request);
    return NextResponse.redirect(
      new URL(
        `/${locale}${pathname.startsWith("/") ? "" : "/"}${pathname}`,
        request.url
      )
    );
  }

还有另一种解决方法,即使在没有区域设置的主页中也可以使用国际化,但你必须在主页中使用 negotiator,例如:

// app/page.tsx
import { headers } from 'next/headers'
// You can declare this in a separate file and use it in both this page and middleware 
function getLocale(request: NextRequest): string | undefined {
  const negotiatorHeaders: Record<string, string> = {};
  request.headers.forEach((value, key) => (negotiatorHeaders[key] = value));

  const locales: string[] = i18n.languages.map(lang => lang.id);
  const languages = new Negotiator({ headers: negotiatorHeaders }).languages();

  const locale = matchLocale(languages, locales, i18n.base || "id");
  return locale;
}

export function HomePage(): JSX.Element {
  const acceptLanguage = headers().get("accept-language");
  const req = {
    "accept-language": acceptLanguage
  }
  const locale = getLocale(req);
  
  // You can render content dynamically depending on locale value (en or de);
  return(
    ...
  )
}

© www.soinside.com 2019 - 2024. All rights reserved.