Next.js Localization Free

i18n & l10n in Next.js projects (Pages Router)

Try Crowdin

Next.js Localization: The Complete Guide

Copy link

To properly internationalize your Next.js project and make it multilingual, there are two biggest problems to solve:

  1. Project Internationalization
  2. Content Localization

Next.js Internationalization

Copy link

Internationalization (often abbreviated as i18n) is the foundational process of preparing your Next.js application's code and architecture to support multiple languages and regions without requiring major re-engineering. For effective Next.js internationalization, consider the following aspects in your projects:

Next.js Multilingual Routing

Copy link

Multilingual routing is a built-in feature starting from Next.js version v10 and a huge helper. Localized routing is here for several reasons. You want to preserve a preferred locale while the user browses around or shares an URL and give search bots a better idea about how your multilingual website is structured.

Next.js would allow you to store locale in a domain name (sub-domains like fr.crowdin.com and TLD crowdin.ee) or as a Sub-path of the URL, i.e., crowdin.com/ee/, crowdin.com/fr.

To add Next.js multilanguage to your project, you want to add the respective config to your next.config.js file.

Sample for Sub-path Routing Config

Copy link
module.exports = {
  i18n: {
    locales: ['en-US', 'ee', 'fr'],
    defaultLocale: 'en-US',
  },
}

If your project is already in production, all your existing pages will open as usual, but you will get new URLs available:

  • /ee/page
  • /fr/page

Sample Domain Routing

Copy link

Storing a locale in a domain name is another way to keep your Next.js project aware of which language the current visitor prefers. While this approach is usually more tricky and expensive (you should own proper TLDs), it is believed to bring some SEO benefits and has a better brand impact. This method improves Next.js localization and can streamline Next.js translation efforts for a better user experience.

Below is your next.config.js config template.

module.exports = {
  i18n: {
    locales: ['en-US', 'fr', 'ee'],
    defaultLocale: 'en-US',
    domains: [{
        domain: 'crowdin.com',
        defaultLocale: 'en-US',
      }, {
        domain: 'crowdin.ee',
        defaultLocale: 'fr',
      }, {
        domain: 'fr.crowdin.com',
        defaultLocale: 'fr-FR',
        locales: ['fr-BE'],
      }],
  },
}

Note: All domains crowdin.com, crowdin.ee, fr.crowdin.com, fr-be.crowdin.com should be pointed to your server.

You might have noticed that the configuration for the French locale has additional locales property. If you use a locale with a region format (like fr-FR), you can list all the language dialects that should lead to this locale.

Choosing an i18n Library for Next.js

Copy link

Next.js i18n does not have a recommended approach for content localization. So you can choose a toolset depending on content type and needs. The content you publish can also be in a variety of formats. UI elements usually reside in the resource files (in key-value files), and articles might come from your headless CMS or Markdown files.

Using Plain JSON Files to Store Next.js Localization Keys

Copy link

A regular JSON file might be everything you need if you work on a simple project like a Blog.

{
  "blog.header": "Sample Next.js",
  "blog.date": "Posted by {{author}}",
}

Avoid concatenating strings that will be localized, as this breaks context for translators. Instead, use clear placeholders like {{author}} within a single, complete string to help them get better-quality translations.

Translators might still need more information about how your keys are used in the UI. Usually, you can provide more contextual information for your keys in your TMS.

If you go with this hand-made localization approach, keep your JSON files in a separate directory and name with a ${locale-code}.json.

When the multilingual routing is done, you can find a locale property in the useRouter() hook. Th​at​ is a visitor's preferred locale. Require a proper locale and use values from localized JSONs as myLocale.stringKey everywhere you need a text label in the UI.

Choosing an Next.js i18n Library

Copy link

If you work on anything more complex than a Blog or a small, static website, you might want to consider having a specialized i18n library for your UI text management.

Here's a quick questionary that might help you decide:

  • Will you need plurals management? (UI labels like: "One file added" or "5 files added" depending on the quantity)
  • Will you have gender-dependent labels? (like: "Sebastian invited Victoria to his sandbox" or "Victoria invited Sebastian to her sandbox," depending on the gender of an actor)
  • Will you need complex formatting for currencies, dates, and numbers?

