使用 next.js 更改多语言网站中的语言

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

我想创建一个多语言网站。我已经遵循了官方文档

我创建了这样的中间件:

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { match } from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'
 

let headers = { 'accept-language': 'en-US,en;q=0.5' }
let languages = new Negotiator({ headers }).languages()
let locales = ['en', 'nl', 'fr']
let defaultLocale = 'nl'
 

// Get the preferred locale, similar to above or using a library
function getLocale(request: any): string { 
    return match(languages, locales, defaultLocale) // -> 'en-US'
 }
 
export default function middleware(request: NextRequest) {
  // Check if there is any supported locale in the pathname
  console.log("Middleware is executed");

  const pathname = request.nextUrl.pathname
  const pathnameIsMissingLocale = locales.every(
    (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
  )
 
  // Redirect if there is no locale
  if (pathnameIsMissingLocale) {
    const locale = getLocale(request);
    console.log(locale);
    console.log(request);
    // e.g. incoming request is /products
    // The new URL is now /en-US/products
    return NextResponse.redirect(
      new URL(`/${locale}/${pathname}`, request.url)
    )
  }
  return NextResponse.next();
}
 
export const config = {
  matcher: [
    // Skip all internal paths (_next)
    '/((?!_next).*)',
    // Optional: only run on root (/) URL
    // '/'
  ],
}

结构是这样的

我有一个语言切换器:

import Link from "next/link";

export default function LanguageSwitcher() {
    return (
      <ul>
        <li><Link href="/" locale="en">EN</Link></li>
        <li><Link href="/" locale="nl">NL</Link></li>
        <li><Link href="/" locale="fr">FR</Link></li>
      </ul>
    )
  }

我有几个问题:

  1. 语言切换器不起作用,我无法像那样切换语言。
  2. 如果我输入 site.com/de/contact,那么它将转到 site.com/nl/de/contact。对于未知语言,他将添加默认语言:(
  3. 我不知道如何做到默认语言保持正常路由site.com / site.com/contact /等

我检查了多个博客,但首先他们谈论页面路由(旧系统),+它们包含一些其他包,为了简单起见,我实际上并不需要这些包。 虽然我已经尝试过这些库,但无论如何都无法正常工作。

next.js localization url-routing
2个回答
0
投票

在中间件函数中,有一行检查路径名是否丢失,如下所示:

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

但是通过这样做,您要求它检查路径名是否具有每个语言环境,并且您应该寻找 .some() 因为如果它与其中一个语言环境匹配,就足以知道它是正确的。

所以改成:

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

这应该可以处理未重定向到正确位置的链接。现在关于保留默认语言,更改中间件以包含此:

//...
const url = req.nextUrl.clone()
const pathnameIsMissingLocale = locales.some(
  (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
)
const isDefaultLocale = !pathNameIsMissingLocale || pathname.startsWith(`/${defaultLocale}/`)

if (pathnameIsMissingLocale) {
    const locale = getLocale(request);
    
    locale === defaultLocale 
      ? url.pathname = `/${pathname}`
      : url.pathname = `/${locale}/${pathname}`
    
    return NextResponse.redirect(url)
}
if(isDefaultLocale) {
  url.pathname = `/${pathname}`
  return NextResponse.redirect(url)
}
//...

此更改应检查链接是否为 defaultLocale 并相应地更改路径名


-1
投票

测试人员通常使用 Locale 来更改站点中的语言。

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