Next.js - 本地化 next-intl - 从 url 中删除默认语言

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

我正在分享我的

middleware.ts
i18n.ts

这是我第一次在

next.js
中进行本地化,我成功了,但现在我正在与
URL
作斗争,因为我不希望在默认版本中使用
"cs"
,并且正在添加
"cs"
URL
,即使我不输入它。

next-intl
中是否有任何设置可以防止这种情况发生?

我什至不知道从哪里开始,我试图从

"cs"
中删除
matcher
,但我相信这对“向URL添加cs”没有影响。

还尝试将

    localeDetection: false,
添加到
return
i18n.ts

所以安装了

http://localhost:3000/
我每次都会得到
http://localhost:3000/cs

感谢您的任何建议。

Middleware.ts

export default createMiddleware({
  // A list of all locales that are supported
  locales: ["cs", "en"],

  // Used when no locale matches
  defaultLocale: "cs",
});

export const config = {
  // Match only internationalized pathnames
  matcher: ["/", "/(cs|en)/:path*"],
};

i18n.ts

import { notFound } from "next/navigation";
import { getRequestConfig } from "next-intl/server";

// Can be imported from a shared config
const locales = ["cs"];

export default getRequestConfig(async ({ locale }) => {
  // Validate that the incoming `locale` parameter is valid
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
  if (!locales.includes(locale as any)) notFound();

  return {
    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
    messages: (await import(`/i18n/${locale}.json`)).default,
  };
});
reactjs next.js localization next-intl
1个回答
0
投票

根据文档,在页面路由器中,当我们将所有页面放置在 /pages 中时,从 URL 中隐藏默认语言版本是标准行为。不幸的是,App Router 中的情况并非如此。我搜索了各种解决方案,但没有任何效果,所以我只是将 /app/[locale]/ 中的所有内容复制到 /app/ 。这是一个丑陋的解决方案,因为我们必须两次维护所有文件,但至少它有效。遗憾的是 Vercel 还没有解决这个问题。这是我的 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.locales;
  const languages = new Negotiator({ headers: negotiatorHeaders }).languages();

  const locale = matchLocale(languages, locales, i18n.defaultLocale);
  return locale;
}

export function middleware(request: NextRequest) {
  const pathname = request.nextUrl.pathname;

  if (pathname.startsWith('/en')) {
    const newPathname = pathname.replace(/^\/en/, '');
    return NextResponse.redirect(new URL(newPathname || '/', request.url));
  }

  const pathnameIsMissingLocale = i18n.locales.every(
    locale => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
  );

  if (pathnameIsMissingLocale) {
    const locale = getLocale(request);

    if (locale === i18n.defaultLocale) {
      return NextResponse.next();
    }

    return NextResponse.redirect(new URL(`/${locale}${pathname}`, request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: [
    '/((?!api|_next/static|_next/image|favicon.ico|public|img|fonts).*)',
  ],
};
© www.soinside.com 2019 - 2024. All rights reserved.