C.W.K.
Stream
Lesson 08 of 09 · published

Internationalization

~20 min · i18n, next-intl, locale

Level 0Curious
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

Two routing strategies

StrategyURL pattern
Sub-path/[locale]/page/en/about, /ko/about
Domain-per-localeen.example.com, ko.example.com

Sub-path is simpler and SEO-friendly out of the box. Domain-per-locale is for separate marketing teams or geo-isolated infrastructure.

next-intl is the well-paved path

It handles message catalogs, locale negotiation, formatting (dates/numbers), and works in both Server and Client Components.

Code

Locale layout under [locale]·tsx
// app/[locale]/layout.tsx
import { NextIntlClientProvider } from 'next-intl';
import { getMessages } from 'next-intl/server';

export default async function LocaleLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: Promise<{ locale: string }>;
}) {
  const { locale } = await params;
  const messages = await getMessages();

  return (
    <html lang={locale}>
      <body>
        <NextIntlClientProvider messages={messages}>
          {children}
        </NextIntlClientProvider>
      </body>
    </html>
  );
}
Translations in components·tsx
import { useTranslations } from 'next-intl';

export default function HomePage() {
  const t = useTranslations('Home');
  return (
    <>
      <h1>{t('title')}</h1>
      <p>{t('description')}</p>
    </>
  );
}

External links

Exercise

Add en and ko locales to a small page using next-intl. Confirm the URL switches and a third-party translation key resolves correctly in both locales.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.