はじめに
こんにちは。
画面のヘッダーやラベル、プルダウンメニュー項目など様々な箇所で使うメッセージ文言、皆さんはどのように管理していますでしょうか?
ここ最近 react-i18next
を使ってみて便利に感じたので、今回はreact-i18next
を使ってメッセージ文言管理を行うやり方を紹介したいと思います。
今回のサンプルは こちら にあげています。
react-i18nextとは
react-i18next is a powerful internationalization framework for React / React Native which is based on i18next.
react-i18nextは、i18nextを基盤とした、React/React Native向けの強力な国際化フレームワークです。(Geminiで和訳)
多言語対応のフレームワークになります。本来の使い方とはズレますが、メッセージ文言管理にも活用できるので、以下でコード例を見ていきたいと思います。
実行環境について
以下の環境で試しています。
- react@18.3.1
- next@14.2.15
事前準備
react-i18nextをプロジェクトに導入。
npm install react-i18next i18next --save
react-i18nextを使った実装サンプル
それではいくつかファイルを準備して実行をしていきます。
メッセージ管理用ファイル
メッセージ管理用のファイルにメッセージをまとめます。
{
"header": {
"title": {
"list": "セール一覧",
"regist": "セール登録",
"detail": "セール詳細"
}
},
"form": {
"button": {
"addSale": "セール追加",
"search": "検索",
"regist": "登録",
"update": "更新",
"back": "戻る"
},
"label": {
"saleName": "セール名",
"saleStatus": "ステータス",
"itemCategory": "商品カテゴリ",
"startDate": "開始日",
"endDate": "終了日"
},
"selectbox": {
"itemCategory": {
"digitalEquipment": "デジタル機器",
"sportsOutdoors": "スポーツ用品",
"books": "本",
"dailyNecessities": "日用品",
"kitchenItems": "キッチン用品",
"foodBeverageAlcohol": "食品・飲料・アルコール",
"cosmeticsAndBeautySupplies": "化粧品・美容用品"
}
}
}
}
react-i18nextの初期化設定
続いて上記メッセージファイルを読み込む設定を追加します。
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import translation_ja from "./ja.json";
const resources = {
ja: {
translation: translation_ja,
},
};
i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init({
resources,
lng: "ja",
interpolation: {
escapeValue: false, // react already safes from xss
},
});
export default i18n;
-
translation
内に「キー:メッセージ」のJSON形式でメッセージ定義できます - メッセージ定義はソースコードと分けたほうが使い勝手良いので、ここではJSON形式で定義した
ja.json
をimport
する形を取っています
プロジェクトにインポートする
先ほどの configs.ts
を読み込み、各コンポーネントでメッセージ文言を扱えるようにします。
ここではappルート直下の layout.tsx
で読み込みを行っています。
"use client";
// import type { Metadata } from "next";
import localFont from "next/font/local";
import "./globals.css";
import { Header } from "@/components/Header";
import "../i18n/configs"; // <-これを追加
・・・(略)
- import を追加しただけですが、これで配下のコンポーネントでメッセージを扱うことができるようになります
メッセージを表示する
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next"; // <-これを追加
import { Form, formSchema } from "./yupForm";
import { yupResolver } from "@hookform/resolvers/yup";
import { InputControl } from "@/components/form/input/InputControl";
import { SelectBoxControl } from "@/components/form/selectbox/SelectBoxControl";
import { CustomDatePickerControl } from "@/components/form/datepicker/CustomDatePickerControl";
import { Button, ButtonType } from "@/components/Button";
export const SaleListForm = () => {
const { t } = useTranslation(); // <-これを追加
const methods = useForm<Form>({
mode: "onBlur",
defaultValues: {
saleName: "",
},
resolver: yupResolver(formSchema),
});
const onSubmit = (data: Form) => console.log(JSON.stringify(data));
return (
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)} noValidate>
<div className="flex items-center gap-4 mb-4 px-16">
<label htmlFor="saleName" className="w-32">
{t("form.label.saleName")} {/* <-これを追加 */}
</label>
<InputControl<Form>
fieldName="saleName"
className="text-black flex-1 border h-10 rounded leading-10"
/>
</div>
・・・(略)
-
useTranslation
フックで取得されるt
ファンクションを経由して、i18next の翻訳コンテンツにアクセスできます - 「t({対象メッセージ文言のキー})」の形式でメッセージを読み込むことができます
これを実行すると以下のように読み込んだメッセージを表示されます。
終わりに
これまでメッセージ文言をソースコードに直書きしたりしていましたが(これで辛みを見たことが何度もあって・・)、一見管理できていると修正の負担も大分軽減できて嬉しい、積極的に活用していきたいと思いました。
それでは〜