Translate Next.js 16 with next-i18next — App Router Setup Guide

· Intlayer ·

12 min read Original article ↗
Author:

Creation:2025-11-01Last update:2026-05-31

See the application template on GitHub

This page has an application template available.

Version History

  1. Initial version

    v7.0.611/1/2025

Edit this doc

If you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.

GitHub link to the documentation

Copy

Copy doc Markdown to clipboard

How to internationalize your Next.js application using next-i18next in 2026

Table of Contents

What is next-i18next?

next-i18next is a popular internationalization (i18n) solution for Next.js applications. While the original next-i18next package was designed for the Pages Router, this guide shows you how to implement i18next with the modern App Router using i18next and react-i18next directly.

With this approach, you can:

  • Organize translations using namespaces (e.g., common.json, about.json) for better content management.
  • Load translations efficiently by loading only the namespaces needed for each page, reducing bundle size.
  • Support both server and client components with proper SSR and hydration handling.
  • Ensure TypeScript support with type-safe locale configuration and translation keys.
  • Optimize for SEO with proper metadata, sitemap, and robots.txt internationalization.
As an alternative, you can also refer to the next-intl guide, or directly using Intlayer.
See the comparison in next-i18next vs next-intl vs Intlayer.

Practices you should follow

Before we dive into the implementation, here are some practices you should follow:

  • Set HTML lang and dir attributes In your layout, compute dir using getLocaleDirection(locale) and set <html lang={locale} dir={dir}> for proper accessibility and SEO.
  • Split messages by namespace Organize JSON files per locale and namespace (e.g., common.json, about.json) to load only what you need.
  • Minimize client payload On pages, send only required namespaces to NextIntlClientProvider (e.g., pick(messages, ['common', 'about'])).
  • Prefer static pages Use static page as much as possible for better performance and SEO.
  • I18n in server components Server components, like pages or all components not marked as client are statics and can be pre-rendered at build time. So we will have to pass the translation functions to them as props.
  • Set up TypeScript types For your locales to ensure type safety throughout your application.
  • Proxy for redirection Use a proxy to handle the locale detection and routing and redirect the user to the appropriate locale-prefixed URL.
  • Internationalization of your metadata, sitemap, robots.txt Internationalize your metadata, sitemap, robots.txt using the generateMetadata function provided by Next.js to ensure a better discovery by search engines in all locales.
  • Localize Links Localize Links using the Link component to redirect the user to the appropriate locale-prefixed URL. It's important to ensure the discovery of your pages in all locales.
  • Automate tests and translations Automate tests and translations help loosing time to maintain your multilingual application.
See our doc listing everything you need to know about internationalization and SEO: Internationalization (i18n) with next-intl.

Step-by-Step Guide to Set Up i18next in a Next.js Application

See Application Template on GitHub.

Here's the project structure we'll be creating:

Copy code

