1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

パッケージをインストール

npm install i18next react-i18next i18next-browser-languagedetector

JSONオブジェクト

多言語対応(i18n: internationalization)を目的とした、英語テキスト、日本語テキストを定義する JSON オブジェクトです。

en/translation.json
{
  "dashboardTitle": "📦 Product Management Dashboard",
  "searchPlaceholder": "Search",
  "createProduct": "➕ Add Product",
  "basicInfo": "📋 Product List (Basic Info)",
  "pricingInfo": "💰 Pricing & Inventory",
  "supplyInfo": "🛒 Supply Information",
  "productionInfo": "🧑‍🌾 Production & Manufacturing",
  "logisticsInfo": "📦 Logistics Information",
  "adminInfo": "🧑‍💻 Admin & Operations"
}
ja/translation.json
{
  "dashboardTitle": "📦 商品管理ダッシュボード",
  "searchPlaceholder": "検索",
  "createProduct": "➕ 商品追加",
  "basicInfo": "📋 商品一覧(基本情報)",
  "pricingInfo": "💰 価格・在庫情報",
  "supplyInfo": "🛒 仕入れ情報",
  "productionInfo": "🧑‍🌾 生産・製造情報",
  "logisticsInfo": "📦 ロジスティクス情報",
  "adminInfo": "🧑‍💻 管理・運用情報"
}

i18next を使って 多言語対応(国際化) を設定するための初期化処理

i18n.ts
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import ja from "@/locales/ja/translation.json";
import en from "@/locales/en/translation.json";

• i18next: 国際化ライブラリのコア機能を提供。
• initReactI18next: React で i18next を使うためのアダプタ(useTranslation() などが使えるようになる)。
• ja, en: 日本語・英語の翻訳 JSON ファイルを読み込んでいる(例: translation.json という名前で翻訳文字列が定義されている)。

i18n.ts
i18n.use(initReactI18next).init({
  resources: {
    ja: { translation: ja },
    en: { translation: en }
  },
  lng: "ja",
  fallbackLng: "ja",
  interpolation: {
    escapeValue: false
  }
});

export default i18n;
オプション名 内容
use(initReactI18next) React 用に i18n を初期化。Hooks (useTranslation) などが使えるようになる。
resources 各言語ごとの翻訳データを指定。ここでは ja と en を設定している。
lng アプリの初期言語(ここでは日本語 "ja")。
fallbackLng lng が見つからない場合に代わりに使う言語(ここも "ja")。
interpolation.escapeValue React は自動で XSS 対策するため false にする(通常このままでOK)。

XSSとは?

<script>alert('XSS!');</script>

このようなスクリプトが、コメント欄やフォームなどに入力され、画面上でそのまま表示・実行されると、以下のような被害が起こり得ます:

• ユーザーの Cookie情報やセッション情報の盗難
• 偽のフォームを表示して フィッシング詐欺
• 悪意あるリンクをクリックさせて マルウェアを配布

XSS対策

• ユーザーの入力値をそのままHTMLに埋め込まない
• JSXでは基本的に自動でエスケープされる
• dangerouslySetInnerHTMLの使用を避ける
• ライブラリを利用する

言語切り替え機能(多言語対応)を提供するUIコンポーネント

LanguageSwitcher.tsx
"use client";

import { useTranslation } from "react-i18next";

• use client: Next.js の App Router 環境で、クライアントコンポーネントであることを宣言。
• useTranslation: i18next の React フック。現在の言語情報や翻訳関数 t() を取得できる。

LanguageSwitcher.tsx
const { i18n } = useTranslation();

• i18n オブジェクトを取得。これにより、現在の言語 (i18n.language) の取得や、i18n.changeLanguage() による変更が可能になる。

LanguageSwitcher.tsx
const changeLanguage = (lng: "ja" | "en") => {
  i18n.changeLanguage(lng);
};

• 引数 lng に基づいて、言語を "ja" か "en" に切り替える。
• 内部的には、i18next の言語設定を変更し、再レンダリングが走る。

LanguageSwitcher.tsx
return (
  <div className="flex gap-2">
    <button ...>日本語</button>
    <button ...>English</button>
  </div>
);

🔘 ボタンのクラスと条件付きスタイル

LanguageSwitcher.tsx
className={`px-3 py-1 rounded text-sm border ${i18n.language === "ja" ? "bg-blue-500 text-white" : "bg-white text-gray-700 border-gray-300"}`}

• i18n.language が "ja" のときは、ボタンを青背景(選択中)。
• それ以外のときは、灰色ボーダーの通常ボタン。
• Tailwind CSS を使用してスタイリングされている。

ホーム画面

page.tsx
<h1 className="text-3xl font-bold text-gray-800">
  {t("dashboardTitle")}
</h1>

• 翻訳キー dashboardTitle に対応する言語データを表示。

page.tsx
<input
  placeholder={t("searchPlaceholder")}
/>

• 入力フィールドのプレースホルダーに翻訳された文言を使用。

page.tsx
<Section title={t("basicInfo")}>
  <ProductList searchKeyword={searchKeyword} />
</Section>

• セクションの見出しにも t() を使って、動的に言語を切り替え可能に。

page.tsx
<LanguageSwitcher />

• コンポーネント LanguageSwitcher.tsx により、ユーザーが "ja" / "en" を切り替え可能。
• その中で i18n.changeLanguage("ja") のように、言語設定を動的に変更。

UI

画面収録 2025-07-26 9.03.25.gif

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?