このページとあなたの好きなAIアシスタントを使ってドキュメントを要約します
バージョン履歴
- "Solid の useIntlayer API の使用法を直接プロパティアクセスに更新"v8.9.02026/5/4
- "initコマンドを追加"v7.5.92025/12/30
- "`alternates` オブジェクトに `x-default` の記述を追加"v7.0.62025/11/1
- "履歴の初期化"v7.0.02025/6/29
このページのコンテンツはAIを使用して翻訳されました。
英語の元のコンテンツの最新バージョンを見るIf you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
Intlayerを使ってNext.js 16のウェブサイトを翻訳する | 国際化(i18n)
GitHubのアプリケーションテンプレートをご覧ください。
目次
代替手段ではなく Interlayer を使用する理由
「next-intl」や「i18next」などの主要なソリューションと比較して、Intlayer は次のような統合された最適化を備えたソリューションです。
Next.js を完全にカバー
Intlayer は、効率的なレンダリングのために サーバー コンポーネント と連携するように最適化されており、Turbopack と完全に互換性があります。静的レンダリングをブロックせず、ミドルウェアとスケーリング国際化 (i18n) に必要なすべての機能を提供します。
Intlayer は Next.js 12、13、14、15、および 16 と互換性があります。 Next.js Pages Router を使用している場合は、この ガイド を参照してください。 ロケール ルーティングは、SEO、バンドル サイズ、パフォーマンスに役立ちます。必要ない場合は、このガイドを参照してください。 App Router を使用した Next.js 12、13、14、および 15 については、この ガイド を参照してください。
バンドルサイズ
大量の JSON ファイルをページにロードするのではなく、必要なコンテンツのみをロードします。 Intlayer は、バンドルとページのサイズを最大 50% 削減するのに役立ちます。
保守性
アプリケーションのコンテンツのスコープを設定すると、大規模なアプリケーションの メンテナンスが容易になります。コンテンツ コードベース全体を確認するという精神的な負担を負うことなく、単一の機能フォルダーを複製または削除できます。さらに、Intlayer は完全に型指定されており、コンテンツの正確性を保証します。
AI エージェント
コンテンツを同じ場所に配置すると、大規模言語モデル (LLM) によって 必要なコンテキストが削減されます。 Intlayer には、翻訳の欠落をテストする CLI、LSP、MCP などのツール スイートも付属しています。および エージェント スキル により、AI エージェントの開発者エクスペリエンス (DX) がさらにスムーズになります。
オートメーション
AI プロバイダーの費用で、選択した LLM を使用して CI/CD パイプラインで自動化を変換します。 Intlayer は、コンテンツ抽出を自動化する コンパイラー と、バックグラウンドでの翻訳を支援する Web プラットフォーム も提供します。
パフォーマンス
大量の JSON ファイルをコンポーネントに接続すると、パフォーマンスと反応性の問題が発生する可能性があります。 Intlayer は、ビルド時のコンテンツの読み込みを最適化します。
非開発によるスケーリング
Intlayer は単なる i18n ソリューションではなく、自己ホスト型 ビジュアル エディター と 完全な CMS を提供します。 リアルタイムで多言語コンテンツを管理できるようになり、翻訳者、コピーライター、その他のチーム メンバーとのコラボレーションがシームレスになります。コンテンツはローカルおよび/またはリモートに保存できます。
Next.jsアプリケーションでIntlayerをセットアップするステップバイステップガイド
依存関係のインストール
npmを使って必要なパッケージをインストールします:
bashコードをコピーコードをクリップボードにコピー
npm install intlayer next-intlayernpx intlayer initプロジェクトの設定
最終的な構成は以下のようになります:
bashコードをコピーコードをクリップボードにコピー
.├── src│ ├── app│ │ ├── [locale]│ │ │ ├── layout.tsx # Intlayerプロバイダー用のロケールレイアウト│ │ │ ├── page.content.ts│ │ │ └── page.tsx│ │ └── layout.tsx # スタイルとグローバルプロバイダー用のルートレイアウト│ ├── components│ │ ├── client-component-example.content.ts│ │ ├── ClientComponentExample.tsx│ │ ├── LocaleSwitcher│ │ │ ├── localeSwitcher.content.ts│ │ │ └── LocaleSwitcher.tsx│ │ ├── server-component-example.content.ts│ │ └── ServerComponentExample.tsx│ └── proxy.ts├── intlayer.config.ts├── next.config.ts├── package.json└── tsconfig.jsonロケールルーティングが不要な場合、intlayerはシンプルなプロバイダー/フックとして使用できます。詳細はこのガイドを参照してください。
アプリケーションの言語を設定するための設定ファイルを作成します:
intlayer.config.tsコードをコピーコードをクリップボードにコピー
import { Locales, type IntlayerConfig } from "intlayer"; const config: IntlayerConfig = { internationalization: { locales: [ Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH, // 他のロケール ], defaultLocale: Locales.ENGLISH, }, }; export default config;この設定ファイルを通じて、ローカライズされたURLの設定、プロキシリダイレクト、クッキー名、コンテンツ宣言の場所と拡張子の指定、コンソールでのIntlayerログの無効化などが行えます。利用可能なパラメータの完全なリストについては、設定ドキュメントを参照してください。
Next.jsの設定にIntlayerを統合する
Next.jsのセットアップをIntlayerを使うように設定します:
next.config.tsコードをコピーコードをクリップボードにコピー
import type { NextConfig } from "next"; import { withIntlayer } from "next-intlayer/server"; const nextConfig: NextConfig = { /* ここに設定オプションを記述 */ }; export default withIntlayer(nextConfig);withIntlayer()は Next.js プラグインで、Intlayer を Next.js と統合するために使用されます。これにより、コンテンツ宣言ファイルのビルドが保証され、開発モードでそれらを監視します。また、Webpack や Turbopack 環境内で Intlayer の環境変数を定義します。さらに、パフォーマンス最適化のためのエイリアスを提供し、サーバーコンポーネントとの互換性を確保します。withIntlayer()関数は Promise 関数です。ビルド開始前に Intlayer の辞書を準備することができます。他のプラグインと一緒に使用したい場合は、await で待機できます。例:tsコードをコピーコードをクリップボードにコピー
const nextConfig = await withIntlayer(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;同期的に使用したい場合は、
withIntlayerSync()関数を使用できます。例:tsコードをコピーコードをクリップボードにコピー
const nextConfig = withIntlayerSync(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;Intlayer は、コマンドラインフラグ
--webpack、--turbo、または--turbopack、および現在の Next.js バージョン に基づいて、プロジェクトが webpack または Turbopack を使用しているかどうかを自動的に検出します。next>=16以降、Rspack を使用している場合は、Turbopack を無効にして webpack 設定を使用するように Intlayer に明示的に強制する必要があります。tsコードをコピーコードをクリップボードにコピー
withRspack(withIntlayer(nextConfig, { enableTurbopack: false }));動的ロケールルートの定義
RootLayoutの内容をすべて削除し、以下のコードに置き換えます:src/app/layout.tsxコードをコピーコードをクリップボードにコピー
import type { PropsWithChildren, FC } from "react"; import "./globals.css"; const RootLayout: FC<PropsWithChildren> = ({ children }) => ( // `next-themes`、`react-query`、`framer-motion` などの他のプロバイダーで子要素をラップすることも可能です。 <>{children}</> ); export default RootLayout;RootLayoutコンポーネントを空のままにしておくことで、<html>タグにlangおよびdir属性を設定できます。動的ルーティングを実装するには、
[locale]ディレクトリに新しいレイアウトを追加してロケールのパスを指定します:src/app/[locale]/layout.tsxコードをコピーコードをクリップボードにコピー
import { type NextLayoutIntlayer, IntlayerClientProvider } from "next-intlayer"; import { Inter } from "next/font/google"; import { getHTMLTextDir } from "intlayer"; const inter = Inter({ subsets: ["latin"] }); const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => { const { locale } = await params; return ( <html lang={locale} dir={getHTMLTextDir(locale)}> <body className={inter.className}> <IntlayerClientProvider locale={locale}> {children} </IntlayerClientProvider> </body> </html> ); }; export default LocaleLayout;[locale]パスセグメントはロケールを定義するために使用されます。例:/en-US/aboutはen-USを指し、/fr/aboutはfrを指します。この段階で、
Error: Missing <html> and <body> tags in the root layout.というエラーが発生します。これは予期されたもので、/app/page.tsxファイルはもはや使用されておらず、削除して問題ありません。代わりに、[locale]パスセグメントが/app/[locale]/page.tsxページを有効にします。その結果、ブラウザでは/en、/fr、/esのようなパスでページにアクセスできるようになります。デフォルトのロケールをルートページとして設定するには、ステップ7のproxy設定を参照してください。次に、アプリケーションのレイアウト内で
generateStaticParams関数を実装します。src/app/[locale]/layout.tsxコードをコピーコードをクリップボードにコピー
export { generateStaticParams } from "next-intlayer"; // 挿入する行 const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => { /*... 残りのコード */ }; export default LocaleLayout;generateStaticParamsは、アプリケーションがすべてのロケールに対して必要なページを事前にビルドすることを保証し、実行時の計算を減らしユーザー体験を向上させます。詳細は Next.js の generateStaticParams に関するドキュメント を参照してください。Intlayer は
export const dynamic = 'force-static';と連携して、すべてのロケールのページが事前にビルドされることを保証します。コンテンツの宣言
翻訳を格納するためのコンテンツ宣言を作成・管理します:
src/app/[locale]/page.content.tsコードをコピーコードをクリップボードにコピー
import { t, type Dictionary } from "intlayer"; const pageContent = { key: "page", content: { getStarted: { main: t({ en: "Get started by editing", fr: "Commencez par éditer", es: "Comience por editar", }), pageLink: "src/app/page.tsx", }, }, } satisfies Dictionary; export default pageContent;コンテンツ宣言は、
contentDirディレクトリ(デフォルトは./src)に含まれている限り、アプリケーションのどこにでも定義できます。また、コンテンツ宣言ファイルの拡張子は(デフォルトで.content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml})に一致する必要があります。詳細については、コンテンツ宣言のドキュメントを参照してください。
コード内でコンテンツを利用する
アプリケーション全体でコンテンツ辞書にアクセスします:
src/app/[locale]/page.tsxコードをコピーコードをクリップボードにコピー
import type { FC } from "react"; import { ClientComponentExample } from "@components/ClientComponentExample"; import { ServerComponentExample } from "@components/ServerComponentExample"; import { type NextPageIntlayer } from "next-intlayer"; import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server"; const PageContent: FC = () => { const content = useIntlayer("page"); return ( <> <p>{content.getStarted.main}</p> <code>{content.getStarted.pageLink}</code> </> ); }; const Page: NextPageIntlayer = async ({ params }) => { const { locale } = await params; return ( <IntlayerServerProvider locale={locale}> <PageContent /> <ServerComponentExample /> <ClientComponentExample /> </IntlayerServerProvider> ); }; export default Page;IntlayerClientProviderはクライアントサイドのコンポーネントにロケールを提供するために使用されます。レイアウトを含む任意の親コンポーネントに配置できます。ただし、Next.jsはページ間でレイアウトコードを共有するため、レイアウトに配置することが推奨されます。レイアウトでIntlayerClientProviderを使用することで、各ページごとに再初期化する必要がなくなり、パフォーマンスが向上し、アプリケーション全体で一貫したローカリゼーションコンテキストを維持できます。IntlayerServerProviderはサーバー側の子コンポーネントにロケールを提供するために使用されます。レイアウトには設定できません。レイアウトとページは共通のサーバーコンテキストを共有できません。なぜなら、サーバーコンテキストシステムはリクエストごとのデータストア(Reactのcache メカニズム)に基づいており、アプリケーションの異なるセグメントごとに「コンテキスト」が再作成されるためです。プロバイダーを共有レイアウトに配置すると、この分離が破られ、サーバーコンポーネントに正しくサーバーコンテキストの値が伝播されなくなります。
src/components/ClientComponentExample.tsxコードをコピーコードをクリップボードにコピー
"use client"; import type { FC } from "react"; import { useIntlayer } from "next-intlayer"; export const ClientComponentExample: FC = () => { const content = useIntlayer("client-component-example"); // 関連するコンテンツ宣言を作成 return ( <div> <h2>{content.title}</h2> <p>{content.content}</p> </div> ); };src/components/ServerComponentExample.tsxコードをコピーコードをクリップボードにコピー
import type { FC } from "react"; import { useIntlayer } from "next-intlayer/server"; export const ServerComponentExample: FC = () => { const content = useIntlayer("server-component-example"); // 関連するコンテンツ宣言を作成 return ( <div> <h2>{content.title}</h2> <p>{content.content}</p> </div> ); };コンテンツを
alt、title、href、aria-labelなどのstring属性で使用したい場合は、関数の値を使用できます。例えば:htmlコードをコピーコードをクリップボードにコピー
<img src="{content.image.src.value}" alt="{content.image.value}" /><img src="{content.image.src.toString()}" alt="{content.image.toString()}" /><img src="{String(content.image.src)}" alt="{String(content.image)}" />useIntlayerフックの詳細については、ドキュメントを参照してください。アプリケーションが既に存在する場合は、Intlayer コンパイラ と 抽出コマンド を組み合わせて、1 秒で何千ものコンポーネントを変換できます。
ロケール検出のためのプロキシ設定
ユーザーの優先ロケールを検出するためのプロキシを設定します:
src/proxy.tsコードをコピーコードをクリップボードにコピー
export { intlayerProxy as proxy } from "next-intlayer/proxy"; export const config = { matcher: "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)", };intlayerProxyはユーザーの優先ロケールを検出し、設定で指定された適切なURLにリダイレクトするために使用されます。さらに、ユーザーの優先ロケールをクッキーに保存することも可能にします。複数のプロキシを連結する必要がある場合(例えば、認証付きの
intlayerProxyやカスタムプロキシと組み合わせる場合)、Intlayer はmultipleProxiesというヘルパーを提供しています。tsコードをコピーコードをクリップボードにコピー
import { multipleProxies, intlayerProxy } from "next-intlayer/proxy";import { customProxy } from "@utils/customProxy";export const proxy = multipleProxies([intlayerProxy, customProxy]);メタデータの国際化
ページのタイトルなどのメタデータを国際化したい場合は、Next.jsが提供する
generateMetadata関数を使用できます。その中で、getIntlayer関数からコンテンツを取得してメタデータを翻訳できます。src/app/[locale]/metadata.content.tsコードをコピーコードをクリップボードにコピー
import { type Dictionary, t } from "intlayer"; import { Metadata } from "next"; const metadataContent = { key: "page-metadata", content: { title: t({ en: "Create Next App", fr: "Créer une application Next.js", es: "Crear una aplicación Next.js", }), description: t({ en: "Generated by create next app", fr: "Généré par create next app", es: "Generado por create next app", }), }, } satisfies Dictionary<Metadata>; export default metadataContent;src/app/[locale]/layout.tsx or src/app/[locale]/page.tsxコードをコピーコードをクリップボードにコピー
import { getIntlayer, getMultilingualUrls } from "intlayer"; import type { Metadata } from "next"; import type { LocalPromiseParams } from "next-intlayer"; export const generateMetadata = async ({ params, }: LocalPromiseParams): Promise<Metadata> => { const { locale } = await params; const metadata = getIntlayer("page-metadata", locale); /** * 各ロケールのすべてのURLを含むオブジェクトを生成します。 * * 例: * ```ts * getMultilingualUrls('/about'); * * // 戻り値 * // { * // en: '/about', * // fr: '/fr/about', * // es: '/es/about', * // } * ``` */ const multilingualUrls = getMultilingualUrls("/"); const localizedUrl = multilingualUrls[locale as keyof typeof multilingualUrls]; return { ...metadata, alternates: { canonical: localizedUrl, languages: { ...multilingualUrls, "x-default": "/" }, }, openGraph: { url: localizedUrl, }, }; }; // ... 残りのコードnext-intlayerからインポートされたgetIntlayer関数は、コンテンツをIntlayerNodeでラップして返し、ビジュアルエディタとの統合を可能にします。対照的に、intlayerからインポートされたgetIntlayer関数は、追加のプロパティなしで直接コンテンツを返します。代わりに、
getTranslation関数を使用してメタデータを宣言することもできます。ただし、メタデータの翻訳を自動化し、コンテンツを外部化するためには、コンテンツ宣言ファイルを使用することが推奨されます。src/app/[locale]/layout.tsx or src/app/[locale]/page.tsxコードをコピーコードをクリップボードにコピー
import { type IConfigLocales, getTranslation, getMultilingualUrls, } from "intlayer"; import type { Metadata } from "next"; import type { LocalPromiseParams } from "next-intlayer"; export const generateMetadata = async ({ params, }: LocalPromiseParams): Promise<Metadata> => { const { locale } = await params; const t = <T>(content: IConfigLocales<T>) => getTranslation(content, locale); return { title: t<string>({ en: "My title", fr: "Mon titre", es: "Mi título", }), description: t({ en: "My description", fr: "Ma description", es: "Mi descripción", }), }; }; // ... 残りのコードメタデータの最適化について詳しくは、公式Next.jsドキュメントをご覧ください。
sitemap.xml と robots.txt の多言語対応
sitemap.xmlとrobots.txtを多言語対応にするには、Intlayer が提供するgetMultilingualUrls関数を使用できます。この関数を使うことで、サイトマップ用の多言語 URL を生成できます。src/app/sitemap.tsコードをコピーコードをクリップボードにコピー
import { getMultilingualUrls } from "intlayer"; import type { MetadataRoute } from "next"; const sitemap = (): MetadataRoute.Sitemap => [ { url: "https://example.com", alternates: { languages: { ...getMultilingualUrls("https://example.com"), "x-default": "https://example.com", }, }, }, { url: "https://example.com/login", alternates: { languages: { ...getMultilingualUrls("https://example.com/login"), "x-default": "https://example.com/login", }, }, }, { url: "https://example.com/register", alternates: { languages: { ...getMultilingualUrls("https://example.com/register"), "x-default": "https://example.com/register", }, }, }, ]; export default sitemap;src/app/robots.tsコードをコピーコードをクリップボードにコピー
import type { MetadataRoute } from "next"; import { getMultilingualUrls } from "intlayer"; const getAllMultilingualUrls = (urls: string[]) => urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]); const robots = (): MetadataRoute.Robots => ({ rules: { userAgent: "*", allow: ["/"], disallow: getAllMultilingualUrls(["/login", "/register"]), }, host: "https://example.com", sitemap: `https://example.com/sitemap.xml`, }); export default robots;サイトマップの最適化については、公式の Next.js ドキュメントをご覧ください。robots.txt の最適化については、公式の Next.js ドキュメントをご覧ください。
コンテンツの言語を変更する
Next.js でコンテンツの言語を変更するには、推奨される方法として
Linkコンポーネントを使用してユーザーを適切なローカライズされたページにリダイレクトする方法があります。Linkコンポーネントはページのプリフェッチを可能にし、完全なページリロードを回避するのに役立ちます。src/components/LocaleSwitcher.tsxコードをコピーコードをクリップボードにコピー
"use client"; import type { FC } from "react"; import { Locales, getHTMLTextDir, getLocaleName, getLocalizedUrl, } from "intlayer"; import { useLocale } from "next-intlayer"; import Link from "next/link"; export const LocaleSwitcher: FC = () => { const { locale, pathWithoutLocale, availableLocales, setLocale } = useLocale(); return ( <div> <button popoverTarget="localePopover">{getLocaleName(locale)}</button> <div id="localePopover" popover="auto"> {availableLocales.map((localeItem) => ( <Link href={getLocalizedUrl(pathWithoutLocale, localeItem)} key={localeItem} aria-current={locale === localeItem ? "page" : undefined} onClick={() => setLocale(localeItem)} replace // 「戻る」ブラウザボタンが前のページにリダイレクトすることを保証します > <span> {/* ロケール - 例: FR */} {localeItem} </span> <span> {/* 自身のロケールでの言語名 - 例: Français */} {getLocaleName(localeItem, locale)} </span> <span dir={getHTMLTextDir(localeItem)} lang={localeItem}> {/* 現在のロケールでの言語名 - 例: Francés(現在のロケールが Locales.SPANISH の場合) */} {getLocaleName(localeItem)} </span> <span dir="ltr" lang={Locales.ENGLISH}> {/* 英語での言語名 - 例: French */} {getLocaleName(localeItem, Locales.ENGLISH)} </span> </Link> ))} </div> </div> ); };代替方法として、
useLocaleフックで提供されるsetLocale関数を使用することもできます。この関数はページのプリフェッチを許可しません。詳細はuseLocaleフックのドキュメント を参照してください。また、
onLocaleChangeオプションに関数を設定して、ロケールが変更されたときにカスタム関数をトリガーすることも可能です。src/components/LocaleSwitcher.tsxコードをコピーコードをクリップボードにコピー
"use client";import { useRouter } from "next/navigation";import { useLocale } from "next-intlayer";import { getLocalizedUrl } from "intlayer";// ... 残りのコードconst router = useRouter();const { setLocale } = useLocale({ onLocaleChange: (locale) => { router.push(getLocalizedUrl(pathWithoutLocale, locale)); },});return ( <button onClick={() => setLocale(Locales.FRENCH)}>フランス語に変更</button>);ドキュメント参照:
コンポーネントのコンテンツを抽出する
オプション既存のコードベースがある場合、数千のファイルを変換するのは時間がかかることがあります。
このプロセスを容易にするために、Intlayerは、コンポーネントを変換しコンテンツを抽出するための コンパイラ / エクストラクタ を提案しています。
セットアップするには、
intlayer.config.tsファイルにcompilerセクションを追加します。intlayer.config.tsコードをコピーコードをクリップボードにコピー
import { type IntlayerConfig } from "intlayer"; const config: IntlayerConfig = { // ... 他の構成 compiler: { /** * コンパイラを有効にするかどうかを指定します。 */ enabled: true, /** * 出力ファイルのパスを定義します。 */ output: ({ fileName, extension }) => `./${fileName}${extension}`, /** * 変換後にコンポーネントを保存するかどうかを指定します。これにより、コンパイラを一度だけ実行してアプリを変換し、その後削除することができます。 */ saveComponents: false, /** * 辞書キーの接頭辞 */ dictionaryKeyPrefix: "", }, }; export default config;コンポーネントを変換してコンテンツを抽出するためにエクストラクタを実行します
bashコードをコピーコードをクリップボードにコピー
npx intlayer extractローカライズされたリンクコンポーネントの作成
アプリケーションのナビゲーションが現在のロケールを尊重するようにするために、カスタムの
Linkコンポーネントを作成できます。このコンポーネントは内部のURLに自動的に現在の言語をプレフィックスとして付加します。例えば、フランス語ユーザーが「About」ページへのリンクをクリックすると、/aboutではなく/fr/aboutにリダイレクトされます。この動作は以下の理由で有用です:
- SEOとユーザー体験:ローカライズされたURLは検索エンジンが言語別のページを正しくインデックスし、ユーザーに好みの言語でコンテンツを提供するのに役立ちます。
- 一貫性:アプリケーション全体でローカライズされたリンクを使用することで、ナビゲーションが現在のロケール内に留まり、予期しない言語切り替えを防ぎます。
- 保守性:URLの管理を単一のコンポーネントに集約することで、コードベースの保守や拡張が容易になります。
以下は、TypeScript によるローカライズされた
Linkコンポーネントの実装です:src/components/Link.tsxコードをコピーコードをクリップボードにコピー
"use client"; import { getLocalizedUrl } from "intlayer"; import NextLink, { type LinkProps as NextLinkProps } from "next/link"; import { useLocale } from "next-intlayer"; import type { PropsWithChildren, FC } from "react"; /** * 指定された URL が外部かどうかを確認するユーティリティ関数。 * URL が http:// または https:// で始まる場合、外部とみなされます。 */ export const checkIsExternalLink = (href?: string): boolean => /^https?:\/\//.test(href ?? ""); /** * 現在のロケールに基づいて href 属性を適応させるカスタム Link コンポーネント。 * 内部リンクの場合、`getLocalizedUrl` を使用して URL にロケールを付加します (例: /fr/about)。 * これにより、ナビゲーションが同じロケールコンテキスト内に留まることが保証されます。 */ export const Link: FC<PropsWithChildren<NextLinkProps>> = ({ href, children, ...props }) => { const { locale } = useLocale(); const isExternalLink = checkIsExternalLink(href.toString()); // リンクが内部であり、有効な href が提供されている場合、ローカライズされた URL を取得します。 const hrefI18n: NextLinkProps["href"] = href && !isExternalLink ? getLocalizedUrl(href.toString(), locale) : href; return ( <NextLink href={hrefI18n} {...props}> {children} </NextLink> ); };仕組み
外部リンクの検出:
ユーティリティ関数checkIsExternalLinkは、URL が外部かどうかを判断します。外部リンクはローカライズの必要がないため、そのまま保持されます。現在のロケールの取得:
useLocaleフックは、現在のロケール(例: フランス語ならfr)を提供します。URL のローカライズ:
内部リンク(外部以外)の場合、getLocalizedUrlを使用して、自動的に現在のロケールを URL の先頭に付加します。つまり、ユーザーがフランス語の設定であれば、/aboutを渡すと/fr/aboutに変換されます。リンクの返却:
コンポーネントはローカライズされた URL を持つ<a>要素を返し、ナビゲーションがロケールと一致するようにします。
この
Linkコンポーネントをアプリケーション全体に統合することで、一貫性のある言語対応のユーザー体験を維持しつつ、SEO やユーザビリティの向上というメリットも得られます。