svintl について
svintlは、Svelteの国際化辞書を管理するCLIで、多言語アプリを開発する人向けです。翻訳ファイルを生成し、OpenAIによる言語追加、動的な値、複数形、マウント単位の管理に対応します。
主な機能
- 01CLIによる辞書管理
- 02OpenAIを使った翻訳生成
- 03プレースホルダーと複数形の処理
- 04マウント単位で翻訳を整理
活用シーン
- 01翻訳キーの一括追加や更新
- 02コンテキストに基づく辞書の生成
- 03動的な文言や複数形の利用
- 04アプリ領域ごとの翻訳分割
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ temich/ svintl --skill svintlインストール後、Claude Code で/svintlを入力して読み込まれたか確認します。
詳細
svintl — Svelte 向け i18n
OpenAI による自動翻訳を利用して、国際化辞書を管理する CLI ツールです。
基本ルール
intl ディレクトリ内の *.yaml、built.js、types.ts ファイルは生成されるファイルです。手動で編集せず、npx intl CLI で編集してください。
CLI コマンド
npx intl hola # init dictionaries (default: src/lib/intl/)
npx intl hola -p ./custom/path # init at custom path
npx intl add key.path "Value" "context" # add a new key — fails if it already exists; context optional
npx intl set key.path "Updated value" # update a key that already exists — fails if missing
npx intl set "mount/key.path" "Value" # target a mount with the mount/ prefix
npx intl add --from strings.yaml # many new keys in one run — `key: value` or `key: { value, context }`, flat (`a.b: …`) or nested (`a: { b: … }`)
npx intl set --from strings.yaml # many existing keys in one run; `--from -` reads stdin
npx intl add key.path "Value" --debug # --debug (add or set): print the OpenAI request first
npx intl create de --tokens 60000 # --tokens (any command): output-token limit per OpenAI request, default 30000
npx intl const key.path "Same everywhere" # same value across all locales (no translation)
npx intl unit items.count "item" # pluralized entry (auto-generates plural forms)
npx intl move old.key new.key # rename key/branch
npx intl del key.path # delete key/branch
npx intl create es # add a locale (BCP 47 tag) — auto-translates the whole dictionary into it
npx intl destroy es -y # delete locale (without -y it fails)
npx intl mount foo ./any/path # create empty mount
npx intl import foo ./any/path # adopt existing dict dir as mount, reconcile locales
npx intl unmount foo # remove mount (keeps files)
npx intl context "Project description" # set project-wide translation guidance
npx intl context --clear # clear project context
npx intl genders he she none # enable gender-aware translations (list the gender values)
npx intl genders # print current gender values
npx intl sync en key.path # reconcile: re-translate one key into all locales from source en
npx intl sync en # reconcile: re-translate the whole dictionary from source en
npx intl build # rebuild JS/TS from YAML
辞書の形式
任意の階層構造を持つ YAML で、末端の値には文字列を指定します。
native: English
example:
hello: "Hello world"
使用方法:{$dict.example.hello}
動的な値 — プレースホルダー
単純なケースでは、CLI がプレースホルダー構文から !js 関数を自動生成するため、手動で記述する必要はありません。
npx intl set greeting "Hello, {name}!" # {name} → function param
npx intl set joined "[names] joined {groupName}" # [names] → Intl.ListFormat
複雑なロジックの場合は、intl set で !js 関数を渡します。
npx intl set greeting '!js (count) => `${count || "No"} item${count === 1 ? "" : "s"}`'
コンポーネントでの使用方法:{$dict.greeting(user.name)}
フレーズ全体を辞書に記述してください。 テンプレート内で動的な値を挟んで文を分割しないでください。
<strong>{brand}</strong>{$dict.form.destroyDescription}
{@html $dict.form.destroyDescription(brand)}
npx intl set "apps/form.destroyDescription" \
'!js (brand) => `<strong>${brand}</strong> and all accumulated data will be permanently deleted.`'
名前にマークアップが必要で、どの言語でも常にフレーズの先頭にある場合は、タグを !js 関数内に記述し、{@html} でレンダリングしてください。値を渡す前に、ユーザーが制御する値をエスケープしてください。
複数形
npx intl unit を使用すると、Intl.PluralRules ベースの関数が生成されます。
npx intl unit items.count "item"
次のように生成されます。
items:
count:
- one: item
other: items
使用方法:{$dict.items.count(count)}
ロシア語やアラビア語など、複雑なロケールでは few、many なども自動的に生成されます。
性別
有効にすると(npx intl genders he she none)、性別に応じたフレーズは、最後の引数に性別('he' | 'she' | 'none')を取る関数になります。フレーズ自体の引数が先に来ます。たとえば (name, gender) => … のようになります。列挙した値は、生成される Grammar ユニオン型になります。
マウント
翻訳を複数のディレクトリに分けて整理できます。
npx intl mount admin ./src/features/admin/intl
npx intl set "admin/dashboard.title" "Admin Dashboard"
マウントキーには、CLI コマンドで {mount}/ プレフィックスを使用します。
mount は空のマウントを作成し、import は内容のあるディレクトリ(独自の context.yaml を含む)を取り込み、そのロケールをルートに合わせて調整します。ルートにない言語を削除し、ルートにない言語を生成して(取り込んだ inputs を翻訳します)、共通するロケールはそのままにします。
インポートのパターン
ルート辞書:
<script lang="ts">
import { dict, locale } from '$lib/intl'
</script>
<h1>{$dict.example.hello}</h1>
マウント辞書:
<script lang="ts">
import { dict } from './intl'
</script>
<h1>{$dict.dashboard.title}</h1>
マウントの intl/index.ts(package.json で #lib/* をマッピングしている場合(SvelteKit 3 など)は、$lib/intl の代わりに #lib/intl/index.js を使用します。mount と import はここにその形式を書き込み、build は built.js に書き込みます):
import { derived } from 'svelte/store'
import { locale } from '$lib/intl'
import { dictionaries } from './built.js'
import type { Locale, Dictionary } from './types'
const dict = derived(locale, ($locale) => dictionaries[$locale])
export { dict, dictionaries, locale }
export type { Locale, Dictionary }
翻訳精度を高めるためのコンテキスト
npx intl set app.welcome "Welcome" "greeting shown on homepage"
npx intl context "B2B SaaS for enterprise users"
コンテキストは context.yaml に保存され、新しいロケールを作成する際に OpenAI が使用します。
ワークフロー
npx intl add/set/unit/constを使用して翻訳を追加・更新します。複数のキーは、add --from/set --fromのファイルにまとめます。npx intlをループで呼び出してはいけません。npx intl buildを実行して JS/TS を生成します(自動実行されることもよくあります)。- コンポーネントで
dictストアをインポートします。 - テンプレートで
$dict.key.pathを使用します。
避けること
- YAML を手動で編集すること — CLI を使用してください。
npx intlのループ実行 — 呼び出しのたびにプロセス、翻訳リクエスト、ビルドが発生します。キーをファイルに書き込み、add --fromを一度だけ実行してください。- 一括追加に
const+syncを使うこと —syncは辞書全体を再翻訳します。add --fromを使用してください。 - 通常の編集で
npx intl syncを使うこと — 手動でソースを編集した後の調整にのみ使用します。代わりにadd/setを使用してください。 - BCP47 に準拠しないロケールコード —
en-US、es、pt-BRなど、有効なタグを使用してください。 - テンプレート内でフレーズを分割すること — 動的な値を辞書の接尾辞/接頭辞と連結しないでください。文全体を表す単一の
{placeholder}/!jsエントリーを使用してください。