胖蔡说技术
随便扯扯

Next.js 国际化(i18n)教程

Next.js是由Vercel(原 ZEIT)创建的开源框架。它建立在 React 之上,为 React 组件的服务器端渲染(SSR) 提供了一个开箱即用的解决方案。此外,它还支持静态站点生成(SSG),这可以帮助我们立即构建超快速且用户友好的网站。虽然是一个相对年轻的框架,但它具有良好的国际化基础与现有的 i18n 库很好地互补。在接下来的章节中,您将了解如何在 Next.js 应用程序中设置国际化。

新建Next.js项目

首先,让我们使用create-next-app命令行工具创建一个新的 Next.js 项目。

npx create-next-app nextjs-i18n-example

添加 React Intl 依赖

正如我们之前提到的,Next.js 可以很好地与现有的 i18n 库(react-intl、lingui、next-intl等)配合使用。在本教程中,我们将使用react-intl

$ cd nextjs-i18n-example 
$ npm i react-intl

为国际化路由添加配置

翻译和路由是国际化的两个主要支柱。之前添加的react-intl库将处理翻译和格式化。在路由方面,Next.js 有内置支持。这种内置支持提供了两个选项,子路径路由和域路由。在本教程中,我们将使用子路径路由,因为它不太复杂,并且对于普通网站来说更常见。为此,让我们使用i18n配置更新next.config.js文件。

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  i18n: {
    // The locales you want to support in your app
    locales: ["en", "fr"],
    // The default locale you want to be used when visiting a non-locale prefixed path e.g. `/hello`
    defaultLocale: "en",
  },
};

module.exports = nextConfig;

国际化路由从Next.js 10开始可用。

创建本地化文件

下一个重要的事情是添加本地化文件。为此,让我们创建一个lang目录。在其中添加两个 JSON 文件:en.jsonfr.json。这些文件将分别保存英语和法语的翻译。下面,您可以看到添加上述文件后的项目结构。

nextjs-i18n-example
|-- lang
|   |-- en.json
|   |-- fr.json
|-- pages
|   |-- api
|   |-- _app.js
|   |-- index.js
|   |-- ...
|-- public
|-- ...
|-- package.json
|-- package-lock.json

然后,在本地化文件中填写我们稍后将使用的消息。

en.json文件:

{
  "page.home.head.title": "Next.js i18n example",
  "page.home.head.meta.description": "Next.js i18n example - English",
  "page.home.title": "Welcome to <b>Next.js i18n tutorial</b>",
  "page.home.description": "You are currently viewing the homepage in English 🚀"
}

fr.json文件:

{
  "page.home.head.title": "Next.js i18n exemple",
  "page.home.head.meta.description": "Next.js i18n exemple - Français",
  "page.home.title": "Bienvenue à <b>Next.js i18n didacticiel</b>",
  "page.home.description": "Vous consultez actuellement la page d'accueil en Français 🚀"
}

在 Next.js 项目中配置 react-intl

国际化的路由和本地化文件只是任务的第一部分。第二部分是设置react-intl库。下面,您可以看到_app.js文件中发生了哪些更改。

import { useRouter } from "next/router";
import { IntlProvider } from "react-intl";

import en from "../lang/en.json";
import fr from "../lang/fr.json";

import "../styles/globals.css";

const messages = {
  en,
  fr,
};

function MyApp({ Component, pageProps }) {
  const { locale } = useRouter();

  return (
    <IntlProvider locale={locale} messages={messages[locale]}>
      <Component {...pageProps} />
    </IntlProvider>
  );
}

export default MyApp;

为 i18n 适配页面

我们做了大部分工作。最后一步是将所有这些放在一起。因此,我们将更新 pages 目录下的index.js文件。下面,您可以找到两种访问本地化消息的方法,命令式和声明式。我们已经介绍了这两种使用方式、格式化选项以及类似的另一个帖子。

index.js文件:

import Head from "next/head";
import Link from "next/link";
import { useRouter } from "next/router";
import { FormattedMessage, useIntl } from "react-intl";

import styles from "../styles/Home.module.css";

export default function Home(props) {
  const { locales } = useRouter();

  const intl = useIntl();

  const title = intl.formatMessage({ id: "page.home.head.title" });
  const description = intl.formatMessage({ id: "page.home.head.meta.description" });

  return (
    <div className={styles.container}>
      <Head>
        <title>{title}</title>
        <meta name="description" content={description} />
        <link rel="icon" href="/favicon.ico" />

        {/* Add hreflang links */}
        <link rel="alternate" href="http://example.com" hrefLang="x-default" />
        <link rel="alternate" href="http://example.com" hrefLang="en" />
        <link rel="alternate" href="http://example.com/fr" hrefLang="fr" />
      </Head>

      <header>
        <div className={styles.languages}>
          {[...locales].sort().map((locale) => (
            <Link key={locale} href="/" locale={locale}>
              {locale}
            </Link>
          ))}
        </div>
      </header>

      <main className={styles.main}>
        <h1 className={styles.title}>
          <FormattedMessage id="page.home.title" values={{ b: (chunks) => <b>{chunks}</b> }} />
        </h1>

        <p className={styles.description}>
          <FormattedMessage id="page.home.description" />
        </p>
      </main>
    </div>
  );
}

恭喜! 🎉

您已在 Next.js 项目中成功设置国际化。

您可以在原始帖子中找到更多详细信息和示例。

本文中使用的所有代码示例都可在GitHub 存储库上找到。

我希望您发现本指南有用。

赞(1) 打赏
转载请附上原文出处链接:胖蔡叨叨叨 » Next.js 国际化(i18n)教程
分享到: 更多 (0)

请小编喝杯咖啡~

支付宝扫一扫打赏

微信扫一扫打赏