Internationalization with next-intl

Launch Express comes with built-in internationalization support using next-intl, making it easy to create multilingual applications. This guide will help you understand how to use and configure internationalization in your project.

Overview

Internationalization (i18n) allows your application to adapt to different languages and regions. With next-intl, Launch Express provides:

  • Simple translation management
  • Locale-based routing
  • Date, number, and time formatting
  • RTL (Right-to-Left) language support
  • SEO-friendly localized pages

Configuration

Locale Settings

The internationalization settings are configured in src/i18n/request.ts:

Translation Files

Translation messages are stored in JSON files in the locales directory, organized by locale:

locales/
    en.json
    fr.json
    es.json
    de.json

Each translation file follows this structure:

{
	"Index": {
		"title": "Welcome to Launch Express",
		"description": "The fastest way to launch your SaaS"
	},
	"Navigation": {
		"home": "Home",
		"dashboard": "Dashboard",
		"settings": "Settings"
	},
	"Auth": {
		"signIn": "Sign In",
		"signUp": "Sign Up",
		"forgotPassword": "Forgot Password?"
	}
}

Using Translations in Components

Client Components

For client components, use the useTranslations hook:

"use client";

import { useTranslations } from "next-intl";

export default function MyClientComponent() {
	const t = useTranslations("Navigation");

	return (
		<nav>
			<ul>
				<li>{t("home")}</li>
				<li>{t("dashboard")}</li>
				<li>{t("settings")}</li>
			</ul>
		</nav>
	);
}

Server Components

For server components, use the getTranslations function:

import { getTranslations } from "next-intl/server";

export default async function MyServerComponent() {
	const t = await getTranslations("Index");

	return (
		<div>
			<h1>{t("title")}</h1>
			<p>{t("description")}</p>
		</div>
	);
}

Formatting Dates, Numbers, and Times

next-intl provides utilities for formatting dates, numbers, and currencies according to the current locale:

import { useFormatter } from "next-intl";

export default function PriceDisplay() {
	const format = useFormatter();

	return (
		<div>
			<p>{format.number(1000, { style: "currency", currency: "USD" })}</p>
			<p>
				{format.dateTime(new Date(), {
					dateStyle: "full",
					timeStyle: "short",
				})}
			</p>
		</div>
	);
}

Handling Dynamic Content

For dynamic content with variables, use placeholders in your translations:

{
	"Welcome": {
		"greeting": "Hello, {name}!",
		"itemCount": "You have {count, plural, =0 {no items} one {# item} other {# items}}."
	}
}

Then in your component:

const t = useTranslations("Welcome");

return (
	<div>
		<p>{t("greeting", { name: user.name })}</p>
		<p>{t("itemCount", { count: items.length })}</p>
	</div>
);

SEO Considerations

Metadata for Different Locales

Create locale-specific metadata in your page components:

import { getTranslations } from "next-intl/server";

export async function generateMetadata({ params }) {
	const t = await getTranslations("Meta");

	return {
		title: t("title"),
		description: t("description"),
	};
}

Add alternate links for different locales in your layout:

import { locales } from "@/config/i18n";

export default function RootLayout({ children, params }) {
	const { locale } = params;

	return (
		<html lang={locale}>
			<head>
				{locales.map((loc) => (
					<link
						key={loc}
						rel="alternate"
						hrefLang={loc}
						href={`https://example.com/${loc === defaultLocale ? "" : loc}`}
					/>
				))}
			</head>
			<body>{children}</body>
		</html>
	);
}

Adding a New Language

To add a new language to your Launch Express project:

  1. Update the locales array in src/i18n/request.ts
  2. Create a new translation file in locales (e.g., ja.json for Japanese)
  3. Translate all the strings from the default locale file
  4. Restart your development server

Accelerating Translations with Languine.ai

When expanding your application to support multiple languages, manually translating all your content can be time-consuming. Languine.ai offers a powerful solution to streamline this process.

How Languine.ai Helps

Languine.ai is a specialized tool for translating locale files that:

  • Automatically translates your existing locale files to new languages
  • Preserves the JSON structure and keys of your original files
  • Maintains context-aware translations for more natural results
  • Supports a wide range of languages including French, German, Spanish, Chinese, Japanese, and many more

Using Languine.ai with Launch Express

Here’s how to use Languine.ai to quickly expand your language support:

  1. Start with a complete locale file (e.g., your English en.json)
  2. Upload your source locale file to Languine.ai
  3. Select the target languages you want to translate to
  4. Download the translated locale files
  5. Place the new files in your locales directory
  6. Update your locales array in the config file to include the new languages

This approach allows you to rapidly add new languages to your application without the need for manual translation of every string, saving significant time and effort while maintaining high-quality translations.

Best Practices

  • Use semantic keys instead of the actual text (e.g., welcome_message instead of Welcome to our site)
  • Group translations by feature or page
  • Keep translation files organized and consistent across languages
  • Use placeholders for dynamic content
  • Consider using a translation management system for larger projects

Troubleshooting

Missing Translations

If a translation is missing, next-intl will fall back to the key name. To debug missing translations, you can enable strict mode in your development environment:

// src/i18n.ts
export default function createIntlConfig(locale: string) {
	return {
		locale,
		messages: messages[locale],
		onError:
			process.env.NODE_ENV === "development"
				? (error) => {
						if (error.code === "MISSING_MESSAGE") {
							console.warn(`Missing translation: ${error.key}`);
						} else {
							console.error(error);
						}
				  }
				: undefined,
	};
}

Locale Detection

If you’re having issues with locale detection, check:

  1. The middleware configuration in middleware.ts
  2. The locale parameter in your page routes
  3. The Accept-Language header handling in your application

Resources