Internationalizing Next.js: A Comprehensive Guide to i18n Integration
Published: July 06, 2024 Edited July 06, 2024
Internationalization (i18n) is a crucial feature for any modern web application that seeks to reach a global audience. It enables you to deliver content in various languages, making your application accessible and user-friendly to people from different linguistic backgrounds.
In today’s guide, you will learn how to integrate internationalization to a Next.js application using next-intl
.
Let’s get started.
Prerequisite
To make the most out of this guide, here’s what you should have under your belt:
- Understanding of Next.js app router and TypeScript.
- Knowledge of how Next.js Middleware works.
Install Next.js
To integrate multi-language support you need a Next.js project.
Let’s create a brand new project with create-next-app.
npx create-next-app@latest
Run the above command and go with all the default options. You can choose the options according to your requirements.
Once you are done, you will have the Next.js project ready to integrate multi-language support.
Write the Translations
Before we proceed to configure next-intl
we need the translation for the different languages.
We will keep all the translations in the messages folder. You can name it anything you want.
Translations are stored as JSON objects. We only have a title for this example.
Go ahead and add all your text and their corresponding translations in these files.
Configure next-intl
First, you have to install next-intl
Run this command to install the package:
npm install next-intl
Once done, create a new route named [locale] inside the app directory.
And move all the routes under [locale], we will use this to get the locale and show the text in that language.
Now that we have all set up, let’s configure next-intl.
#1: Create a config file on the root of your project's directory and name it: i18n.ts.
Paste this code snippet into that file:
import { notFound } from "next/navigation";
import { getRequestConfig } from "next-intl/server";
export const locales = ["en", "de", "fr"];
export default getRequestConfig(async ({ locale }) => {
// Validate that the incoming `locale` parameter is valid
if (!locales.includes(locale as any)) notFound();
return {
messages: (await import(`../messages/${locale}.json`)).default,
};
});
In this code snippet, set up the locales for your project and validate the incoming locale parameter. If the locale is not on your list, redirect it to the not-found page. If it matches one of the locales, return the message for that locale.
#2: Create middleware.ts file on the root of your project.
Copy this code snippet over to your middleware
import createMiddleware from "next-intl/middleware";
import { locales } from "./i18n";
export default createMiddleware({
// A list of all locales that are supported
locales: locales,
// Used when no locale matches
defaultLocale: "en",
// Removes the locale when it's default
localePrefix: "as-needed",
});
export const config = {
// Match only internationalized pathnames
matcher: ["/", "/(de|en|fr)/:path*"],
};
Import the locales from the i18n config file you created earlier and the CreateMiddleware function from next-intl.
Inside the CreateMiddlware function, you can specify all the options you want to have.
Check out the next-intl documentation for more information.
Use the Translation
All the configurations are done.
Now, let’s see how to use the translation on a Client Component.
Client component
To use the translation on a Client Component, you must wrap your Layout with NextIntlClientProvider
.
And pass the messages as props to use on the Client components.
import "./globals.css";
import { NextIntlClientProvider } from "next-intl";
import { getMessages } from "next-intl/server";
import LangSwitcher from "@/components/LangSwitcher";
export default async function LocaleLayout({
children,
params: { locale },
}: {
children: React.ReactNode,
params: { locale: string },
}) {
// Providing all messages to the client
// side is the easiest way to get started
const messages = await getMessages();
return (
<html lang={locale}>
<body>
<NextIntlClientProvider messages={messages}>
<LangSwitcher />
{children}
</NextIntlClientProvider>
</body>
</html>
);
}
Here is an example of using translation on a client component.
import { useTranslations } from "next-intl";
export default function Index() {
const t = useTranslations("Index");
return (
<div className="container text-center my-5 mx-auto">
<h1 className="text-3xl font-bold">{t("title")}</h1>
</div>
);
}
First, import the useTranslations
hook from next-intl and ****then call it by the object name.
It will provide the associated translations.
You can add more translations like this:
{
"Index": {
"title": "Hallo Welt"
},
{
"About": {
"title": "About Us"
...
}
}
}
This way you can use the translations on a Client Component.
Let’s see how to use the translation on a Server Component.
Server component
For the server component, you don’t have to configure anything else.
Just import getTranslations
and call it with the translation object key.
import React from "react";
import { getTranslations } from "next-intl/server";
const AboutPage = async () => {
const t = await getTranslations("About");
return (
<div className="container text-center my-5 mx-auto">
<h1 className="text-3xl font-bold">{t("title")}</h1>
</div>
);
};
export default AboutPage;
This is how you can use translations on a Server Component.
Now to test our translations let’s create a language switcher.
Language switcher
Create a file named LangSwitcher.tsx in the components folder.
And paste this code into that file.
"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { locales } from "@/i18n";
const LangSwitcher = () => {
const pathName = usePathname();
const redirectedPathName = (locale: string) => {
if (!pathName) return "/";
const segments = pathName.split("/");
segments[1] = locale;
return segments.join("/");
};
return (
<div className="flex space-x-10 justify-center my-5">
{locales.map((locale) => (
<Link
key={locale}
href={redirectedPathName(locale)}
className="capitalize hover:underline hover:text-blue-500"
>
{locale}
</Link>
))}
</div>
);
};
export default LangSwitcher;
This is the language switcher for your Next.js application. It dynamically generates links for each locale in the locales
array, modifying the current path to reflect the selected locale.
When a user clicks on a locale link, they are redirected to the same page but in the chosen language.
Resources:
Documentations: https://next-intl-docs.vercel.app/docs/getting-started
Source code: https://github.com/Coderamrin/next14-i18n-integration
Conclusion
This article showed you how to integrate multi-language support into your Next.js projects.
If you followed this article step by step you should have i18n integrated on your Next.js project.
Comment below if you have any questions or suggestions.
Connect With Me
Happy Coding.