
1. i18nとは?
i18n
は “internationalization”(インターナショナライゼーション)の略称で、
“i” から “n” までの18文字を省略して名付けられています。
簡単にいえば、アプリケーションやゲームを多言語に対応させるための設計・実装のことです。
✅ 関連用語
i18n
:国際化(internationalization)l10n
:ローカライズ(localization)t9n
:翻訳(translation)
✅ なぜ必要?
- 世界中のユーザーに使ってもらうため
- 表示する言語を切り替えられるようにするため
- 管理やメンテナンスを効率化するため(=翻訳ファイルの分離)
💬 例:日本語と英語で表示切り替え
Key | 日本語 | 英語 |
---|---|---|
title | ゲーム開始 | Start Game |
settings | 設定 | Settings |
exit | 終了 | Exit |
2. 言語ファイルを準備する
i18nをシンプルに始めるなら、言語ごとにJSONファイルを分ける方法が一番手軽でおすすめです。
📁 例:フォルダ構成
/assets/data/lang_ja.json
/assets/data/lang_en.json
📝 lang_ja.json
{
"title": "ゲーム開始",
"settings": "設定",
"exit": "終了"
}
📝 lang_en.json
{
"title": "Start Game",
"settings": "Settings",
"exit": "Exit"
}
💡 ポイント
- キー(例:title, settings)はすべての言語で共通にする
- 翻訳ファイルを増やすだけで言語追加が可能になる
3. JSONを読み込んで画面に反映
ここでは、選択した言語のJSONファイルを fetch() で読み込み、HTMLの要素に反映する基本的な実装を紹介します。
🔄 HTML側(例)
<h1 id="title"></h1>
<button id="settings-btn"></button>
<button id="exit-btn"></button>
📥 JavaScriptで読み込み
async function loadLanguage(lang = "ja") {
const res = await fetch(`/assets/data/lang_${lang}.json`);
const translations = await res.json();
document.getElementById("title").textContent = translations.title;
document.getElementById("settings-btn").textContent = translations.settings;
document.getElementById("exit-btn").textContent = translations.exit;
}
// 初期読み込み(例:日本語)
loadLanguage("ja");
💡 応用のヒント
- data-i18n=“key名” を使ってループで一括更新することも可能
- ボタンで言語を切り替える実装はこのあと紹介します
4. 切り替えボタンとlocalStorage保存
言語選択をユーザーが行えるようにし、その選択を localStorage に保存して、次回アクセス時にも同じ言語が適用されるようにします。
🌐 HTMLに言語切り替えボタンを追加
<button onclick="switchLanguage('ja')">日本語</button>
<button onclick="switchLanguage('en')">English</button>
🔁 JavaScriptで切り替え処理を実装
async function switchLanguage(lang) {
localStorage.setItem("lang", lang);
await loadLanguage(lang);
}
🚀 ページ初期表示時に保存された言語を適用
const savedLang = localStorage.getItem("lang") || "ja";
loadLanguage(savedLang);
💡 ポイント
- localStorage はページを再読み込みしても値が保持される(ブラウザに永続保存)
- ユーザーの利便性を高める重要な工夫
5. 実用例:ボタン・UI・テキストに適用
i18nの導入は、ボタンやメニューといったUIだけでなく、説明文やポップアップ、モーダルなどゲームやアプリ全体に展開できます。
ここでは、共通のキーを data-i18n 属性に持たせ、JavaScriptで一括置き換えする方法を紹介します。
🧩 HTML例(共通構造)
<h1 data-i18n="title"></h1>
<button data-i18n="settings"></button>
<p data-i18n="description"></p>
⚙ JavaScriptで一括反映
async function loadLanguage(lang = "ja") {
const res = await fetch(`/assets/data/lang_${lang}.json`);
const translations = await res.json();
document.querySelectorAll("[data-i18n]").forEach(el => {
const key = el.getAttribute("data-i18n");
if (translations[key]) {
el.textContent = translations[key];
}
});
}
✅ メリット
- UIを構造的に書ける(HTMLと翻訳が分離)
- 言語ファイルを更新すれば即反映される
- コードの保守性・拡張性が高い
よくある落とし穴
i18nの導入はシンプルに見えて、いくつかつまずきやすいポイントがあります。ここでは実際によく起きる問題とその解決策を紹介します。
❗ 非同期処理のタイミングずれ
loadLanguage("ja");
document.getElementById("title").textContent = "..."; // ← 上書きされてしまう!
✅ 対処法
- 翻訳ファイルの読み込み完了後にUIの更新を行う
- await を正しく使う or .then() を使って同期タイミングを管理
❗ 要素がまだ描画されていない
document.querySelectorAll("[data-i18n]").forEach(...); // 要素がまだDOMに存在しない場合、反映されない!
✅ 対処法
- DOMContentLoaded イベントの後に呼び出す
document.addEventListener("DOMContentLoaded", () => {
loadLanguage("ja");
});
❗ 翻訳ファイルにキーが存在しない
{
"start": "ゲーム開始"
}
<h1 data-i18n="title"></h1> <!-- title が存在しない! -->
✅ 対処法
- 翻訳キーの見直し&共通化(lintやチェックツールも活用)
- 未定義のキーにはデフォルト値を入れるなどの工夫も可
❗ 言語切り替えが反映されない(キャッシュ問題)
- ブラウザがJSONをキャッシュしていて、内容が変わっても反映されない場合がある
✅ 対処法
fetch(`/assets/data/lang_${lang}.json?ts=${Date.now()}`); // タイムスタンプを付与
これらの落とし穴を意識しておくだけで、実装の安定性が大きく変わります。
7. まとめ:i18nを味方につける
- まとめ:i18nを味方につける
i18n(国際化)は一見すると専門的な技術のように思われがちですが、JSONとJavaScriptを活用することで、意外なほどシンプルに実装できます。
今回の記事では、
- 言語ファイルの設計(JSON)
- 画面への反映方法(textContent / data-i18n)
- 言語切り替えとlocalStorageの保存
- よくあるミスと対処法
…と、i18nの実用的な導入フローを学びました。
🎯 これからやるべきこと
- 自分のUIに data-i18n を取り入れてみる
- 日本語+英語の2言語対応から始めてみる
- 翻訳ファイルや設定を localStorage で保存してみる
💬 最後にひとこと
「i18n対応」は、“作品を自分の世界だけに留めない”という表現の広がり。たったひとつのJSONファイルが、あなたのゲームを世界に届ける鍵になるかもしれません。
今後もゲーム開発やWebアプリ制作の中で、i18nを“味方”にして、もっと自由に、もっと柔軟に表現していきましょう!
余談
ありがとうございます。
localStorage はページを再読み込みしても値が保持される(ブラウザに永続保存)
これは、DecapCMSの時にやった、
F12 → DevTools を起動 上部タブで「Application(アプリケーション)」を選択 左サイドバーから: 「Storage」→「Clear site data」にチェックを入れて「Clear site data」 「IndexedDB」→ すべてのデータベースを右クリック → 「Delete」
これかな…。
そうです、それまさに localStorage や IndexedDB などの「Webストレージ系」のデータを完全に消す操作 です!
🔍 あらためて整理すると:
ストレージ種別 | 解説 |
---|---|
localStorage | キー・バリュー形式でデータを保存。ページを再読み込みしても値は保持される(ブラウザごとに永続)。容量は約5MB前後。 |
sessionStorage | localStorageと似てるが、ブラウザタブを閉じると消える。 |
IndexedDB | 構造化された大きなデータ保存用。CMSなど高度なWebアプリで利用されることが多い。 |
Cookies | サーバーとのやりとりで使うことも多い。セッション管理などで使われる。 |
🔧 DevTools の Application タブでの操作
-
「Clear site data」ボタン:
localStorage
、IndexedDB
、Cookies
、Cache Storage
などをまるごと削除します。
-
localStorage だけを消す:
- 左ペインの「Storage → Local Storage → 自分のサイトURL」を選択 → 右側のキーを右クリック → 「Clear」
✅ 実用のヒント
i18nで使った localStorage.getItem("lang")
の保存値もこの操作で削除されます。
つまり、リセットして再テストしたいときに便利です。
もし今後、
- 設定を保持したいがリセットもしたい
- 複数端末での挙動を検証したい
などが出てきたら、localStorage
や IndexedDB
の扱い方をもう一段深く学んでもいいかもしれませんね。
希望があれば、その辺の講座も用意できます!
💬 コメント