コンテンツにスキップ

Next.js で多言語に対応する

Next.js App Router Internationalization (i18n) – Internationalization (i18n) for Next.js

1
$ npm i next-intl
src/app/layout.tsx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import type { Metadata } from "next";
import { NextIntlClientProvider } from "next-intl";
import { getLocale } from "next-intl/server";
import "./globals.css";

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default async function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  const locale = await getLocale();

  return (
    <html lang={locale}>
      <body>
        <NextIntlClientProvider>{children}</NextIntlClientProvider>
      </body>
    </html>
  );
}
src/app/page.tsx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import { useTranslations } from "next-intl";
import Link from "next/link";

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

  return (
    <>
      <p>{t("hello")}</p>
    </>
  );
}
src/i18n/en.json
1
2
3
{
  "hello": "Hello"
}
src/i18n/ja.json
1
2
3
{
  "hello": "こんにちは"
}
src/i18n/request.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import { getRequestConfig } from "next-intl/server";

export default getRequestConfig(async () => {
  // Provide a static locale, fetch a user setting,
  // read from `cookies()`, `headers()`, etc.
  const locale = "en";

  return {
    locale,
    messages: (await import(`./${locale}.json`)).default,
  };
});
next.config.ts
1
2
3
4
5
6
7
8
9
import type { NextConfig } from "next";
import createNextIntlPlugin from "next-intl/plugin";

const nextConfig: NextConfig = {
  /* config options here */
};

const withNextIntl = createNextIntlPlugin();
export default withNextIntl(nextConfig);

非同期コンポーネントの場合

Internationalization of Server & Client Components – Internationalization (i18n) for Next.js

非同期コンポーネントの場合はuseTranslations()ではなくawait getTranslations()を使う。