コンテンツにスキップ

国際化(i18n)

Hypermedia Components のテキストのほぼすべてはあなたの HTML から来ます。 それはサーバが好きな言語で描画すればよいものです。しかし少数の文字列は ビヘイビアが注入します — 生成される DOM ノード(コンボボックスの 「No matches」マーカー、マルチセレクトのタグ削除ボタン)と、デフォルトの ARIA ラベル(シェルのナビゲーショントグル、スプリッターのハンドル)です。 これらはマークアップに書けないため、1 か所で翻訳できる小さな メッセージカタログを持ちます。

注入されるすべての文字列について、優先度の高いソースが勝ちます:

  1. サーバ / 作者が書いた要素ごとの属性 — 既存の aria-labeldata-hc-* の上書き。サーバが要素単位でローカライズします。
  2. setMessages() で設定したグローバルカタログ — アプリ全体の ロケール。
  3. 組み込みの英語デフォルト

メインエントリから名前付きインストーラをインポートし、カタログを一度 設定してからインストールします。setMessages() はフラットな { key: value } マップをマージします:

import { setMessages, installCombobox, installConfirm } from '@hypermedia-components/core';
setMessages({
'combobox.empty': '一致なし',
'confirm.confirm': 'OK',
'confirm.cancel': 'キャンセル',
'multicombobox.remove': '{label} を削除', // {label} is interpolated
});
installCombobox();
installConfirm();

組み込み文字列を手で翻訳する必要はありません: 公式のロケールパックが インポート可能なモジュールとしてパッケージに同梱されており、そのまま setMessages() に渡せます。日本語は今日から利用できます:

import { setMessages } from '@hypermedia-components/core/i18n';
import ja from '@hypermedia-components/core/locales/ja';
setMessages(ja);
// App-specific wording layers on top — later merges win:
setMessages({ 'confirm.confirm': 'OK' });

すべてのパックはすべてのカタログキーをカバーします: ビヘイビアが キーを追加したのに同梱パックが翻訳していない場合、キット自身の CI が 失敗するため、アップグレードをまたいでパックがカタログに静かに遅れる ことはありません。

ゼロ設定の /behaviors エントリは実行と同時にすべてをインストールするため、カタログはその 前に設定してください。ES モジュールスクリプトはドキュメント順に 実行されるので、まず i18n モジュールからメッセージを設定し、その後で バンドルを読み込みます:

<script type="module">
import { setMessages } from '@hypermedia-components/core/i18n';
setMessages({ 'combobox.empty': '一致なし' });
</script>
<script type="module" src="/path/to/hc.behaviors.js"></script>

setMessages@hypermedia-components/core(自動初期化のメイン エントリ)からインポートすると、先にインストールが走ってしまいます — 自動初期化フローでは、副作用のない i18n サブモジュールから インポートしてください。

キーデフォルト注入元
combobox.emptyNo matchesコンボボックスの空結果マーカー
combobox.loadingLoading…リモートコンボボックスの読み込み行
combobox.errorCouldn’t load optionsリモートコンボボックスのエラー行
combobox.createCreate “{value}”作成可能コンボボックスの「作成」オプション
multicombobox.emptyNo matchesマルチコンボボックスの空結果マーカー
multicombobox.createAdd “{value}”作成可能マルチコンボボックスの「追加」オプション
multicombobox.removeRemove {label}タグ削除ボタンの aria-label
calendar.labelCalendarグリッドの aria-label(フォールバック)
calendar.prevMonthPrevious month前月ボタンの aria-label
calendar.nextMonthNext month翌月ボタンの aria-label
calendar.monthMonth月ドロップダウンの aria-label(data-nav="select")
calendar.yearYear年ドロップダウンの aria-label(data-nav="select")
confirm.messageContinue?確認ダイアログ本文(フォールバック)
confirm.titleConfirm確認ダイアログタイトル(フォールバック)
confirm.confirmConfirm確認ボタン(フォールバック)
confirm.cancelCancelキャンセルボタン(フォールバック)
datagrid.selected{selected} selected選択アクションバーの件数({selected} / {total} パラメータ)
fieldErrors.unknownInvalid value解決できるキーもテキストもない field-errors 項目
copy.okCopiedコピーボタン成功時の role="status" 通知(data-hc-copy-ok で上書き可)
dirtyguard.leaveYou have unsaved changes. Leave this page?unsaved-changes の boosted ナビゲーション確認(タブを閉じる際のプロンプトはブラウザ汎用のまま)
sortable.handleReorder記号のみの並べ替えハンドルの aria-label(フォールバック)
sortable.grabbedGrabbed. Position {index} of {count}.キーボードでつかんだときの role="status" 通知
sortable.movedPosition {index} of {count}キーボード移動の通知
sortable.droppedDropped. Position {index} of {count}.並べ替え確定の通知
sortable.cancelReorder cancelled並べ替えキャンセルの通知
shell.toggleNavToggle navigationシェルのナビトグル aria-label(フォールバック)
shell.collapseNavCollapse sidebarシェルの折りたたみボタン aria-label(フォールバック)
splitter.resizeResize panelsスプリッターハンドルの aria-label(フォールバック)
networkRetry.failedThe request didn't reach the server — check your connection and retry.network-retry の無応答アラート
networkRetry.retryRetryその再試行ボタンのラベル
themeToggle.labelSwitch color themeアイコンのみテーマトグルの aria-label(フォールバック)
toast.dismissDismissトーストの閉じるボタンの aria-label
toast.labelNotificationsトースト領域の aria-label(フォールバック)

