DEV Community

Cover image for Implementing Internationalization (i18n) in Next.js 14 using App Router
Fabrikapp
Fabrikapp

Posted on

Implementing Internationalization (i18n) in Next.js 14 using App Router

Welcome to our new tech post. Today we're delving (naaah, just kidding), we're implementing the most complete and renowned Internationalization library for NextJS 14. This article will be adapted to App Router, but works for Page Router

Introduction to Internationalization (i18n)

Internationalization (i18n) is a crucial aspect of modern web development that enables websites and applications to cater to a global audience. In today's interconnected world, businesses and organizations need to reach users from various linguistic and cultural backgrounds to maximize their impact and success. By implementing i18n, developers can create inclusive and accessible digital experiences that adapt to the user's preferred language and region.

The importance of i18n in web development cannot be overstated. It allows for:

  1. Global Reach: With i18n, websites can expand their reach to users worldwide, regardless of their native language or location. This opens up new market opportunities and fosters a diverse user base.

  2. Enhanced User Experience: Users feel more comfortable and engaged when they can access content in their preferred language. i18n ensures that the user interface, navigation, and content are presented in a language that the user understands, leading to a more satisfying and personalized experience.

  3. Cultural Sensitivity: i18n goes beyond mere translation; it also considers cultural nuances, local conventions, and regional preferences. By adapting content to specific locales, websites can demonstrate cultural sensitivity and build trust with their target audience.

  4. Competitive Advantage: In a globalized market, websites that offer multilingual support gain a competitive edge. Users are more likely to engage with and recommend websites that cater to their language preferences, leading to increased traffic, conversions, and customer loyalty.

As web technologies evolve, it is essential for developers to stay up-to-date with the latest tools and best practices for implementing i18n. Next.js, a popular React framework for building server-rendered and statically generated applications, has introduced significant improvements in its version 14 release, particularly with the new App Router stack. This tutorial will guide you through the process of setting up and implementing i18n in a Next.js 14 project using the App Router, enabling you to create scalable and efficient multilingual applications.

Setting up Internationalization in Next.js 14 with App Router

Step 1: Create a Next.js Project

To get started, create a new Next.js project using the following command:

npx create-next-app@latest my-i18n-app
Enter fullscreen mode Exit fullscreen mode

When prompted, select the following options:

  • Choose a template: Default starter app
  • Use TypeScript: Yes
  • Use ESLint: Yes
  • Use Tailwind CSS: No
  • Use src/ directory: No
  • Use App Router: Yes
  • Use default import alias: Yes

This will create a new Next.js project with the App Router enabled and TypeScript support.

Step 2: Install Required Dependencies

Navigate to the project directory and install the necessary dependencies for i18n:

cd my-i18n-app
npm install next-intl
Enter fullscreen mode Exit fullscreen mode

next-intl is a powerful library that simplifies the process of internationalizing Next.js applications.

Step 3.1: Configure i18n in i18n.ts

With that setup, you won't edit the next.config.js as you're probably used to.

Open the src/i18n.ts file in the project root and add the following configuration:

import { notFound } from "next/navigation";
import { getRequestConfig } from "next-intl/server";

// Can be imported from a shared config
export const locales = ["en", "fr", "es", "de"];

export default getRequestConfig(async ({ locale }) => {
  // Validate that the incoming `locale` parameter is valid
  if (!locales.includes(locale as any)) notFound();

  return {
    messages: (await import(`../public/locales/${locale}.json`)).default,
  };
});

Enter fullscreen mode Exit fullscreen mode

Step 3.2: Create a middleware to manage localized routing src/middleware.ts

import createMiddleware from "next-intl/middleware";
import { locales } from "./i18n";

export default createMiddleware({
  // A list of all locales that are supported
  locales: locales,

  // Used when no locale matches
  defaultLocale: "en",
  // Used to make the default lang as root
  localePrefix: "as-needed",
});

export const config = {
  // Match only internationalized pathnames
  matcher: ["/", "/(en)/:path*"],
};


Enter fullscreen mode Exit fullscreen mode

In this example, we specify the supported locales (en, fr, and es) and set the default locale to en. Adjust these values according to your project's requirements.

Step 4: Create Translation Files

Create a new directory called locales in the project root and add translation files for each supported locale. For example:

  • locales/en.json:
  {
    "hello": "Hello",
    "welcome": "Welcome to my website"
  }
