Skip to content

国際化

N.E.K.O. はクライアントサイドのロケール切り替えにより 5 言語をサポートしています。

サポートされているロケール

コード言語ファイル
en英語static/locales/en.json
zh-CN簡体字中国語static/locales/zh-CN.json
zh-TW繁体字中国語static/locales/zh-TW.json
ja日本語static/locales/ja.json
ko韓国語static/locales/ko.json

仕組み

  1. ページ読み込み時に、システムがユーザーの言語を検出します:
    • まず Steam クライアントの言語を確認します(/api/config/steam_language 経由で利用可能な場合)
    • ブラウザの言語設定にフォールバックします
    • ユーザーの上書き設定を尊重します(/api/config/user_language
  2. 対応するロケール JSON ファイルを読み込みます
  3. data 属性または直接的な JS 置換を使用して DOM 内のテキストコンテンツを置き換えます

ロケールファイルの形式

ロケールファイルはドット記法のキーを持つフラットな JSON オブジェクトです:

json
{
  "nav.home": "Home",
  "nav.settings": "Settings",
  "chat.placeholder": "Type a message...",
  "chat.send": "Send"
}

i18n マークアップパターン

HTML: data-i18n 属性

html
<!-- 要素テキスト -->
<span data-i18n="chat.send">発送</span>
<button data-i18n="common.ok">確定</button>

<!-- プレースホルダー -->
<input placeholder="請輸入" data-i18n-placeholder="chat.inputPlaceholder">

<!-- title 属性 -->
<button title="関閉" data-i18n-title="common.close">X</button>

<!-- alt 属性 -->
<img alt="対話" src="chat.png" data-i18n-alt="chat.title">

JavaScript: window.t() とフォールバック

適切なフォールバックのために常に中国語のフォールバックを提供してください:

javascript
// 表示テキスト
showStatusToast(window.t ? window.t('common.connectionSuccess') : '連接成功', 2000);

// エラーメッセージ
showMessage(window.t ? window.t('common.saveFailed') : '保存失敗', 'error');

// パラメータ付き
showMessage(window.t ? window.t('files.deleted', { count }) : `削除了 ${count} 個文件`);

i18n 化すべきでないもの

javascript
// ✅ スキップ: コンソールデバッグメッセージ
console.log('連接成功');

// ✅ スキップ: 内部ロジックの検出
if (status.includes('已離開')) { ... }

// ✅ スキップ: データキー(キャラクターフィールド名)
const name = characterData['档案名'];

// ✅ スキップ: すでにラップ済み
showMessage(window.t ? window.t('key') : 'fallback');

モジュールとファイルのマッピング

未翻訳の文字列をチェックする際は、以下のモジュールグループを使用してください:

モジュールHTML ファイルJS ファイル
mainindex.htmlapp.js
live2dlive2d*.htmllive2d*.js
voicevoice*.htmlvoice*.js, tts*.js
steamsteam*.htmlsteam*.js
settingssettings*.html, config*.htmlsettings*.js, config*.js
chatmemory_browser.html, chara_manager.htmlmemory_browser.js, chara_manager.js

HTML + アイコンの競合

i18next が textContent 経由でテキストを更新すると、要素内の <img> タグが破壊されます。翻訳に HTML アイコンが含まれる場合、完全な HTML をロケール JSON に含めることで、システムが代わりに innerHTML を使用するようになります。開発者ノート を参照してください。

新しい言語の追加

  1. static/locales/ に新しいファイルを作成します(例: fr.json
  2. en.json の構造をコピーし、すべての値を翻訳します
  3. フロントエンドの言語セレクターにロケールオプションを追加します
  4. utils/language_utils.py を更新して新しいロケールコードを認識させます

バックエンド翻訳

バックエンドも TranslationServiceutils/translation_service.py)経由で翻訳をサポートしています:

  • プライマリ: googletrans ライブラリ
  • フォールバック: translatepy ライブラリ
  • 最終フォールバック: LLM ベースの翻訳

これは、ユーザーの言語がキャラクターの言語と異なる場合にセッションマネージャー内の translate_if_needed() で使用されます。

MIT ライセンスの下で公開。