このページとあなたの好きなAIアシスタントを使ってドキュメントを要約します
バージョン履歴
- "Solid の useIntlayer API の使用法を直接プロパティアクセスに更新"v8.9.02026/5/4
- "initコマンドを追加"v7.5.92025/12/30
- "初期履歴"v7.3.42025/12/8
このページのコンテンツは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でReact Router v7(fs-routes)を翻訳する | 国際化(i18n)
このガイドでは、React Router v7プロジェクトにおいて、ファイルシステムベースのルーティング(@react-router/fs-routes)を使用して、ロケール対応ルーティング、TypeScriptサポート、最新の開発手法を活用しながら、Intlayerを使ったシームレスな国際化の統合方法を説明します。
クライアントサイドルーティングについては、IntlayerとReact Router v7ガイドを参照してください。
目次
代替手段ではなく Interlayer を使用する理由
「react-i18next」や「i18next」などの主要なソリューションと比較して、Intlayer は次のような統合された最適化を備えたソリューションです。
React Router を完全にカバー
Intlayer は、ロケール対応ルーティング、ロケール検出用のミドルウェア、およびスケーリング国際化 (i18n) に必要なすべての機能を提供することにより、React Router と完全に連携するように最適化されています。
バンドルサイズ
大量の JSON ファイルをページにロードするのではなく、必要なコンテンツのみをロードします。 Intlayer は、バンドルとページのサイズを最大 50% 削減するのに役立ちます。
保守性
アプリケーションのコンテンツのスコープを設定すると、大規模なアプリケーションの メンテナンスが容易になります。コンテンツ コードベース全体を確認するという精神的な負担を負うことなく、単一の機能フォルダーを複製または削除できます。さらに、Intlayer は完全に型指定されており、コンテンツの正確性を保証します。
AI エージェント
コンテンツを同じ場所に配置すると、大規模言語モデル (LLM) によって 必要なコンテキストが削減されます。 Intlayer には、翻訳の欠落をテストする CLI、LSP、MCP などのツール スイートも付属しています。および エージェント スキル により、AI エージェントの開発者エクスペリエンス (DX) がさらにスムーズになります。
オートメーション
AI プロバイダーの費用で、選択した LLM を使用して CI/CD パイプラインで自動化を変換します。 Intlayer は、コンテンツ抽出を自動化する コンパイラー と、バックグラウンドでの翻訳を支援する Web プラットフォーム も提供します。
パフォーマンス
大量の JSON ファイルをコンポーネントに接続すると、パフォーマンスと反応性の問題が発生する可能性があります。 Intlayer は、ビルド時のコンテンツの読み込みを最適化します。
非開発によるスケーリング
Intlayer は単なる i18n ソリューションではなく、自己ホスト型 ビジュアル エディター と 完全な CMS を提供します。 リアルタイムで多言語コンテンツを管理できるようになり、翻訳者、コピーライター、その他のチーム メンバーとのコラボレーションがシームレスになります。コンテンツはローカルおよび/またはリモートに保存できます。
ファイルシステムベースのルートを使用したReact Router v7アプリケーションでIntlayerを設定するためのステップバイステップガイド
See Application Template on GitHub.
依存パッケージのインストール
お好みのパッケージマネージャーを使って必要なパッケージをインストールします:
bashコードをコピーコードをクリップボードにコピー
npm install intlayer react-intlayernpm install vite-intlayer --save-devnpm install @react-router/fs-routes --save-devnpx intlayer initintlayer
intlayer
設定管理、翻訳、コンテンツ宣言、トランスパイル、およびCLIコマンドのための国際化ツールを提供するコアパッケージ。react-intlayer
IntlayerをReactアプリケーションと統合するパッケージです。Reactの国際化のためのコンテキストプロバイダーとフックを提供します。vite-intlayer IntlayerをViteバンドラーと統合するためのViteプラグイン、およびユーザーの優先ロケール検出、クッキー管理、URLリダイレクト処理のためのミドルウェアを含みます。
@react-router/fs-routes React Router v7のファイルシステムベースのルーティングを有効にするパッケージ。
プロジェクトの設定
アプリケーションの言語を設定するための設定ファイルを作成します:
intlayer.config.tsコードをコピーコードをクリップボードにコピー
import { type IntlayerConfig, Locales } from "intlayer"; const config: IntlayerConfig = { internationalization: { defaultLocale: Locales.ENGLISH, // デフォルトのロケールを英語に設定 locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], // 利用可能なロケールのリスト }, }; export default config;この設定ファイルを通じて、ローカライズされたURL、ミドルウェアのリダイレクション、クッキー名、コンテンツ宣言の場所と拡張子、コンソールでのIntlayerログの無効化などを設定できます。利用可能なパラメータの完全なリストについては、設定ドキュメントを参照してください。
Vite設定にIntlayerを統合する
設定にintlayerプラグインを追加します:
vite.config.tsコードをコピーコードをクリップボードにコピー
import { reactRouter } from "@react-router/dev/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";export default defineConfig({ plugins: [reactRouter(), intlayer()],});intlayer()Viteプラグインは、IntlayerをViteと統合するために使用されます。これにより、コンテンツ宣言ファイルのビルドが保証され、開発モードで監視されます。また、Viteアプリケーション内でIntlayerの環境変数を定義します。さらに、パフォーマンスを最適化するためのエイリアスも提供します。React Router v7のファイルシステムルートを設定する
flatRoutesを使用してファイルシステムベースのルートを使用するようにルーティング設定を行います:app/routes.tsコードをコピーコードをクリップボードにコピー
import type { RouteConfig } from "@react-router/dev/routes";import { flatRoutes } from "@react-router/fs-routes";import { configuration } from "intlayer";const routes: RouteConfig = flatRoutes({ // コンテンツ宣言ファイルをルートとして扱わないように無視する ignoredRouteFiles: configuration.content.fileExtensions.map( (fileExtension) => `**/*${fileExtension}` ),});export default routes;@react-router/fs-routesのflatRoutes関数は、routes/ディレクトリ内のファイル構造がアプリケーションのルートを決定するファイルシステムベースのルーティングを有効にします。ignoredRouteFilesオプションは、Intlayerコンテンツ宣言ファイル(.content.tsなど)がルートファイルとして扱われないようにします。ファイルシステム規則でルートファイルを作成する
ファイルシステムルーティングでは、ドット(
.)がパスセグメントを表し、括弧()がオプションセグメントを示すフラットな命名規則を使用します。app/routes/ディレクトリに次のファイルを作成します:ファイル構造
bashコードをコピーコードをクリップボードにコピー
app/├── root.tsx # ロケールルートのレイアウトラッパー└──routes/ ├── ($locale)._index.tsx # ホームページ (/, /es, など) ├── ($locale)._index.content.ts # ホームページのコンテンツ ├── ($locale).about.tsx # アバウトページ (/about, /es/about, など) └── ($locale).about.content.ts # アバウトページのコンテンツ命名規則:
($locale)- ロケールパラメータのオプションの動的セグメント_layout- 子ルートをラップするレイアウトルート_index- インデックスルート(親パスでレンダリングされる).(ドット) - パスセグメントを区切る(例:($locale).about→/:locale?/about)
レイアウトコンポーネント
app/root.tsxコードをコピーコードをクリップボードにコピー
import { getLocaleFromPath } from "intlayer";import { IntlayerProvider } from "react-intlayer";import { isRouteErrorResponse, Meta, Outlet, Scripts, ScrollRestoration, useLoaderData,} from "react-router";import type { Route } from "./+types/root";import "./app.css";// links and ErrorBoundary codeexport async function loader({ request }: Route.LoaderArgs) { const locale = getLocaleFromPath(request.url); return { locale };}export function Layout({ children,}: { children: React.ReactNode } & Route.ComponentProps) { const data = useLoaderData<typeof loader>(); const { locale } = data ?? {}; return ( <html lang={locale}> <head> <meta charSet="utf-8" /> <meta content="width=device-width, initial-scale=1" name="viewport" /> <Meta /> <Links /> </head> <body> <IntlayerProvider locale={locale}>{children}</IntlayerProvider> <ScrollRestoration /> <Scripts /> </body> </html> );}インデックスページ
app/routes/($locale)._index.tsxコードをコピーコードをクリップボードにコピー
import { getIntlayer, validatePrefix } from "intlayer";import { useIntlayer } from "react-intlayer";import { data } from "react-router";import { LocaleSwitcher } from "~/components/locale-switcher";import { Navbar } from "~/components/navbar";import type { Route } from "./+types/($locale)._index";export const loader = ({ params }: Route.LoaderArgs) => { const { locale } = params; const { isValid } = validatePrefix(locale); if (!isValid) { throw data("Locale not supported", { status: 404 }); }};export const meta: Route.MetaFunction = ({ params }) => { const content = getIntlayer("page", params.locale); return [ { title: content.title }, { content: content.description, name: "description" }, ];};export default function Page() { const { title, description, aboutLink } = useIntlayer("page"); return ( <div> <h1>{title}</h1> <p>{description}</p> <nav> <LocalizedLink to="/about">{aboutLink}</LocalizedLink> </nav> </div> );}アバウトページ
app/routes/($locale).about.tsxコードをコピーコードをクリップボードにコピー
import { getIntlayer, validatePrefix } from "intlayer";import { useIntlayer } from "react-intlayer";import { data } from "react-router";import { LocaleSwitcher } from "~/components/locale-switcher";import { Navbar } from "~/components/navbar";import type { Route } from "./+types/($locale).about";export const loader = ({ params }: Route.LoaderArgs) => { const { locale } = params; const { isValid } = validatePrefix(locale); if (!isValid) { throw data("Locale not supported", { status: 404 }); }};export const meta: Route.MetaFunction = ({ params }) => { const content = getIntlayer("about", params.locale); return [ { title: content.title }, { content: content.description, name: "description" }, ];};export default function AboutPage() { const { title, content, homeLink } = useIntlayer("about"); return ( <div> <h1>{title}</h1> <p>{content}</p> <nav> <LocalizedLink to="/">{homeLink}</LocalizedLink> </nav> </div> );}コンテンツを宣言する
翻訳を格納するためのコンテンツ宣言を作成および管理します。コンテンツファイルをルートファイルの横に配置します:
app/routes/($locale)._index.content.tsコードをコピーコードをクリップボードにコピー
import { t, type Dictionary } from "intlayer";const pageContent = { key: "page", content: { title: t({ en: "Welcome to React Router v7 + Intlayer", es: "Bienvenido a React Router v7 + Intlayer", fr: "Bienvenue sur React Router v7 + Intlayer", }), description: t({ en: "Build multilingual applications with ease using React Router v7 and Intlayer.", es: "Cree aplicaciones multilingües fácilmente usando React Router v7 y Intlayer.", fr: "Créez des applications multilingues facilement avec React Router v7 et Intlayer.", }), aboutLink: t({ en: "Learn About Us", es: "Aprender Sobre Nosotros", fr: "En savoir plus sur nous", }), },} satisfies Dictionary;export default pageContent;app/routes/($locale).about.content.tsコードをコピーコードをクリップボードにコピー
import { t, type Dictionary } from "intlayer";const aboutContent = { key: "about", content: { title: t({ en: "About Us", es: "Sobre Nosotros", fr: "À propos de nous", }), content: t({ en: "This is the about page content.", es: "Este es el contenido de la página de información.", fr: "Ceci est le contenu de la page à propos.", }), homeLink: t({ en: "Home", es: "Inicio", fr: "Accueil", }), },} satisfies Dictionary;export default aboutContent;コンテンツ宣言は、
contentDirディレクトリ(デフォルトは./app)に含まれている限り、アプリケーションのどこにでも定義できます。また、コンテンツ宣言ファイルの拡張子(デフォルトは.content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml})に一致する必要があります。詳細については、コンテンツ宣言ドキュメントを参照してください。
アプリケーションが既に存在する場合は、Intlayer コンパイラ と 抽出コマンド を組み合わせて、1 秒で何千ものコンポーネントを変換できます。
ロケール対応コンポーネントの作成
ロケール対応のナビゲーション用に
LocalizedLinkコンポーネントを作成します:app/components/localized-link.tsxコードをコピーコードをクリップボードにコピー
import type { FC } from "react";import { getLocalizedUrl, type LocalesValues } from "intlayer";import { useLocale } from "react-intlayer";import { Link, type LinkProps, type To } from "react-router";// 外部リンクかどうかを判定する関数const isExternalLink = (to: string) => /^(https?:)?\/\//.test(to);// 指定されたURLをロケールに応じてローカライズする関数export const locacalizeTo = (to: To, locale: LocalesValues): To => { if (typeof to === "string") { if (isExternalLink(to)) { return to; } return getLocalizedUrl(to, locale); } if (isExternalLink(to.pathname ?? "")) { return to; } return { ...to, pathname: getLocalizedUrl(to.pathname ?? "", locale), };};// ロケール対応のリンクコンポーネントexport const LocalizedLink: FC<LinkProps> = (props) => { const { locale } = useLocale(); return <Link {...props} to={locacalizeTo(props.to, locale)} />;};ローカライズされたルートにナビゲートしたい場合は、
useLocalizedNavigateフックを使用できます。app/hooks/useLocalizedNavigate.tsコードをコピーコードをクリップボードにコピー
import { useLocale } from "react-intlayer";import { type NavigateOptions, type To, useNavigate } from "react-router";import { locacalizeTo } from "~/components/localized-link";export const useLocalizedNavigate = () => { const navigate = useNavigate(); const { locale } = useLocale(); const localizedNavigate = (to: To, options?: NavigateOptions) => { const localedTo = locacalizeTo(to, locale); navigate(localedTo, options); }; return localizedNavigate;};ロケールスイッチャーコンポーネントを作成する
ユーザーが言語を変更できるコンポーネントを作成します:
app/components/locale-switcher.tsxコードをコピーコードをクリップボードにコピー
import type { FC } from "react";import { getHTMLTextDir, getLocaleName, getLocalizedUrl, getPathWithoutLocale, Locales,} from "intlayer";import { useIntlayer, useLocale } from "react-intlayer";import { Link, useLocation } from "react-router";export const LocaleSwitcher: FC = () => { const { localeSwitcherLabel } = useIntlayer("locale-switcher"); const { pathname } = useLocation(); const { availableLocales, locale } = useLocale(); const pathWithoutLocale = getPathWithoutLocale(pathname); return ( <ol> {availableLocales.map((localeItem) => ( <li key={localeItem}> <Link aria-current={localeItem === locale ? "page" : undefined} aria-label={`${localeSwitcherLabel.value} ${getLocaleName(localeItem)}`} reloadDocument // 新しいロケールを適用するためにページを再読み込み to={getLocalizedUrl(pathWithoutLocale, localeItem)} > <span> {/* ロケール - 例: FR */} {localeItem} </span> <span> {/* 自身のロケールでの言語名 - 例: Français */} {getLocaleName(localeItem, locale)} </span> <span dir={getHTMLTextDir(localeItem)} lang={localeItem}> {/* 現在のロケールでの言語名 - 例: 現在のロケールがLocales.SPANISHの場合のFrancés */} {getLocaleName(localeItem)} </span> <span dir="ltr" lang={Locales.ENGLISH}> {/* 英語での言語名 - 例: French */} {getLocaleName(localeItem, Locales.ENGLISH)} </span> </Link> </li> ))} </ol> );};useLocaleフックの詳細については、ドキュメントを参照してください。HTML属性の管理を追加(オプション)
HTMLのlang属性とdir属性を管理するフックを作成します:
app/hooks/useI18nHTMLAttributes.tsxコードをコピーコードをクリップボードにコピー
import { getHTMLTextDir } from "intlayer";import { useEffect } from "react";import { useLocale } from "react-intlayer";export const useI18nHTMLAttributes = () => { const { locale } = useLocale(); useEffect(() => { document.documentElement.lang = locale; document.documentElement.dir = getHTMLTextDir(locale); }, [locale]);};このフックは、ステップ5で示したレイアウトコンポーネント(
root.tsx)で既に使用されています。コンポーネントのコンテンツを抽出する
オプション既存のコードベースがある場合、数千のファイルを変換するのは時間がかかることがあります。
このプロセスを容易にするために、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
Configure TypeScript
Intlayer uses module augmentation to get benefits of TypeScript and make your codebase stronger.
Ensure your TypeScript configuration includes the autogenerated types:
コードをクリップボードにコピー
{ // ... your existing configurations include: [ // ... your existing includes ".intlayer/**/*.ts", // Include the auto-generated types ],}Git Configuration
It is recommended to ignore the files generated by Intlayer. This allows you to avoid committing them to your Git repository.
To do this, you can add the following instructions to your .gitignore file:
コードをクリップボードにコピー
# Intlayerによって生成されたファイルを無視する.intlayerVS Code Extension
To improve your development experience with Intlayer, you can install the official Intlayer VS Code Extension.
Install from the VS Code Marketplace
This extension provides:
- Autocompletion for translation keys.
- Real-time error detection for missing translations.
- Inline previews of translated content.
- Quick actions to easily create and update translations.
For more details on how to use the extension, refer to the Intlayer VS Code Extension documentation.
Go Further
To go further, you can implement the visual editor or externalize your content using the CMS.
Documentation References
- Intlayer Documentation
- React Router v7 Documentation
- React Router fs-routes Documentation
- useIntlayer hook
- useLocale hook
- Content Declaration
- Configuration
This comprehensive guide provides everything you need to integrate Intlayer with React Router v7 using file-system based routing for a fully internationalized application with locale-aware routing and TypeScript support.
ミドルウェアを追加する(オプション)
intlayerProxyを使用して、アプリケーションにサーバーサイドルーティングを追加することもできます。このプラグインは、URL に基づいて現在のロケールを自動的に検出し、適切なロケールクッキーを設定します。ロケールが指定されていない場合、プラグインはユーザーのブラウザの言語設定に基づいて最も適切なロケールを判断します。ロケールが検出されない場合は、デフォルトのロケールにリダイレクトします。intlayerProxyを本番環境で使用するには、vite-intlayerパッケージをdevDependenciesからdependenciesに切り替える必要があることに注意してください。vite.config.tsコードをコピーコードをクリップボードにコピー
import { reactRouter } from "@react-router/dev/vite";import { defineConfig } from "vite";import { intlayer, intlayerProxy } from "vite-intlayer";export default defineConfig({ plugins: [ intlayerProxy(), // should be placed first reactRouter(), intlayer(), ],});
TypeScriptの設定
Intlayerはモジュール拡張を使用して、TypeScriptの利点を活かし、コードベースをより強固にします。
TypeScriptの設定に自動生成された型が含まれていることを確認してください。
コードをクリップボードにコピー
{ // ... 既存の設定 include: [ // ... 既存のinclude ".intlayer/**/*.ts", // 自動生成された型を含める ],}Gitの設定
Intlayerによって生成されたファイルは無視することを推奨します。これにより、Gitリポジトリへのコミットを避けることができます。
これを行うには、.gitignoreファイルに以下の指示を追加してください。
コードをクリップボードにコピー
# Intlayerによって生成されたファイルを無視する.intlayerVS Code 拡張機能
Intlayerでの開発体験を向上させるために、公式の Intlayer VS Code 拡張機能 をインストールできます。
この拡張機能は以下を提供します:
- 翻訳キーの 自動補完。
- 翻訳が不足している場合の リアルタイムエラー検出。
- 翻訳内容の インラインプレビュー。
- 翻訳を簡単に作成・更新できる クイックアクション。
拡張機能の使い方の詳細は、Intlayer VS Code 拡張機能のドキュメントを参照してください。
さらに進む
さらに進めるために、ビジュアルエディターを実装するか、CMSを使用してコンテンツを外部化することができます。
ドキュメント参照
- Intlayer ドキュメント
- React Router v7 ドキュメント
- React Router fs-routes ドキュメント
- useIntlayer フック
- useLocale フック
- コンテンツ宣言
- 設定
この包括的なガイドは、ファイルシステムベースのルーティングを使用してIntlayerをReact Router v7と統合し、ロケール対応のルーティングとTypeScriptサポートを備えた完全に国際化されたアプリケーションを構築するために必要なすべてを提供します。