Copy the code to the clipboard

  1. Install Dependencies

    Install the necessary packages using npm:

    Copy code

    Copy the code to the clipboard

    • i18next: The core internationalization framework that handles translation loading and management.
    • react-i18next: React bindings for i18next that provide hooks like useTranslation for client components.
    • i18next-resources-to-backend: A plugin that enables dynamic loading of translation files, allowing you to load only the namespaces you need.
  2. Configure Your Project

    Create a configuration file to define your supported locales, default locale, and helper functions for URL localization. This file serves as the single source of truth for your i18n setup and ensures type safety throughout your application.

    Centralizing your locale configuration prevents inconsistencies and makes it easier to add or remove locales in the future. The helper functions ensure consistent URL generation for SEO and routing.

    Copy code

    Copy the code to the clipboard

  3. Centralize Translation Namespaces

    Create a single source of truth for every namespace your application exposes. Reusing this list keeps server, client, and tooling code in sync and unlocks strong typing for translation helpers.

    Copy code

    Copy the code to the clipboard

  4. Strongly Type Translation Keys with TypeScript

    Augment i18next to point at your canonical language files (usually English). TypeScript then infers valid keys per namespace, so calls to t() are checked end-to-end.

    Copy code

    Copy the code to the clipboard

    Tip: Store this declaration under src/types (create the folder if it doesn't exist). Next.js already includes src in tsconfig.json, so the augmentation is picked up automatically. If not, add the following to your tsconfig.json file:

    Copy code

    Copy the code to the clipboard

    With this in place you can rely on autocomplete and compile-time checks:

    Copy code

    Copy the code to the clipboard

  5. Set Up Server-Side i18n Initialization

    Create a server-side initialization function that loads translations for server components. This function creates a separate i18next instance for server-side rendering, ensuring that translations are loaded before rendering.

    Server components need their own i18next instance because they run in a different context than client components. Pre-loading translations on the server prevents flash of untranslated content and improves SEO by ensuring search engines see translated content.

    Copy code

    Copy the code to the clipboard

  6. Create Client-Side i18n Provider

    Create a client component provider that wraps your application with i18next context. This provider receives pre-loaded translations from the server to prevent flash of untranslated content (FOUC) and avoid duplicate fetching.

    Client components need their own i18next instance that runs in the browser. By accepting pre-loaded resources from the server, we ensure seamless hydration and prevent content flashing. The provider also manages locale changes and namespace loading dynamically.

    src/components/I18nProvider.tsx

    Copy code

    Copy the code to the clipboard

  7. Define Dynamic Locale Routes

    Set up dynamic routing for locales by creating a [locale] directory in your app folder. This allows Next.js to handle locale-based routing where each locale becomes a URL segment (e.g., /en/about, /fr/about).

    Using dynamic routes enables Next.js to generate static pages for all locales at build time, improving performance and SEO. The layout component sets the HTML lang and dir attributes based on the locale, which is crucial for accessibility and search engine understanding.

    src/app/[locale]/layout.tsx

    Copy code

    Copy the code to the clipboard

  8. Create Your Translation Files

    Create JSON files for each locale and namespace. This structure allows you to organize translations logically and load only what you need for each page.

    Organizing translations by namespace (e.g., common.json, about.json) enables code splitting and reduces bundle size. You only load the translations needed for each page, improving performance.

    src/locales/en/common.json

    Copy code

    Copy the code to the clipboard

    src/locales/fr/common.json

    Copy code

    Copy the code to the clipboard

    Copy code

    Copy the code to the clipboard

    Copy code

    Copy the code to the clipboard

    src/locales/en/about.json

    Copy code

    Copy the code to the clipboard

    src/locales/fr/about.json

    Copy code

    Copy the code to the clipboard

  9. Utilize Translations in Your Pages

    Create a page component that initializes i18next on the server and passes translations to both server and client components. This ensures that translations are loaded before rendering and prevents content flashing.

    Server-side initialization loads translations before the page renders, improving SEO and preventing FOUC. By passing pre-loaded resources to the client provider, we avoid duplicate fetching and ensure smooth hydration.

    src/app/[locale]/about/index.tsx

    Copy code

    Copy the code to the clipboard

  10. Use Translations in Client Components

    Client components can use the useTranslation hook to access translations. This hook provides access to the translation function and the i18n instance, allowing you to translate content and access locale information.

    Client components need React hooks to access translations. The useTranslation hook integrates seamlessly with i18next and provides reactive updates when the locale changes.

    Ensure the page/provider includes only the namespaces you need (e.g., about).
    If you use React < 19, memoize heavy formatters like Intl.NumberFormat.

    src/components/ClientComponent.tsx

    Copy code

    Copy the code to the clipboard

  11. Use Translations in Server Components

    Server components cannot use React hooks, so they receive translations via props from their parent components. This approach keeps server components synchronous and allows them to be nested inside client components.

    Server components that might be nested under client boundaries need to be synchronous. By passing translated strings and locale information as props, we avoid async operations and ensure proper rendering.

    src/components/ServerComponent.tsx

    Copy code

    Copy the code to the clipboard

  12. Change the language of your content

    Optional

    To change the language of your content in Next.js, the recommended way is to use locale-prefixed URLs and Next.js links. The example below reads the current locale from the route, strips it from the pathname, and renders one link per available locale.

    src/components/LocaleSwitcher.tsx

    Copy code

    Copy the code to the clipboard

  13. Optional

    Reusing localized URLs across your app keeps navigation consistent and SEO-friendly. Wrap next/link in a small helper that prefixes internal routes with the active locale while leaving external URLs untouched.

    src/components/LocalizedLink.tsx

    Copy code

    Copy the code to the clipboard

    Tip: Because LocalizedLink is a drop-in replacement, migrate gradually by swapping imports and letting the component handle locale-specific URLs.
  14. Access the active locale inside Server Actions

    Optional

    Server Actions often need the current locale for emails, logging, or third-party integrations. Combine the locale cookie set by your proxy with the Accept-Language header as a fallback.

    src/app/actions/get-current-locale.ts

    Copy code

    Copy the code to the clipboard

    Because the helper relies on Next.js cookies and headers, it works in Route Handlers, Server Actions, and other server-only contexts.
  15. Internationalize Your Metadata

    Optional

    Translating content is important, but the main goal of internationalization is to make your website more visible to the world. I18n is an incredible lever to improve your website visibility through proper SEO.

    Properly internationalized metadata helps search engines understand what languages are available on your pages. This includes setting hreflang meta tags, translating titles and descriptions, and ensuring canonical URLs are correctly set for each locale.

    Here's a list of good practices regarding multilingual SEO:

    • Set hreflang meta tags in the <head> tag to help search engines understand what languages are available on the page
    • List all page translations in the sitemap.xml using the http://www.w3.org/1999/xhtml XML schema
    • Do not forget to exclude prefixed pages from the robots.txt (e.g., /dashboard, /fr/dashboard, /es/dashboard)
    • Use custom Link component to redirect to the most localized page (e.g., in French <a href="/fr/about">À propos</a>)

    Developers often forget to properly reference their pages across locales. Let's fix that:

    src/app/[locale]/about/layout.tsx

    Copy code

    Copy the code to the clipboard

  16. Internationalize Your Sitemap

    Optional

    Generate a sitemap that includes all locale versions of your pages. This helps search engines discover and index all language versions of your content.

    A properly internationalized sitemap ensures search engines can find and index all language versions of your pages. This improves visibility in international search results.

    Copy code

    Copy the code to the clipboard

  17. Internationalize Your robots.txt

    Optional

    Create a robots.txt file that properly handles all locale versions of your protected routes. This ensures that search engines don't index admin or dashboard pages in any language.

    Properly configuring robots.txt for all locales prevents search engines from indexing sensitive pages in any language. This is crucial for security and privacy.

    Copy code

    Copy the code to the clipboard

  18. Set Up Middleware for Locale Routing

    Optional

    Create a proxy to automatically detect the user's preferred locale and redirect them to the appropriate locale-prefixed URL. This improves user experience by showing content in their preferred language.

    Middleware ensures that users are automatically redirected to their preferred language when they visit your site. It also saves the user's preference in a cookie for future visits.

    Copy code

    Copy the code to the clipboard

  19. Automate Your Translations Using Intlayer

    Optional

    Intlayer is a free and open-source library designed to assist the localization process in your application. While i18next handles the translation loading and management, Intlayer helps automate the translation workflow.

    Managing translations manually can be time-consuming and error-prone. Intlayer automates translation testing, generation, and management, saving you time and ensuring consistency across your application.

    Intlayer will allows your to:

    • Declare your content where you want in your codebase Intlayer allows to declare your content where you want in your codebase using .content.{ts|js|json} files. It will allow a better organization of your content, ensuring better readability and maintainability of your codebase.

    • Test missing translations Intlayer provide test functions to that can be integrated in your CI/CD pipeline, or in your unit tests. Learn more about testing your translations.

    • Automate your translations, Intlayer provide a CLI and a VSCode extension to automate your translations. It can be integrated in your CI/CD pipeline. Learn more about automating your translations. You can use your own API key, and the AI provider of your choice. It also provide context aware translations, see fill content.

    • Connect external content Intlayer allows you to connect your content to an external content management system (CMS). To fetch it in a optimized way and insert it in your JSON resources. Learn more about fetching external content.

    • Visual editor Intlayer offers an free visual editor to edit your content using a visual editor. Learn more about visual editing your translations.

    And more. To discover all the features provided by Intlayer, please refer to the Interest of Intlayer documentation.

Once you have namespaces like common.json and about.json typed through i18next's module augmentation, you've effectively defined a content schema. The next question is where that schema lives and who edits it. Sanity treats it as first-class: you model fields, references, and validation in code, and editors work against that same model in Sanity Studio instead of hand-editing JSON per locale.

Content lives in the Content Lake as structured JSON, queryable through GROQ and served via API, with locale as a field rather than a folder. For a Next.js App Router setup, you can fetch a namespace on the server, pass it into your i18n provider exactly as this pattern expects, and let the same source feed apps, emails, and agents. As locales and surfaces grow, the schema stays the contract; the delivery layer stays i18next.

Make existing Vite & React app multilinguali18n using next-intl

Comments

No comments yet. Be the first to share your thoughts.

Related Posts

Last Posts