An i18n library would typically bring even more value than mentioned above, things like fallback management of untranslated keys, advanced context management, which is highly valuable and help to produce higher quality translations, and more. But integrating the i18n library might require a little more effort, especially if it's your first experience.

Some of the most frequently used i18n libs in Next.js projects are i18next, React Intl. And a more advanced like FBT and Project Fluent. FBT and FTL were developed and used by Facebook and Mozilla, respectively. They would guide you while creating your UI texts and guarantee the localization will be as good as possible for many languages.

Next.js Content Localization

Copy link

Now, when your project is ready to be translated, you might have the following setup:

One of the main objectives you want when building your workflow is that you don't want to speak to translators every time you change something in your source content. This is why a TMS is so important.

The workflow you are looking for might work like the following:

  • Automated Branch Localization: When you introduce new UI texts on a GitHub branch, the workflow should automatically trigger translation before merging to main.
  • Staging Content Sync: Your headless CMS should sync new content from staging environments, allowing translators to work before release.
  • Delta Content Detection: For minor text changes, your TMS should automatically detect the difference and notify translators, avoiding manual oversight.

This approach is key to agile localization, and it's precisely what Crowdin helps you achieve. Crowdin connects directly to your content repositories (like GitHub) and headless CMS platforms, or accepts various file types (like PDFs, docx, Youtube subtitles), ensuring you can go multilingual while staying agile.

Next.js Translation Quality Management Strategies

Copy link

Here at Crowdin, we believe that there are no terrible translators. Any bilingual person can deliver decent-quality translations. We had seen that many times when the community was doing a fantastic job translating games, knowledge bases, and open-source software.

What is killing translations' quality is a lack of context. Traditional translation tools would present translators with a list of texts. While not sure about the context, translators will make assumptions. Where assumptions are, errors are guaranteed.

Crowdin provides a range of quality management features, including Glossaries for consistent terminology and collaboration tools that allow translators to ask context-specific questions, which ensures higher accuracy.

But some things still are on developers. What you can do to increase high UI texts translations quality is this:

  • Provide textual information for every key in your resource files (this is where the i18n library is useful again, there's no easy way to add contextual information if you store your keys in plain JS object)
  • Provide screenshots, ideally setup an automated screenshots upload to Crowdin during your build process
  • Set up a Crowdin In-Context so translators can preview or even do translations on the live application. Crowdin In-Context can also be a source of the screenshots for your keys.

React Intl Sample Resource File

{
   "app.name":{
      "defaultMessage":"Umbrella Editor",
      "description":"an app name. Umbrella should not be translated"
   },
   "app.menu.save_as_label":{
      "defaultMessage":"Save as...",
      "description":"Used in main menu"
   }
}

When translating Markdown files or Rich Text content from your headless CMS, Crowdin will try to preserve as much context as possible by rendering a WYSIWYG view to translators.

Additional Next.js Localization Features

Copy link

Automatic locale detection

That is surprisingly cool that Next.js will automatically check the Accept-Language header and redirect a visitor to the proper locale. Because visitors usually configure their operating system to the language they prefer, with this feature, they will see content in their locale even if they visit a default route. It is recommended to list all the dialects your visitors might have in their settings to give them an even better experience while browsing your website.

This feature is configured by the localeDetection property in your i18n config object. It is set as true by default.

It is recommended, though, to store the user-selected locale in a NEXT_LOCALE cookie. That is how Next.js will not do an auto-detect of the locale if a user prefers the en locale while having the fr locale configured in a browser.

Wrapping up

Copy link

Next.js is a modern framework made with localization in mind. Localization is not just internationalization or the actual translator's work, but it is always an investment as well as new development workflows. Book a demo with a Crowdin expert to find out what workflow will work best for your business.

Check out our complete code of a minimalistic Next.js app on Github or play with it on a CodeSandbox.

Localize your product with Crowdin

Automate content updates, boost team collaboration, and reach new markets faster.

Crowdin is a platform that helps you manage and translate content into different languages. Integrate Crowdin with your repo, CMS, or other systems. Source content is always up to date for your translators, and translated content is returned automatically.

Learn More
Categories
Development
Works with
  • Crowdin Enterprise
  • crowdin.com
Details

Released on Sep 25, 2022

Updated on Jul 14, 2025

Published by Community

Identifier:nextjs-localization

Built by Crowdin
GitHub