Reactician

Internationalization (i18n) in Next.js: Building Multi-language Sites

Ever wanted your Next.js app to greet users in their own language, but felt lost in the maze of routing, translation files, and browser settings? You're not alone. Internationalization (i18n) is essential for global audiences, but it can feel overwhelming to implement cleanly—especially with the new App Router.

Let's break it down. Imagine you're building a site for a global audience. You want Dutch users to see Dutch, English users to see English, and everyone to land on the right version of your site automatically. But as soon as you start thinking about how to detect the user's language, organize your routes, and keep your translations tidy, things can get messy fast. Without a clear structure, you might end up with duplicated code, confusing navigation, or missing translations.

The Problem

Supporting multiple languages isn't just about swapping out text. You need to figure out how to detect the user's preferred language, redirect them if needed, and make sure your URLs and SEO play nicely with all this. And you want to do it in a way that doesn't bloat your client bundle or make your codebase a nightmare to maintain.

The Solution

Here's where Next.js 14's App Router shines. By using a route segment, you can make the current language available to every page and layout in your app. This keeps your routing clean and your code organized. Translation files can be loaded dynamically on the server, so you're not sending every language to every user. And with a bit of middleware, you can detect a user's preferred language and send them to the right place automatically. Static generation works seamlessly with this setup, so you can pre-render pages for each supported language without any extra fuss.

Let's see how this works in practice.

1. Set Up Locale-Aware Routing

First, organize your app with a segment:


This structure makes the current language available to every page and layout.

2. Server-Only Translation Loading

Keep your translation files out of the client bundle by loading them dynamically on the server:


3. Use Translations in Your Pages

Now, fetch the right dictionary in your page or layout:


4. Middleware for Language Detection

Want to automatically send users to their preferred language? Add a middleware:


5. Static Generation for Locales

To pre-render pages for each language, use :


What You Need to Know

If you use a segment, you'll keep your routing clean and your code organized. Loading translations server-side means your users only get what they need, and your app stays fast. Middleware can boost the user experience by sending people to the right language automatically, and static generation works seamlessly with locales—so you get all the performance benefits of pre-rendering, no matter how many languages you support.

Watch Out For

Don't forget to update your translation files as your app grows. Make sure your middleware doesn't redirect internal Next.js paths (like ). If you add more languages, update your config and static params everywhere. And always test your SEO and navigation for each locale.

With this setup, you'll have a scalable, maintainable foundation for a truly global Next.js app—without the headaches.


This configuration tells Next.js to support English and Dutch, with English as the default. Automatic locale detection will redirect users based on their browser settings.


Here, translation files (e.g., , ) are loaded and selected based on the current locale. This approach works well for small projects or as a starting point before introducing a more advanced i18n library.

Stephan Lagerwaard
Stephan Lagerwaard
Frontend Engineer at Fiberplane.