Getting Started Internationalizing (i18n) with Intlayer and React Create App
What is Intlayer?
Intlayerは、モダンなウェブアプリケーションにおける多言語サポートを簡素化するために設計された革新的なオープンソースの国際化(i18n)ライブラリです。
Intlayerを使用することで:
- コンポーネントレベルで宣言的な辞書を使用して翻訳を簡単に管理できます。
- メタデータ、ルート、コンテンツを動的にローカライズできます。
- TypeScriptのサポートを保証し、自動生成される型により、オートコンプリートとエラー検出を改善できます。
- 動的ロケール検出と切り替えのような高度な機能を利用できます。
Step-by-Step Guide to Set Up Intlayer in a React Application
Step 1: Install Dependencies
必要なパッケージをnpmを使用してインストールします:
1npm install intlayer react-intlayer
1yarn add intlayer react-intlayer
1pnpm add intlayer react-intlayer
Step 2: Configuration of your project
アプリケーションの言語を設定するための設定ファイルを作成します:
1// intlayer.config.ts
2
3import { Locales, type IntlayerConfig } from "intlayer";
4
5const config: IntlayerConfig = {
6 internationalization: {
7 locales: [
8 Locales.ENGLISH,
9 Locales.FRENCH,
10 Locales.SPANISH,
11 // 他のロケールを追加
12 ],
13 defaultLocale: Locales.ENGLISH,
14 },
15};
16
17export default config;
すべての利用可能なパラメータについては、こちらの設定ドキュメントを参照してください。
Step 3: Integrate Intlayer in Your CRA Configuration
スクリプトを変更してreact-intlayerを使用します。
1 "scripts": {
2 "build": "react-intlayer build",
3 "start": "react-intlayer start",
4 "transpile": "intlayer build"
5 },
注意:react-intlayerのスクリプトはcracoに基づいています。独自の設定をintlayer cracoプラグインに基づいて実装することもできます。こちらの例を参照してください。
Step 4: Declare Your Content
コンテンツ辞書を作成・管理します:
1// src/app.content.tsx
2import { t, type DeclarationContent } from "intlayer";
3import { type ReactNode } from "react";
4
5const appContent = {
6 key: "app",
7 content: {
8 getStarted: t<ReactNode>({
9 en: (
10 <>
11 Edit <code>src/App.tsx</code> and save to reload
12 </>
13 ),
14 fr: (
15 <>
16 Éditez <code>src/App.tsx</code> et enregistrez pour recharger
17 </>
18 ),
19 es: (
20 <>
21 Edita <code>src/App.tsx</code> y guarda para recargar
22 </>
23 ),
24 }),
25 reactLink: {
26 href: "https://reactjs.org",
27 content: t({
28 en: "Learn React",
29 fr: "Apprendre React",
30 es: "Aprender React",
31 }),
32 },
33 },
34} satisfies DeclarationContent;
35
36export default appContent;
Intlayerの宣言ファイルの宣言方法はこちらを参照してください。
Step 5: Utilize Intlayer in Your Code
アプリケーション全体でコンテンツ辞書にアクセスします:
1import logo from "./logo.svg";
2import "./App.css";
3import { IntlayerProvider, useIntlayer } from "react-intlayer";
4import { LocaleSwitcher } from "./components/LangSwitcherDropDown";
5
6function AppContent() {
7 const content = useIntlayer("app");
8
9 return (
10 <header className="App-header">
11 <img src={logo} className="App-logo" alt="logo" />
12
13 {content.getStarted}
14 <a
15 className="App-link"
16 href={content.reactLink.href.value}
17 target="_blank"
18 rel="noopener noreferrer"
19 >
20 {content.reactLink.content}
21 </a>
22 </header>
23 );
24}
25
26function App() {
27 return (
28 <IntlayerProvider>
29 <div className="App">
30 {/* useIntlayerフックを正しく使用するには、子コンポーネントでデータにアクセスする必要があります */}
31 <AppContent />
32 </div>
33 <div className="absolute bottom-5 right-5 z-50">
34 <LocaleSwitcher />
35 </div>
36 </IntlayerProvider>
37 );
38}
39
40export default App;
Note: alt、title、href、aria-labelなどのstring属性でコンテンツを使用したい場合は、関数の値を呼び出す必要があります。例えば:
tsx1<img src={content.image.src.value} alt={content.image.value} />
(Optional) Step 6: Change the language of your content
コンテンツの言語を変更するには、useLocaleフックによって提供されるsetLocale関数を使用します。この関数を使用すると、アプリケーションのロケールを設定し、それに応じてコンテンツを更新できます。
1import { Locales } from "intlayer";
2import { useLocale } from "react-intlayer";
3
4const LocaleSwitcher = () => {
5 const { setLocale } = useLocale();
6
7 return (
8 <button onClick={() => setLocale(Locales.Japanese)}>
9 Change Language to 日本語
10 </button>
11 );
12};
(Optional) Step 7: Add localized Routing to your application
このステップの目的は、各言語のユニークなルートを作成することです。これはSEOとSEOフレンドリーなURLに役立ちます。 例:
1// /dashboard
2// /ja/dashboard
3// /fr/dashboard
デフォルトでは、ルートはデフォルトロケールのプレフィックスが付いていません。デフォルトロケールにプレフィックスを付けたい場合は、設定のmiddleware.prefixDefaultオプションをtrueに設定できます。詳細については、設定ドキュメントをご覧ください。
アプリケーションにローカライズされたルーティングを追加するには、アプリケーションのルートをラップし、ロケールに基づいたルーティングを処理するLocaleRouterコンポーネントを作成できます。以下はReact Routerを使用した例です:
1// 必要な依存関係と関数をインポート
2import { Locales, getConfiguration, getPathWithoutLocale } from "intlayer"; // 'intlayer'からのユーティリティ関数と型
3import { FC, PropsWithChildren } from "react"; // 関数コンポーネントとプロップのためのReact型
4import { IntlayerProvider } from "react-intlayer"; // 国際化コンテキスト用のプロバイダー
5import {
6 BrowserRouter,
7 Routes,
8 Route,
9 useParams,
10 Navigate,
11 useLocation,
12} from "react-router-dom"; // ナビゲーション管理のためのルーターコンポーネント
13
14// Intlayerから設定を分解
15const { internationalization, middleware } = getConfiguration();
16const { locales, defaultLocale } = internationalization;
17
18/**
19 * ローカライズを処理し、適切なロケールコンテキストで子要素をラップするコンポーネント。
20 * URLベースのロケール検出と検証を管理します。
21 */
22const AppLocalized: FC<PropsWithChildren> = ({ children }) => {
23 const path = useLocation().pathname; // 現在のURLパスを取得
24 const { locale } = useParams<{ locale: Locales }>(); // URLからロケールパラメータを抽出
25
26 // 現在のロケールを決定し、指定されていない場合はデフォルトにフォールバック
27 const currentLocale = locale ?? defaultLocale;
28
29 // パスからロケールプレフィックスを削除してベースパスを構築
30 const pathWithoutLocale = removeLocaleFromUrl(
31 path // 現在のURLパス
32 );
33
34 /**
35 * middleware.prefixDefaultがtrueの場合、デフォルトロケールは常にプレフィックスが付けられます。
36 */
37 if (middleware.prefixDefault) {
38 // ロケールを検証
39 if (!locale || !locales.includes(locale)) {
40 // デフォルトロケールでパスを更新してリダイレクト
41 return (
42 <Navigate
43 to={`/${defaultLocale}/${pathWithoutLocale}`}
44 replace // 現在の履歴エントリを新しいもので置き換える
45 />
46 );
47 }
48
49 // IntlayerProviderで子要素をラップし、現在のロケールを設定
50 return (
51 <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
52 );
53 } else {
54 /**
55 * middleware.prefixDefaultがfalseの場合、デフォルトロケールはプレフィックスが付けられません。
56 * 現在のロケールが有効であり、デフォルトロケールでないことを確認します。
57 */
58 if (
59 currentLocale.toString() !== defaultLocale.toString() &&
60 !locales
61 .filter(
62 (locale) => locale.toString() !== defaultLocale.toString() // デフォルトロケールを除外
63 )
64 .includes(currentLocale) // 現在のロケールが有効なロケールのリストにあるか確認
65 ) {
66 // ロケールプレフィックスなしでパスにリダイレクト
67 return <Navigate to={pathWithoutLocale} replace />;
68 }
69
70 // IntlayerProviderで子要素をラップし、現在のロケールを設定
71 return (
72 <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
73 );
74 }
75};
76
77/**
78 * ロケール固有のルートを設定するルーターコンポーネント。
79 * React Routerを使用してナビゲーションを管理し、ローカライズされたコンポーネントをレンダリングします。
80 */
81export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => (
82 <BrowserRouter>
83 <Routes>
84 <Route
85 // ロケールをキャプチャするルートパターン(例:/en/、/fr/)を指定し、その後のすべてのパスと一致させます
86 path="/:locale/*"
87 element={<AppLocalized>{children}</AppLocalized>} // 子要素をロケール管理でラップ
88 />
89
90 {
91 // デフォルトロケールのプレフィクシングが無効な場合、ルートパスで直接子要素をレンダリング
92 !middleware.prefixDefault && (
93 <Route
94 path="*"
95 element={<AppLocalized>{children}</AppLocalized>} // 子要素をロケール管理でラップ
96 />
97 )
98 }
99 </Routes>
100 </BrowserRouter>
101);
(Optional) Step 8: Change the URL when the locale changes
ロケールが変更されたときにURLを変更するには、useLocaleフックによって提供されるonLocaleChangeプロパティを使用できます。同時に、react-router-domからuseLocationとuseNavigateフックを使用してURLパスを更新できます。
1import { Locales, getLocalizedUrl } from "intlayer";
2import { useLocale } from "react-intlayer";
3import { useLocation, useNavigate } from "react-router-dom";
4
5const LocaleSwitcher = () => {
6 const location = useLocation(); // 現在のURLパスを取得。例:/fr/about
7 const navigate = useNavigate();
8
9 const changeUrl = (locale: Locales) => {
10 // 更新されたロケールでURLを構築
11 // 例:ロケールをスペイン語に設定した場合の/es/about
12 const pathWithLocale = getLocalizedUrl(location.pathname, locale);
13
14 // URLパスを更新
15 navigate(pathWithLocale);
16 };
17
18 const { setLocale } = useLocale({
19 onLocaleChange: changeUrl,
20 });
21
22 return (
23 <button onClick={() => setLocale(Locales.Japanese)}>
24 Change Language to 日本語
25 </button>
26 );
27};
Configure TypeScript
Intlayerは、TypeScriptの利点を得るためにモジュール拡張を使用し、コードベースを強化します。
TypeScriptの設定には自動生成された型を含めるようにしてください。
1// tsconfig.json
2
3{
4 // あなたのカスタム設定
5 include: [
6 "src",
7 "types", // <- 自動生成された型を追加
8 ],
9}
Git Configuration
Intlayerによって生成されたファイルを無視することをお勧めします。これにより、それらをGitリポジトリにコミットするのを避けることができます。
これを行うには、.gitignoreファイルに以下の指示を追加できます:
1# Intlayerによって生成されたファイルを無視
2.intlayer
このドキュメントを改善するアイデアがある場合は、GitHubでプルリクエストを送信することで自由に貢献してください。
ドキュメントへのGitHubリンク