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.json
和fr.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 存储库上找到。
我希望您发现本指南有用。