Svelte i18n vs 自動翻訳:どちらを使うべきか?
SvelteKit には、基本的な URL ルーティング以外の組み込み i18n 機能がありません。主な選択肢は 2つです。文字列抽出ライブラリ(svelte-i18n または Paraglide-JS)を使うか、DOM レベルの自動翻訳を 使うか。どちらを選ぶべきかは、プロジェクトのスケジュール、チーム規模、コンテンツの更新頻度に よって決まります。
文字列抽出アプローチ:svelte-i18n と Paraglide-JS
svelte-i18n は、Svelte エコシステムで最も広く使われている i18n ライブラリです。おなじみのメッセージファイル形式を採用しており、翻訳をロケールごとに キー付けされた JSON ファイルに保存し、テンプレート内ではリアクティブな Svelte ストアに 裏付けられた $_() 構文で参照します。
// src/lib/i18n.js
import { addMessages, init, getLocaleFromNavigator } from 'svelte-i18n'
import en from './locales/en.json'
import fr from './locales/fr.json'
addMessages('en', en)
addMessages('fr', fr)
init({ fallbackLocale: 'en', initialLocale: getLocaleFromNavigator() })
Svelte のテンプレートでは、$_ ストアをインポートし、関数として呼び出します。
<script>
import { _ } from 'svelte-i18n'
</script>
<h1>{$_('home.title')}</h1>
<p>{$_('home.description')}</p>
inlang による Paraglide-JS は異なるアプローチを取ります。コンパイル時に 型安全なメッセージ関数をロケールファイルから生成する仕組みです。これにより、あらゆる 翻訳キーで IDE の自動補完が効き、存在しないキーを参照するとビルドエラーになります。 比較的新しいですが、より強い保証を求めるチームの間で SvelteKit コミュニティで 急速に採用が広がっています。
両ライブラリとも基本的なワークフローは同じです。コンポーネント内のすべての文字列を ロケール JSON ファイルに抽出し、言語ごとに1ファイルを維持し、コピーが変わるたびに それらのファイルを更新し、複数形や埋め込みをメッセージ構文で明示的に処理します。 中規模の SvelteKit アプリでは、初期セットアップに通常1〜3日かかります——しかも それは翻訳内容を実際に埋める前の話です。
自動翻訳アプローチ
もう一つの方法は、コンポーネントレベルではなく DOM レベルで処理することです。 src/app.html の </body> の直前に スクリプトタグを1つ追加するだけで、あとは Lingvit が処理します。
<!-- src/app.html -->
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
<script src="https://cdn.lingvit.com/widget.bundle.js"
data-project-id="YOUR_PROJECT_ID"></script>
</body>
Lingvit の MutationObserver は DOM の変化を監視し、テキストノードが現れるたびに翻訳します。 これは SvelteKit のリアクティビティモデル全体をカバーします。
- →ルート遷移。 SvelteKit のクライアントサイドナビゲーションは DOM 内の ページ本体を置き換えます。MutationObserver は新しいコンテンツを即座に検知し、 ユーザーの目に触れる前に翻訳します。
- →リアクティブなストア更新。 Svelte のストアが変化してカウンター、 取得済みリスト、条件付きブロックなどの DOM 更新を引き起こすと、新しいノードは 自動的に翻訳されます。
- →
$derived値。 Svelte 5 のルーンベースのリアクティビティも、結局は DOM に書き込みます。Lingvit は その結果生じる変化を監視するだけなので、リアクティブプリミティブの種類は関係ありません。 - →文字列抽出もロケールファイルも不要。 新しいコンテンツは DOM に現れた 瞬間に翻訳されます。コピーが変わってもソース管理上で更新するものは何もありません。
コードに触れることなく特定の文字列に人によるレビュー済み翻訳を反映させたい場合は、 ダッシュボードから編集による上書きが可能です。
両者の比較
2つのアプローチは、実務上重要なあらゆる点で異なります。
セットアップ時間
既存の SvelteKit アプリに svelte-i18n や Paraglide-JS を追加するには、テキストを 描画するすべてのコンポーネントに手を入れ、リテラル文字列を $_('key') 呼び出しに置き換え、ロケールファイルを構築する必要があります。中規模のアプリでは これは複数日にわたる作業です。Lingvit の追加はスクリプトタグ1つとガイド付き セットアップフローで完結し、実際の所要時間はアプリによって異なります。
継続的な保守
文字列抽出では、コピーを変更するたびにすべてのロケールファイルを更新する必要が あります。1つでも見落とすと、その言語は静かに英語にフォールバックします。自動翻訳 には継続的な保守がほとんど不要です。新しい文字列は開発者の作業なしで初回描画時に 処理されます。
開発者体験
Paraglide-JS は型安全な翻訳キーと IDE の自動補完を提供します——すべての文字列が 計画的に管理される製品を構築しているなら、これは本当に優れた DX です。マーケティング サイトや変化の速い SaaS の UI では、あらゆる場所でリテラル文字列を関数呼び出しに 置き換えることは、開発のイテレーションを遅らせる摩擦になります。Lingvit は Svelte コンポーネントへの変更を一切必要としません。
SEO
どちらのアプローチも、SEO フレンドリーなロケール URL(/fr/、 /de/)をサポートできます。 Lingvit は動的にレンダリングされるコンテンツも自動で処理します——SvelteKit が クライアントサイドナビゲーションや非同期データ経由で挿入する翻訳済みテキストも、 追加設定なしで検知されます。
コントロール
文字列抽出はキー単位のコントロールを提供します。すべての翻訳がソース管理に保存された 明示的な決定です。自動翻訳はダッシュボードレベルのレビューを提供します。コードに 触れることなく、Lingvit のインターフェースから個々の文字列を確認・上書きできます。 どちらのレベルのコントロールが必要かは、コンテンツのリスクプロファイルによって 異なります。
svelte-i18n や Paraglide-JS を選ぶべきケース
コンパイル時の型安全性が必要な場合
Paraglide-JS は、ロケールファイルから型付きメッセージ関数を生成します。チームが ビルド時に不足している翻訳キーを検出することを重視し、すべてのキーで IDE の 自動補完を求めているなら、このコンパイル時アプローチは本当の意味で生産性を高めます ——特に複数の開発者がコピーに触れる大規模なチームでは効果的です。
翻訳者がロケールファイルで作業する場合
Crowdin や Weblate、あるいは JSON ロケールファイルと連携する TMS を使う確立された 翻訳ワークフローがすでにあるなら、svelte-i18n は自然に馴染みます。ロケール JSON 形式は、プロフェッショナルな翻訳ツールにとって共通言語です。
公開前にすべての文字列をレビューする必要がある場合
法務、医療、政府関連のアプリケーションでは、翻訳された文字列がすべて本番環境に 届く前に明示的な承認を必要とすることがよくあります。文字列抽出は、キー単位の 明示的な監査証跡を提供します——翻訳は、人がロケールファイルのエントリを承認した 時点で初めて公開されます。
i18n 専任のエンジニアリングリソースがある場合
プロダクトの進化に合わせて複数言語のロケールファイルを正確に維持するには、 継続的なエンジニアリングの注意が必要です。翻訳を最新に保つことを職務とする人材が いれば、この負荷は管理可能です。そうした担当者がいない場合、ロケールファイルは プロダクトから取り残されがちです。
自動翻訳を選ぶべきケース
今すぐ多言語対応が必要な場合
既存の SvelteKit アプリケーションに svelte-i18n を後付けするには、テキストを描画 するすべてのコンポーネントに手を入れる必要があります。DOM ベースの翻訳ウィジェット なら、スクリプトタグを1つ変更するだけで済みます——コンポーネントの書き直しも、 ロケールファイルの構築も、ビルドパイプラインの変更も不要です。
コンテンツが頻繁に更新される場合
毎週更新されるブログ、マーケティングサイト、SaaS の UI は、文字列抽出との相性が 良くありません——コンテンツが変わるたびにすべてのロケールファイルを更新するか、 一部の言語で古いコピーが表示されることを受け入れるかのどちらかになります。自動翻訳 は、開発者の作業なしで新しいコンテンツを初回描画時に処理します。
i18n 専任のリソースがない場合
ほとんどのプロダクトチームには i18n エンジニアがいません。担当者がいなければ、 ロケールファイルには不足キー、古い文字列、未翻訳のプレースホルダーといった負債が 急速に蓄積します。自動翻訳は保守の負担を完全になくします——翻訳レイヤーは DOM の 変化に合わせて自ら最新の状態を保ちます。
既存の SvelteKit アプリに言語を追加する場合
すでにアプリが存在していて、新たな要件として多言語対応を追加するなら、文字列抽出を 後付けするコストは、これまでに書いたコンポーネントの数に比例します。Lingvit は 既存の Svelte コンポーネントへの変更を一切必要としません——スクリプトタグを追加し、 ダッシュボードで言語を設定するだけです。
よくある質問
- 自動翻訳は SvelteKit のファイルベースルーティングに対応していますか?
- はい。SvelteKit のクライアントサイドナビゲーションは DOM 内のページコンテンツを置き換えますが、Lingvit の MutationObserver がこれを即座に検知します。ルートが変わるたびに、新しいコンテンツに対して翻訳処理が実行されます。
- URL ルーティングには svelte-i18n を、コンテンツには自動翻訳を使うことはできますか?
- はい。2つのアプローチは異なるレイヤーで動作します。svelte-i18n や Paraglide-JS をロケール対応の URL ルーティング(/fr/、/de/)専用に使い、テキストコンテンツの翻訳はすべて Lingvit に任せることができます。
- Svelte のストアから派生したコンテンツにも対応していますか?
- はい。Svelte のストア更新がリアクティブな DOM の変更を引き起こすと、Lingvit はその結果生じた DOM の変化を検知し、新しいテキストノードを翻訳します。
- 自動翻訳は複数形や埋め込み値をどう処理しますか?
- Lingvit は、Svelte が変数を埋め込み複数形を解決した後の、最終的にレンダリングされた文字列を翻訳します。動的な文字列のために翻訳キーを書く必要はなく、完全にレンダリングされたテキストがそのまま翻訳対象になります。
関連ガイド
SvelteKit アプリに言語を追加する
SvelteKit、Svelte 5 のルーン、リアクティブなストアに対応。スクリプトタグ1つで、 コンポーネントの書き直しは不要です。