Next.js  is an open-source framework created by  Vercel  (formerly ZEIT). It is built on top of React and provides an out-of-the-box solution for  server-side rendering  (SSR) of React components. Furthermore, it supports  static site generation  (SSG), which can help us to build superfast and user-friendly websites in no time. Although a relatively young framework, it has a good  foundation for internationalization  which complements well with existing i18n libraries. In the following chapters, you will find out how to set up internationalization in your Next.js app.

Create a new Next.js project

First, let's create a new Next.js project with the  create-next-app  CLI tool.


npx create-next-app nextjs-i18n-example

Add React Intl dependency

As we mentioned earlier, the Next.js works well with existing i18n libraries ( react-intl lingui next-intl , and similar). In this tutorial, we will use the react-intl.


cd nextjs-i18n-example
npm i react-intl

Add config for internationalized routing

Translations and routing are two main pillars of internationalization. The previously added react-intl library is going to handle translations and formatting. When it comes to routing, Next.js has  built-in support  for that. This built-in support offers two options, sub-path routing, and domain routing. In this tutorial, we will use sub-path routing as it is less complex and more common for average websites. For that, let's update the next.config.js file with the i18n config.


/** @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;

The internationalized routing is available since  Next.js 10 .

Create localization files

The next important thing is to add localization files. For that purpose, let's create a lang directory. Within it, add two JSON files: en.json and fr.json. These files are going to hold translations for English and French, respectively. Below, you can see the project structure after adding the mentioned files.


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


Afterward, fill in localization files with messages that we will use later.

The en.json file:


{
  "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 🚀"
}


The fr.json file:


{
  "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 🚀"
}

Configure react-intl in Next.js project

Internationalized routing and localization files are just the first part of the task. The second part is setting up the react-intl library. Below, you can see what changes have been made in the _app.js file.


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;

Adapt pages for i18n

We did most of the work. The last step is to put all this together. Therefore, we are going to update the index.js file under the pages directory. Below, you can find two approaches for accessing the localization messages, imperative and declarative. We've already covered  these two ways of usage formatting options , and similar in  another post .


The index.js file:


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>
  );
}


Congratulations! 🎉
You have successfully set up internationalization in your Next.js project.


More details and examples you can find in the  original post .

All code samples used in this article are available on the  GitHub repo .


I hope you found this guide useful.

Feel free to give me feedback in the comments.


Also Published Here

Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