Adding Internationalization (i18n) to Next.js Apps: Supporting Multiple Languages
Tags: internationalization, nextjs, i18n, webdev
Published: 2024-07-13 07:26:50

Internationalisation, abbreviated as i18n, is a critical component of contemporary web development. To put it another way, i18n means preparing your app to be able to support multiple languages, making sure that your content can be accessed by users from around the world. By adding i18n to your Next.js app, you are opening up the opportunity for user’s who speak different languages to enjoy your app, and reach a wider audience. This guide is a walkthrough of the steps to add i18n to your Next.js app in a frictionless way, including lots of code examples to aid along the way.

## Setting Up Next.Js For I18n

Firstly, let us confirm that Next.js has been installed. If you haven't already, get started with a new Next.js project by executing the following commands:

```
npx create-next-app my-i18n-app
cd my-i18n-app
```
Next, we need to configure our Next.js to support i18n. Open your project's `next.config.js` file and add the following configuration:

```
// next.config.js

module.exports = {
  i18n: {
    locales: ['en', 'fr', 'es'], // List all the languages you want to support
    defaultLocale: 'en', // Default language
  },
};
```
Once again, we must configure our Next.js application to be able to use i18n. This involves opening our `next.config.js` file, and adding the following configuration:

## Creating Language Files

Language files are the container for your translations. For this we will be using JSON files. Create a locales directory at the root of your project, with a sub-directory for each language that your want support. For example:

```
/locales
  /en
    common.json
  /fr
    common.json
  /es
    common.json
```
Every JSON will have key-value pairs for your translations. Here is an example of what `common.json` might look like for English (`/locales/en/common.json`):

```
{
  "welcome": "Welcome to our website!",
  "description": "This is an example of internationalization with Next.js."
}
```
And for French (`/locales/fr/common.json`):
```
{
  "welcome": "Bienvenue sur notre site!",
  "description": "Ceci est un exemple d'internationalisation avec Next.js."
}
```

## Adding A Language Switcher

To enable users to switch languages, we will create a basic language switcher component- Create a new file called `LanguageSwitcher.js` in your `components` folder:

```
// components/LanguageSwitcher.js

import { useRouter } from 'next/router';

const LanguageSwitcher = () => {
  const router = useRouter();

  const changeLanguage = (locale) => {
    router.push(router.pathname, router.asPath, { locale });
  };

  return (
    <div>
      <button onClick={() => changeLanguage('en')}>English</button>
      <button onClick={() => changeLanguage('fr')}>Français</button>
      <button onClick={() => changeLanguage('es')}>Español</button>
    </div>
  );
};

export default LanguageSwitcher;
```
You can then add this component to your pages to enable the user to swap languages.

## Translating Pages And Components

To assist with translations, Next.js offers a `useTranslation` hook through the `next-i18next` library. To get started:

```
npm install next-i18next
```
Then, create a `next-i18next.config.js` file in the root of your project:

```
// next-i18next.config.js
module.exports = {
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'fr', 'es'],
  },
};
```
Change your `next.config.js` to use this setup:

```
// next.config.js

const { i18n } = require('./next-i18next.config');

module.exports = {
  i18n,
};
```
To finish up, cover your app with the `appWithTranslation` higher-order component. Make changes to `pages/_app.js`:

```
// pages/_app.js

import { appWithTranslation } from 'next-i18next';
import '../styles/globals.css';

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

export default appWithTranslation(MyApp);
```
To apply translations in your components or pages, you need to import the `useTranslation` hook:

```
// pages/index.js

import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import LanguageSwitcher from '../components/LanguageSwitcher';

export async function getStaticProps({ locale }) {
  return {
    props: {
      ...(await serverSideTranslations(locale, ['common'])),
    },
  };
}

export default function Home() {
  const { t } = useTranslation('common');

  return (
    <div>
      <LanguageSwitcher />
      <h1>{t('welcome')}</h1>
      <p>{t('description')}</p>
    </div>
  );
}
```
## Managing Dates, Numbers, And Other Locale-Specific Data

Translating text is significant part of internationalization. There are other aspects to consider. Dates. Numbers. Currencies. Let's look at how to handle these.

## Formatting Dates And Times

To format dates and times according to user's locale You can use the `Intl.DateTimeFormat` API. Here is an example

```
const formatDate = (date, locale) => {
  return new Intl.DateTimeFormat(locale, {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  }).format(date);
};

// Usage
const date = new Date();
console.log(formatDate(date, 'en')); // July 13, 2024
console.log(formatDate(date, 'fr')); // 13 juillet 2024
```

## Handling Numbers And Currencies

For formatting numbers and currencies the `Intl.NumberFormat` API is very useful. Here is how you can use it,

```
const formatNumber = (number, locale, currency) => {
  return new Intl.NumberFormat(locale, {
    style: 'currency',
    currency: currency,
  }).format(number);
};

// Usage
const amount = 123456.789;
console.log(formatNumber(amount, 'en-US', 'USD')); // $123,456.79
console.log(formatNumber(amount, 'fr-FR', 'EUR')); // 123 456,79 €
```
By using these internationalization APIs, you ensure that dates, numbers, and currencies are displayed correctly based on the user's locale.

## Testing Your I18n Setup

To see your translations in action, run your Next.js app:

```
npm run dev
```
Open your browser and navigate to your app. You should see the text in your default language. Try switching languages using the language switcher to see the translated text.

## Conclusion

By this point, you have walked through adding internationalization to your Next.js application. We looked at how to set up Next.js for I18n, create language files, add a language switcher, translate your pages and components, and manage locale-specific data such as dates and numbers.