DEV Community

Adrián Bailador
Adrián Bailador

Posted on

3 1 1 1 1

Guide to Internationalisation (i18n) in Next.js with Routing

Internationalisation (i18n) is the process of designing an application to be easily adaptable to different languages and regions without engineering changes. In this article, you will learn how to set up i18n in a Next.js application and create a language switcher to toggle between English and Spanish using next-intl.

Installation

First, you need to install the next-intl library, which facilitates managing internationalisation in Next.js. Run the following command in your terminal:

npm install next-intl
Enter fullscreen mode Exit fullscreen mode

Project Structure

The project structure will be as follows:

├── messages
│   ├── en.json
│   └── es.json
├── next.config.mjs
└── src
    ├── i18n.ts
    ├── middleware.ts
    └── app
        └── [locale]
            ├── layout.tsx
            └── page.tsx
Enter fullscreen mode Exit fullscreen mode

1. Setting Up Translation Messages

Create a messages directory at the root of your project. Inside this directory, add JSON files for each language you want to support.

messages/en.json

{
  "greeting": "Hello Codú",
  "farewell": "Goodbye Codú"
}
Enter fullscreen mode Exit fullscreen mode

messages/es.json

{
  "greeting": "Hola Codú",
  "farewell": "Adiós Codú"
}
Enter fullscreen mode Exit fullscreen mode

These files contain the translations of the phrases that your application will use.

2. Configuring Next.js

Configure Next.js to support internationalisation in next.config.mjs.

next.config.mjs

import { getRequestConfig } from 'next-intl/server';

// List of supported languages
const locales = ['en', 'es'];

export default getRequestConfig(async ({ locale }) => {
  // Validate that the incoming `locale` parameter is valid
  if (!locales.includes(locale)) {
    return { notFound: true };
  }

  return {
    messages: (await import(`./messages/${locale}.json`)).default
  };
});
Enter fullscreen mode Exit fullscreen mode

This file configures Next.js to load the correct translation messages based on the requested language.

3. Internationalisation Middleware

Create middleware to handle redirection and setting the default language.

src/middleware.ts

import createMiddleware from 'next-intl/middleware';

export default createMiddleware({
  // List of all supported languages
  locales: ['en', 'es'],

  // Default language
  defaultLocale: 'en'
});

export const config = {
  // Only match internationalised pathnames
  matcher: ['/', '/(en|es)/:path*']
};
Enter fullscreen mode Exit fullscreen mode

This middleware handles redirecting to the default language if none is specified.

4. Internationalisation Configuration

Create a configuration file to manage internationalisation settings.

src/i18n.ts

import { notFound } from 'next/navigation';
import { getRequestConfig } from 'next-intl/server';

const locales = ['en', 'es'];

export default getRequestConfig(async ({ locale }) => {
  if (!locales.includes(locale as any)) notFound();

  return {
    messages: (await import(`../messages/${locale}.json`)).default
  };
});
Enter fullscreen mode Exit fullscreen mode

This file validates the locales and loads the corresponding messages.

5. Setting Up Layout and Page

Configure the layout and main page to support internationalisation.

src/app/[locale]/layout.tsx

import { useLocale } from 'next-intl';
import { ReactNode } from 'react';

export default function Layout({ children }: { children: ReactNode }) {
  const locale = useLocale();
  return (
    <html lang={locale}>
      <body>{children}</body>
    </html>
  );
}
Enter fullscreen mode Exit fullscreen mode

src/app/[locale]/page.tsx

import { useTranslations } from 'next-intl';

export default function Page() {
  const t = useTranslations();
  return (
    <div>
      <h1>{t('greeting')}</h1>
      <p>{t('farewell')}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

These files configure the layout and main page to use the translations.

6. Creating the Language Switcher

Finally, create a language switcher to toggle between English and Spanish.

src/app/[locale]/switcher.tsx

'use client';

import { useLocale } from 'next-intl';
import { useRouter } from 'next/navigation';
import { ChangeEvent, useTransition } from 'react';

export default function LocalSwitcher() {
  const [isPending, startTransition] = useTransition();
  const router = useRouter();
  const localActive = useLocale();

  const onSelectChange = (e: ChangeEvent<HTMLSelectElement>) => {
    const nextLocale = e.target.value;
    startTransition(() => {
      router.replace(`/${nextLocale}`);
    });
  };

  return (
    <label className='border-2 rounded'>
      <p className='sr-only'>Change language</p>
      <select
        defaultValue={localActive}
        className='bg-transparent py-2'
        onChange={onSelectChange}
        disabled={isPending}
      >
        <option value='en'>English</option>
        <option value='es'>Spanish</option>
      </select>
    </label>
  );
}
Enter fullscreen mode Exit fullscreen mode

This component allows users to change the interface language.

Conclusion

With these steps, you have successfully set up internationalisation in your Next.js application and created a language switcher to toggle between English and Spanish. This will allow your application to support multiple languages and provide a localised user experience.

Image of AssemblyAI tool

Challenge Submission: SpeechCraft - AI-Powered Speech Analysis for Better Communication

SpeechCraft is an advanced real-time speech analytics platform that transforms spoken words into actionable insights. Using cutting-edge AI technology from AssemblyAI, it provides instant transcription while analyzing multiple dimensions of speech performance.

Read full post

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay