Remixとreact-i18nextで多言語対応
remix-i18nextを使う紹介もあったりしましたが、あまり依存を増やしたくなかったのでreact-i18nextのみ(i18nextは使う)で多言語対応してみたメモです。
ChatGPTでサンプルコード生成
まずはChatGPTでサンプルコードを作成してもらいました(笑
Remixのセットアップ
こちらを参考に以下のコマンドでセットアップします。表示される選択肢を選びながら進めば完了です。
npx create-remix@latest
react-i18nextの導入
こちらを参考にパッケージを追加します。
npm install react-i18next i18next --save
構成ファイルの作成
procject/app/i18n.ts を作成します(ChatGPTのサンプルのコピペ)
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
const resources = {
en: {
translation: {
"welcome": "Welcome",
// 他の翻訳キーと値を追加
},
},
ja: {
translation: {
"welcome": "ようこそ",
// 他の翻訳キーと値を追加
},
},
};
i18n.use(initReactI18next).init({
resources,
lng: "en",
fallbackLng: "en",
interpolation: {
escapeValue: false,
},
});
export default i18n;
i18nのインスタンスを使えるようにする
ここが少しポイントでした。
ChatGPTやQuickStartは通常のReactを想定しているため、index.js(HTMLDocumentにReactをレンダリングする指定が含まれるファイル)に、上記構成ファイルをインポートするようになっています。
しかし、Remixではそのようなファイルがありません(通常見えるプロジェクトファイル内には)ので、react-i18next の I18nextProvider を利用しました。
project/app/root.tsx に追記します。
import i18n の追加と <Outlet /> を I18nextProvider で囲みます。
import type { MetaFunction } from "@remix-run/node";
import {
Links,
LiveReload,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "@remix-run/react";
import { I18nextProvider } from "react-i18next";
import i18n from "./i18n";
export const meta: MetaFunction = () => ({
charset: "utf-8",
title: "New Remix App",
viewport: "width=device-width,initial-scale=1",
});
export default function App() {
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
<I18nextProvider i18n={i18n}>
<Outlet />
</I18nextProvider>
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
);
}
ページ内で利用
多言語対応したいページで以下のように利用します。
project/app/routes/index.tsx (元々生成されたファイルに追記)
import { useTranslation } from "react-i18next";
export default function Index() {
const { t, i18n } = useTranslation();
const change = (language: string) => {
console.log(language);
i18n.changeLanguage(language);
};
return (
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
<h1>{t("welcome")}</h1>
<button onClick={() => change("en")}>English</button>
<button onClick={() => change("ja")}>日本語</button>
<ul>
<li>
<a
target="_blank"
href="https://remix.run/tutorials/blog"
rel="noreferrer"
>
15m Quickstart Blog Tutorial
</a>
</li>
<li>
<a
target="_blank"
href="https://remix.run/tutorials/jokes"
rel="noreferrer"
>
Deep Dive Jokes App Tutorial
</a>
</li>
<li>
<a target="_blank" href="https://remix.run/docs" rel="noreferrer">
Remix Docs
</a>
</li>
</ul>
</div>
);
}
i18n.changeLanguage(language) で言語を変更して表示します。
この記事が気に入ったらサポートをしてみませんか?