在Next.js中重新加载时,如何强制执行i18n区域设置slugs并实现i18n一致性



我使用的是next-translate。默认情况下,我的路线识别如下:

/about         <---
/de/about
/es/about

但我想为所有路径强制设置一个区域设置:

/en/about      <---
/de/about
/es/about

这是我的配置:

next.config.js

const nextTranslate = require('next-translate');
module.exports = nextTranslate({
...
i18n: {
localeDetection: false,
locales: ['en', 'de', 'es'],
defaultLocale: 'en',
}
});

i18n.js

module.exports = {
locales: ['en', 'de', 'es'],
defaultLocale: 'en',
pages: {
'*': ['common']
},
interpolation: {
prefix: '${',
suffix: '}',
},
loadLocaleFrom: (locale, namespace) =>
import(`./translations/${locale}/${namespace}`).then((m) => m.default),
}

请注意,我还有一个langchange组件,它持久化NEXT_LOCALEcookie。因此,我希望当我访问/about并且我的NEXT_LOCALEcookie之前已设置为de时,路由器会将我重定向到/de/about但不是。它停留在/about并将cookie重写为en。。。

以下是当前pages文件夹结构:

...
pages/
_app.tsx
_document.tsx
about.tsx
...

我需要把它重组成这样吗?

pages/
_app.tsx
_document.tsx
[lang]/         <---
about.tsx
...

如果是这样,下一步该怎么办?

  • 通过useRouter()解析首选语言环境
  • 解析NEXT_LOCALEcookie
  • 解析lang段塞

然后决定哪个优先级更高?我该在哪里做?在_app.tsx/一些HOC中?

我的next.config.js中需要任何rewritesredirects吗?还是应该通过Router.push动态处理这些?

持久化的NEXT_LOCALEcookie不会根据其值自动重定向,这是因为您通过设置localeDetection: false明确禁用了它。这会影响基于标头的重定向以及基于cookie的重定向。

只需将其从next.config.js中删除即可解决该问题。


没有内置的方法可以在所有路径上强制使用默认区域设置。但是,有几个解决方法可以帮助在URL上预先设置默认区域设置。

解决方案#1:将默认区域设置为default,并在中间件中重定向

如i18n路由文档中所记载的;伪";名为default的区域设置,并将其设置为默认区域设置。请注意,实际上不会使用此区域设置,它只允许我们在其路径上始终以en区域设置为前缀。

// next.config.js
module.exports = {
i18n: {
locales: ['default', 'en', 'de', 'es'],
defaultLocale: 'default'
}
}

接下来,如果请求default语言环境,则创建一个middleware文件以重定向到/en前缀。

// middleware.js
import { NextResponse } from 'next/server'
const PUBLIC_FILE = /.(.*)$/
export function middleware(request) {
const shouldHandleLocale = !PUBLIC_FILE.test(request.nextUrl.pathname)
&& !request.nextUrl.pathname.includes('/api/') 
&& request.nextUrl.locale === 'default'
if (shouldHandleLocale) {
const url = request.nextUrl.clone()
url.pathname = `/en${request.nextUrl.pathname}`
return NextResponse.redirect(url)
}
return undefined
}

解决方案#2:浅路由到客户端上的前缀路径

或者,您可以检查默认区域设置,并在第一次通过router.push装载时在URL中显式设置它。

让我们假设下面的自定义useDefaultLocale钩子,它抽象了要重用的逻辑。

import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
export const useDefaultLocale = () => {
const router = useRouter();
useEffect(() => {
if (router.locale === router.defaultLocale) {
router.push(`/${router.locale}${router.asPath}`, undefined, {
locale: false,
shallow: true // Optionally add this if you don't want to rerun data fetching methods
});
}
}, [router.asPath]);
};

然后可以在您的页面或_app.js中使用。

import { useDefaultLocale } from '<path-to>/use-default-locale';
const AboutPage = () => {
useDefaultLocale()
return <>About Page</>;
};

最新更新