i18n URL已在所有主要静态站点发电机中都可使用,但在某种程度上缺少NextJ,这绝对是可怜ð。
我是法国人,总是用法语和英语创建my websites。
这是关于任何开发人员如何在少于10分钟中实现这一目标的详细说明,并最终能够处理诸如
的URL- /
- am / accuil < / li>
tldr
可以找到带有所有源代码的存储库 on GitHub
先决条件
本教程使用了出色的next-translate库,但可以适用于Next-I18Next。
- 在您的项目中已经设置了下一个翻译
将要做什么
- 生成
rewrites
规则,该规则将使URL适应用户选择的语言 - 增压
nextTranslate
函数用于使用这些rewrites
- 编写一个自定义的
Link
组件,该组件将使用这些rewrites
生成相应的i18n sl,并将其用于导航
程序
在以下所有步骤中,创建的文件和函数都将放在modules/I18n
文件夹中。
经过多年的编程,这是我提出的一种实践,这有助于分开应用程序的一部分(在这种情况下,所有相关的I18N逻辑)。
我很快将写一篇博客文章。
指定永久链接
要做的第一件事是指定我们要使用的永久链接。
让我们创建一个modules/I18n/permalinks.json
{
"/": {
"fr": "/accueil"
}
}
注意:这对我来说不是一个理想的解决方案,因为它将实际页面(JSX文件)与其永久链接的定义分开,最好从页面内使用export const permalinks
。此问题将在另一篇博客文章中解决(如果您想要更多信息,您可以立即与我联系)。
增压nextTranslate
函数
这里的目标是将我们创建的永久链接转换为重写规则,以便NextJ可以根据语言正确重写URL。
tldr 请参阅commit on GitHub
用
创建一个modules/I18n/next.config.js
const nextTranslate = require('next-translate-plugin');
const fs = require('fs');
const permalinks = require('./permalinks.json');
/**
*
* Transforms
{
"/": {
"fr": "/accueil"
}
}
* into
[
{
source: '/fr/accueil',
destination: '/fr',
locale: false
}
]
*/
const permalinksToRewriteRules = (permalinks) =>
Object.entries(permalinks).reduce(
(acc, [originalSlug, permalinks]) => [
...acc,
...Object.entries(permalinks).reduce(
(acc2, [locale, i18nSlug]) => [
...acc2,
{
source: `/${locale}${i18nSlug}`,
destination: `/${locale}${originalSlug}`,
locale: false,
},
],
[]
),
],
[]
);
module.exports = (nextConfig) => {
const nextTranslateConfig = nextTranslate(nextConfig);
return {
...nextTranslateConfig,
async rewrites() {
const existingRewrites = nextTranslateConfig.rewrites
? await nextTranslateConfig.rewrites()
: [];
return [...permalinksToRewriteRules(permalinks), ...existingRewrites];
},
};
};
并替换对next.config.js
中函数的调用
- const nextTranslate = require('next-translate-plugin')
+ const nextTranslate = require('./src/modules/I18n/next.config');
很棒,现在,如果您重新加载服务器,则可以访问
现在,让我们调整链接组件以将此新的URL计入考虑
调整链接组件
目标是能够直接导航到前面定义的NICE URL。
tldr :请参阅commit on GitHub
必须创建一个称为Link
的新的modules/I18n
组件,必须修改next/link
的所有导入。
是的,这确实是一个痛点,我承认,但我找不到做其他明智的方法。
这实际上不是一个大问题,因为一个简单的“搜索和替换”将起作用
- import Link from 'next/link';
+ import { Link } from 'modules/I18n';
首先,必须将permalinks
变量暴露于前端,以便将由将创建的Link
组件使用。
在nextjs中,这是用
完成的
return {
...nextTranslateConfig,
+ publicRuntimeConfig: {
+ ...nextTranslateConfig.publicRuntimeConfig,
+ permalinks, // add it to publicRuntimeConfig so it can be used by the Link component
+ },
async rewrites() {
...
Link
组件中构建的nextJS的工作方式是它将从href
和通过(或现有)locale
构建URL。
这意味着fr
中的/
的链接将导致/fr
此组件将创建一个URL的地图,以直接路由到相应的正确URL /fr/accueil
import React from 'react';
import Link from 'next/link';
import { useRouter } from 'next/router';
import getConfig from 'next/config';
const { publicRuntimeConfig } = getConfig();
const permalinks: { [key: string]: { [key: string]: string } } =
publicRuntimeConfig.permalinks || {};
/**
* Formats permalinks
{
"/": {
"fr": "/accueil"
}
}
* into
{
"/fr/": "/fr/accueil",
"/en/accueil": "/"
}
*/
export const i18nFallbackUrls: { [key: string]: string } = Object.entries(
permalinks
).reduce(
(acc, [originalSlug, permalinks]) => ({
...acc,
...Object.entries(permalinks || {}).reduce(
(acc2, [locale, permalink]) => ({
...acc2,
[`/${locale}${originalSlug}`]: `/${locale}${permalink}`,
[`/en${permalink}`]: originalSlug,
}),
{}
),
}),
{}
);
const I18nLink = ({ href, locale, ...props }: any) => {
const router = useRouter();
const wantedLocale = locale || router.locale;
let i18nProps: any = {
href,
locale,
};
if (i18nFallbackUrls[`/${wantedLocale}${href}`]) {
i18nProps = {
href: i18nFallbackUrls[`/${wantedLocale}${href}`],
locale: false,
};
}
return <Link {...i18nProps} {...props} />;
};
export default I18nLink;
和 voila!。一切都完成了,这就是它的样子