この表が完全なリストです — ビヘイビアが描画しうるすべての文字列は DEFAULT_MESSAGES から来るため、これらのキーを上書きすればキット全体が 翻訳されます。

キーの一覧は公開 API 表面の一部です(リポジトリの VERSIONING.md を 参照): DEFAULT_MESSAGES がエクスポートされているのは、まさに インストール中のバージョンが定義するキーを列挙できるようにするためです。 ロケールパックを使わず独自カタログを維持する場合は、CI で Object.keys(DEFAULT_MESSAGES) と diff を取り、新バージョンが追加した キーを検出してください — 失敗モードは英語へのフォールバックで、目視では 誰も気づきません。

{name} プレースホルダーは、ビヘイビアが渡すパラメータから補間されます — multicombobox.remove{label}、作成可能な combobox.create / multicombobox.create オプションの {value} です。

起動時に日本語ロケールパックからカタログを一度設定します — すべての キーをカバーするため、以後キットが英語を描画することはありません:

import { setMessages } from '@hypermedia-components/core/i18n';
import ja from '@hypermedia-components/core/locales/ja';
setMessages(ja);

破壊的アクションには、ダイアログのクロームのためのボタンごとの属性が 不要になります — 必要なのはメッセージ本文だけです:

<button class="hc-button" data-variant="error"
data-hc-confirm="ユーザー alice を無効化しますか?"
data-hx-post="/users/alice/disable"
data-hx-trigger="hc:confirmed">
ユーザーを無効化
</button>

タイトル(確認)、確認ボタン(実行)、キャンセルボタン(キャンセル)は カタログから来ます。data-hc-confirm-* 属性は要素ごとの上書きとして 引き続き使えます。 カタログはあなた自身のキーも解決します: field-errors レシピは、 サーバが送る各 data-message-key(例: members.email.duplicate)を同じ カタログで検索し、{field} / {code} — およびサーバが data-message-params として送る値 — を補間に使えます。

要素ごとの上書き(サーバサイドローカライズ)

Section titled “要素ごとの上書き(サーバサイドローカライズ)”

文字列が特定の要素に属するときは、マークアップに書けばカタログより 優先されます — サーバが各領域の言語をすでに知っている場合に便利です:

  • confirm — トリガーの data-hc-confirmdata-hc-confirm-titledata-hc-confirm-labeldata-hc-cancel-label
  • combobox / multi-combobox<ul role="listbox">data-hc-empty
  • calendar / shell / splitter / toast — 作者が与えた aria-label は 決して上書きされません。
<!-- This dialog stays Japanese regardless of the global catalog. -->
<button class="hc-button" data-hc-confirm="削除しますか?"
data-hc-confirm-label="削除" data-hc-cancel-label="キャンセル">
削除
</button>
<!-- Per-listbox empty text. -->
<ul class="hc-combobox__listbox" role="listbox" data-hc-empty="該当なし"></ul>

すべてメインエントリと i18n サブモジュールからエクスポートされます。

  • setMessages(overrides) — 翻訳をカタログにマージ。直前の状態を復元する 関数を返します。
  • resetMessages() — 組み込みの英語デフォルトに戻します。
  • getMessages() — 現在のカタログ(デフォルト + 上書き)のスナップショット。
  • hasMessage(key) — カタログがキーを解決できるか(組み込みデフォルト または上書き)。キーそのものへのフォールバックと区別できます。
  • DEFAULT_MESSAGES — フリーズされた英語デフォルト。

欠けた翻訳は穏やかに劣化します: 未知のキーは英語デフォルトへ、次にキー そのものへフォールバックします — 空文字列や例外にはなりません。

ローカライズされたタイムスタンプ

Section titled “ローカライズされたタイムスタンプ”

サーバーは UTC をレンダリングします — サーバーの時計が言える唯一の 正直なことです。自動インストールされる installTime() が、見ている 人のタイムゾーンと言語で表示テキストを Intl 経由で書き換えます:

<time datetime="2026-08-08T03:24:00Z" data-hc-time="relative">
2026-08-08 03:24 UTC
</time>
  • data-hc-time="relative" — 「3 分前」(Intl.RelativeTimeFormat、 30 秒ごとに更新)。title がなければ絶対時刻のローカライズ 文字列が入ります。
  • data-hc-time="datetime" | "date" | "time" — 絶対時刻のローカル 表示。data-hc-time-style="short | medium | long | full" で スタイルを選べます。
  • datetime 属性には決して触れません(ワイヤ上の真実)。サーバーが レンダリングしたテキストが no-JS のフォールバックで、解析できない 値はそのまま残り、言語は最も近い [lang] に従います。htmx で スワップされたコンテンツは自動的にローカライズされます。

メッセージキーは関与しません — 言語は Intl が運びます。