Nextjs 13 App Router internalization without sub-routing or domain – Javascript

by
Liam Thompson
internationalization next.js next.js13 reactjs

Quick Fix: Implement Next.js 13 App Router internationalization with server components support without sub-routing or domain-based locale detection. Utilize the next-intl, @formatjs/intl-localematcher, and negotiator packages. Create a middleware to handle locale detection and provide language context to both client and server components.

The Problem:

How can I implement internalization (i18n) in a Next.js 13 application using App Route (not Pages Route) without creating sub-routes or domains? I want to fetch the user’s preferred language from the database and apply it to the entire application dynamically.

The Solutions:

Solution 1: I18n using Server Components, Client Components and middleware

Implement i18n by leveraging server components, client components, and a custom middleware:

  1. Install Necessary Packages:

    • npm install @formatjs/intl-localematcher negotiator next-int && npm install -D @types/negotiator server-only
  2. Define i18n Configuration:

    • Create i18n.config.ts to manage i18n configuration.
    • Define the default locale and available locales.
  3. Create a Dictionary for Server Components:

    • In dictionary.ts, define a function to fetch JSON translations for each locale.
  4. Detect Locale:

    • Implement a getLocale function to detect the user’s preferred locale from request headers.
  5. Create Middleware:

    • Define a middleware in middleware.ts to handle locale detection and internationalization.
    • Utilize the next-intl/middleware package for internationalization.
  6. Define Types for Server Component IntelliSense:

    • Add type definitions for server component IntelliSense in global.d.ts.
  7. Create a Provider for Client Components:

    • In providers.tsx, define a client component provider (Providers) that wraps the app with internationalization context.
  8. Move Routes to [lang] Folders:

    • Move each route from the app directory to a corresponding [lang] folder.
  9. Root Layout with Locale Handling:

    • Create a layout component (layout.tsx) that wraps app content and handles locale-specific JSON translations.
  10. Client Component Usage:

    • Use useTranslations from next-intl to access translations in client components.
  11. Server Component Usage:

    • Utilize getDictionary to fetch translations for server components.

Solution 2: Using Next.js Headers

You can leverage the next/headers module to read the browser header related to the language and use it as a value without changing the route or using sub-routes.

  1. Import the headers module:

    import { headers } from 'next/headers';
    
  2. Use the headers module to get the accept-language header:

    const headersList = headers();
    const lang = headersList.get('accept-language');
    
  3. Use the lang value to set the language for your application:

    const locale = lang.split('-')[0]; // Get the first part of the language code (e.g., 'en')
    i18n.changeLanguage(locale); // Set the language in your i18n library
    
  4. Display the localized content based on the selected language:

    const { t } = useTranslation();
    
    return (
      <div>
        {t('lang')}
      </div>
    );
    

This approach allows you to set the language based on the browser’s accept-language header without modifying the URL or using sub-routes.

Q&A

Can I use internalization without changing the route or using sub-routes?

Yes, you can use next/headers to read browser header related to language without changing the route or using sub-routes.

Do I need to use sub-routes like /en or domain like mywebsite.lang to use internalization?

No, you don’t have to use sub-routes or change the domain.

Video Explanation:

The following video, titled "Internationalization (i18n) with Next.js! - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

Learn how to use Internationalized Routing with Next.js to support multiple languages on your site! 0:00 – Introduction 0:46 – Routing + ...