NextJS URL与Next-Translate国际化URL
#javascript #nextjs #i18n

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!。一切都完成了,这就是它的样子

Image description

参考

查看Github Repo