Blog Add internationalization to a Next.js site

Add internationalization to a Next.js site

2 min read

Add internationalization to a Next.js site
TL;DR Give each language its own URL path, store translations in per-locale files, and add hreflang alternates so search engines connect the versions. Keep the locale in the URL, not just a cookie, so every language is crawlable and shareable.

Making a Next.js site multilingual is mostly about three things done consistently: routing by language, storing translations cleanly, and telling search engines how the versions relate. Get those right and the rest follows.

Put the locale in the URL

Each language should live at its own path: /en/about, /fr/about. The App Router supports a locale segment, so you structure routes under a [locale] folder and read the active language from the URL.

The important rule is that the locale belongs in the URL, not only in a cookie or an Accept-Language header. A URL-based locale is crawlable and shareable; a cookie-based one hides every language but the default from search engines and from anyone you send a link to.

Store translations separately

Keep strings out of your components, in per-locale files keyed by a stable identifier:

// en.json
{ "cta.contact": "Get in touch" }
// fr.json
{ "cta.contact": "Contactez-moi" }

Components look up the key for the current locale:

<button>{t("cta.contact")}</button>

This keeps translation separate from code, so a translator works on the files without touching components, and adding a language is adding a file.

Tell search engines with hreflang

Search engines need to know that /en/about and /fr/about are the same page in different languages, or they may treat them as duplicates. hreflang alternates make the relationship explicit. In the App Router, set them in the metadata:

alternates: {
  languages: {
    "en": "/en/about",
    "fr": "/fr/about",
  },
}

Now each version points at the others, and search shows the right language to the right user.

The pieces together

Locale in the path for crawlable, shareable pages. Translations in per-locale files, separate from code. hreflang so search engines connect the versions. That is the backbone of a multilingual Next.js site. Add a language picker on top for humans, but build on those three foundations first, because they are what make the other languages actually reachable and correctly understood.

FAQ

Should the language be in the URL?

Yes. Put the locale in the path, like /en and /fr, so each language has its own crawlable, shareable URL. Relying only on a cookie or header to switch language hides the other versions from search engines and from anyone sharing a link.

What is hreflang for?

hreflang tells search engines that two URLs are the same content in different languages, so they show the right one to the right user and do not treat them as duplicates. Each localized page lists itself and its alternates.

How should I store translations?

Keep strings in per-locale files, one per language, keyed by a stable identifier. Your components look up the key for the active locale. That keeps translation separate from code and easy to hand to a translator.