Enter fullscreen mode Exit fullscreen mode
  • locales/fr.json:
  {
    "hello": "Bonjour",
    "welcome": "Bienvenue sur mon site web"
  }
Enter fullscreen mode Exit fullscreen mode
  • locales/es.json:
  {
    "hello": "Hola",
    "welcome": "Bienvenido a mi sitio web"
  }
Enter fullscreen mode Exit fullscreen mode

These JSON files contain key-value pairs representing the translations for each locale.

Step 5: Implement Internationalization in Pages

Create a new page called index.tsx in the app directory and add the following code:

import { useTranslations } from "next-intl";

export default function Home() {
  const t = useTranslations("Index");

  return (
    <div>
      <h1>{t("hello")}</h1>
      <p>{t("welcome")}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In this example, we import the useTranslations hook from next-intl and use it to access the translations for the current locale. The t function is used to retrieve the translated values based on the provided keys.

Step 6: Run the Development Server

Start the development server by running the following command:

npm run dev
Enter fullscreen mode Exit fullscreen mode

Open your browser and navigate to http://localhost:3000. You should see the translated content based on the default locale (English).

To test the internationalization, append the locale to the URL. For example:

  • http://localhost:3000/fr: French version
  • http://localhost:3000/es: Spanish version

The page content will update accordingly based on the selected locale.

Real-World Use Cases and Examples

Let's explore some practical examples and real-world use cases to demonstrate how internationalization functions within a full-stack application.

Example 1: E-commerce Website

Consider an e-commerce website that sells products globally. Implementing i18n allows the website to:

  • Display product descriptions, prices, and shipping information in the user's preferred language.
  • Adapt the checkout process to include locale-specific payment methods and currency formats.
  • Provide localized customer support and FAQs based on the user's language.
  • Send order confirmation emails and notifications in the user's language.

By offering a localized experience, the e-commerce website can attract and retain customers from different regions, increasing sales and customer satisfaction.

Example 2: Travel Booking Platform

A travel booking platform that serves users from various countries can benefit greatly from i18n:

  • Present destination descriptions, hotel reviews, and travel guides in multiple languages.
  • Allow users to search for and book accommodations, flights, and activities in their preferred language.
  • Display prices and booking details in the user's local currency and date format.
  • Provide customer support and resolve inquiries in the user's language.

Implementing i18n in a travel booking platform enhances the user experience, builds trust, and encourages bookings from a global customer base.

Example 3: Educational Website

An educational website that offers online courses and learning resources can leverage i18n to:

  • Deliver course content, video subtitles, and quizzes in multiple languages.
  • Adapt the user interface and navigation to support right-to-left languages for a seamless learning experience.
  • Provide localized study materials, such as pdfs and presentations, in the user's language.
  • Enable multilingual discussion forums and peer-to-peer interactions.

By offering educational content in various languages, the website can reach learners from different backgrounds, promote inclusivity, and expand its user base.

Code Snippets and Implementation Details

Here are some code snippets and implementation details to help TypeScript developers understand how to implement i18n in Next.js 14 using the App Router.

Defining Translation Keys

Create a types/i18n.ts file to define the translation keys as TypeScript types:

export type TranslationKeys = {
  hello: string;
  welcome: string;
  // Add more translation keys as needed
};
Enter fullscreen mode Exit fullscreen mode

This ensures type safety and provides autocompletion when accessing translations in your code.

Using Translations in Components

To use translations in your components, follow these steps:

  1. Import the useTranslations hook and the TranslationKeys type:
import { useTranslations } from "next-intl";
import { TranslationKeys } from "@/types/i18n";
Enter fullscreen mode Exit fullscreen mode
  1. Use the useTranslations hook to access the translations:
export default function MyComponent() {
  const t = useTranslations<TranslationKeys>("MyComponent");

  return (
    <div>
      <h1>{t("hello")}</h1>
      <p>{t("welcome")}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

The useTranslations hook takes a namespace parameter to scope the translations to a specific component or page.

Handling Dynamic Translations

To handle dynamic translations with interpolation, you can use the t function with placeholders:

const name = "John";
const translatedMessage = t("greeting", { name });
Enter fullscreen mode Exit fullscreen mode

In the corresponding translation file:

{
  "greeting": "Hello, {name}!"
}
Enter fullscreen mode Exit fullscreen mode

The placeholders in the translation key will be replaced with the provided values.

Formatting Dates and Numbers

To format dates and numbers according to the user's locale, you can use the useFormatter hook from next-intl:

import { useTranslations, useFormatter } from "next-intl";

const InternationalShowcase = () => {
  const t = useTranslations("Common");

  const formattedDate = useFormatter().dateTime(new Date(), {
    year: "numeric",
    month: "long",
    day: "numeric",
    hour: "numeric",
    minute: "numeric",
    hour12: true,
  });

  const formattedNumber = useFormatter().number(123456789, {
    style: "currency",
    currency: "USD",
  });

  const name = "John";
  const translatedMessage = t("greeting", { name });

  return (
    <div className="p-4">
      <h1 className="text-xl font-bold">{t("title")}</h1>
      <p>{t("description")}</p>
      <p>{translatedMessage}</p>
      <p>{t("date", { date: formattedDate })}</p>
      <p>{t("number", { number: formattedNumber })}</p>
    </div>
  );
};

export default InternationalShowcase;
Enter fullscreen mode Exit fullscreen mode

The useFormatter hook provides various formatting methods that automatically adapt to the user's locale.

Best Practices for Scalable and Efficient i18n

To maintain scalable and efficient internationalization in Next.js projects, consider the following best practices:

  1. Use a Translation Management System (TMS): As your application grows, managing translations across multiple files and locales can become challenging. Consider using a TMS like Crowdin, Transifex, or Phrase to streamline the translation process, collaborate with translators, and ensure consistency.

  2. Separate Translations from Code: Keep your translation files separate from your codebase. This allows for easier maintenance, updates, and collaboration with translators who may not be familiar with the codebase.

  3. Utilize Automatic Language Detection: Implement automatic language detection based on the user's browser settings or geolocation. This provides a seamless experience for users by displaying content in their preferred language without explicit selection.

  4. Optimize Translation Loading: Load translations efficiently by splitting them into smaller chunks and loading only the necessary translations for each page or component. This improves performance and reduces the initial bundle size.

  5. Handle Missing Translations: Implement fallback mechanisms to handle missing translations gracefully. Provide default or fallback values to ensure a consistent user experience even if translations are incomplete or unavailable.

  6. Test Internationalization: Thoroughly test your application with different locales and languages to ensure proper rendering, formatting, and functionality. Use automated testing tools and engage with native speakers to identify any localization issues.

  7. Consider RTL Support: If your application supports languages with right-to-left (RTL) scripts, ensure that your UI components and layouts adapt accordingly. Use CSS flexbox or grid to handle RTL layouts and test your application with RTL locales.

  8. Continuously Update Translations: Keep your translations up to date as your application evolves. Establish a process for updating translations whenever new features or content are added, and regularly review and refine existing translations based on user feedback and analytics.

By following these best practices, you can create a scalable and efficient internationalization setup that accommodates future growth and ensures a positive user experience across different locales.

Conclusion

Implementing internationalization (i18n) in Next.js 14 using the App Router stack is a powerful way to create multilingual applications that cater to a global audience. By following the step-by-step guide and best practices outlined in this tutorial, developers can set up i18n in their Next.js projects efficiently.

Remember to consider the practical examples and real-world use cases discussed to understand how i18n functions within a full-stack application. The code snippets and implementation details provided will help TypeScript developers implement i18n effectively in their Next.js projects.

As you embark on your internationalization journey, keep in mind the importance of scalability, performance, and user experience. Continuously iterate and improve your i18n setup based on user feedback and evolving requirements.

By embracing internationalization, you open up your application to a wider audience, increase inclusivity, and unlock new opportunities for growth and success in the global market.

Checkout the repository with example :
https://github.com/FabrikappAgency/tutorial-nextjs-i18n

Run on Gitpod

External Sources

  1. Next.js Internationalization Documentation: https://nextjs.org/docs/advanced-features/i18n-routing
  2. next-intl Library: https://github.com/amannn/next-intl
  3. React Intl Documentation: https://formatjs.io/docs/react-intl/
  4. Crowdin: https://crowdin.com/
  5. Transifex: https://www.transifex.com/
  6. Phrase: https://phrase.com/

Top comments (0)