inlangを使ってSvelteKitを多言語化する
はじめに
こんにちは、株式会社Liquitousのエンジニアのかずうみです。
本日はSvelte Advent Calendar 2023の16日目ということで、inlangを用いた、SvelteKitアプリケーションの多言語化(i18n)対応を行っていきます。
inlangとは
inlangは、多言語化のためのアプリケーションや、プラグイン、ソリューションといったエコシステムが揃った基盤です。
今回はinlangで開発されているParaglide JS(i18nライブラリ)、Fink(翻訳文のエディタ)、VSCode拡張(入れるとめちゃくちゃ便利になる)を使っていきます。
多言語化ハンズオン
このセクションでは、公式ページのガイド「Build a Global Svelte App」をベースに実際にコードを書いてみます。
SvelteKitプロジェクトを作成する
pnpm create svelte@latest sveltekit-inlang
cd sveltekit-inlang
pnpm install
git init
Paraglideを初期化する
CLIで簡単に初期化できます。
npx @inlang/paraglide-js@latest init
VSCodeを使っているかなどの質問があるので、今回はYesを選択しました。
インストールが終わると、パッケージのインストールに加えてproject.inlang/settings.json
というファイルが作成されます。今回はプロジェクトで日本語をメインに日英対応するように設定します。
+"sourceLanguageTag": "ja",
-"sourceLanguageTag": "en",
"languageTags": [
+ "ja",
"en"
],
SvelteKit用に設定を行う
SvelteKit使用時にParaglideの開発体験が上がる追加の設定を行います。
Viteのプラグインを追加
Viteプラグインを追加することで、翻訳文を勝手にコンパイルしてくれるようになります。
pnpm i -D @inlang/paraglide-js-adapter-vite
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
+import { paraglide } from "@inlang/paraglide-js-adapter-vite"
export default defineConfig({
plugins: [
sveltekit(),
+ paraglide({
+ project: "./project.inlang",
+ outdir: "./src/paraglide",
+ }),
],
})
エイリアスの設定
kit: {
adapter: adapter(),
+ alias: {
+ $paraglide: "./src/paraglide",
+ }
}
翻訳文の追加と使用
翻訳文を手動で追加する方法と、拡張機能を使用して追加する方法、そして翻訳文を使用する方法を説明します。
翻訳文を手動で追加する
デフォルトの翻訳ファイルの置き場所はmessages/{lang}.json
となっています。
次のようなファイルを作成してください。
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"helloWorld": "こんにちは世界",
"greeting": "{name}さん、こんにちは"
}
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"hello_world": "Hello World",
"greeting": "Hello {name}"
}
このまま手動で編集することもできますが、VSCodeをお使いであればぜひ拡張機能を使うことをお勧めします。
翻訳文を拡張機能を使用して追加する
-
まず拡張機能をインストールし、その後VSCodeを再読み込みしてください。
https://marketplace.visualstudio.com/items?itemName=inlang.vs-code-extension -
適当なSvelteファイル(
src/routes/+page.svelte
など)を開く。 -
追加したい自然言語の箇所を選択状態にし、
Command
キーを押しながら.
を入力する。
このような画面が現れます。 -
Inlang: Extract message を選択し、適当なIDを入力してください。
-
置き換え方法を選びます。今回はテンプレートの中なので{}に囲まれたオプションを選択しました。
-
これで、
messages/ja.json
を確認すると、設定したIDで訳文が追加されます。
翻訳文を使用する
呼び出しの際には、次のようなコードになります。
import * as m from "$paraglide/messages"
m.helloWorld()
m.greeting({ name: "太郎" })
それぞれの翻訳文は関数として、現在の言語で翻訳文を返します。また、翻訳文にパラメータを渡す必要がある場合、TypeScriptによって強制してもらえます。
また、現在の言語を変更するには、$paraglide/runtime
からエクスポートされたsetLanguageTag
関数を使用しますが、翻訳文はリアクティブでないため、言語変更の度に再レンダリングする必要があります。
サブドメインを使ってユーザーの言語設定を行う
今回はja.example.com、en.example.comのように、サブドメイン部分に設定言語情報を入れます。
なお、公式のガイドではパスを使っています。必要に応じてご参考ください。
import { sourceLanguageTag, setLanguageTag, type AvailableLanguageTag } from '$paraglide/runtime';
export const handle = async ({ event, resolve }) => {
// URLから言語を取得し、なければデフォルト言語を使う
const lang = event.request.headers.get('host')?.split('.')[0] as AvailableLanguageTag ?? sourceLanguageTag;
// 言語をセット
setLanguageTag(lang);
// サーバーサイドで扱うためにlocalsにセット
event.locals.lang = lang;
return await resolve(event);
}
export const load = async ({ locals }) => {
return {
lang: locals.lang
}
}
<script lang="ts">
export let data;
import { setLanguageTag } from "$paraglide/runtime";
$: setLanguageTag(data.lang);
</script>
<slot />
+interface Locals {
+ lang: import("$paraglide/runtime").AvailableLanguageTag;
+}
SEO用の調整
+<html lang="%lang%">
-<html lang=>
+ return await resolve(event, {
+ transformPageChunk({ done, html }) {
+ // レンダリングの最後にのみ実行する
+ if (done) {
+ return html.replace("%lang%", lang)
+ }
+ },
+ })
以上でハンズオンは終了となります。
訳文の調整
アプリケーションにおける多言語化の課題の1つに、訳文の管理があります。
Finkを使うと、使いやすいUIで編集や警告表示を確認したり、変更履歴を全てGitでの管理に集められます。
Finkを使う
- inlang Editor
- URLの入力欄に、publicまたはアクセス権限を持つGitHubのレポジトリを入力してください。
- 欄に翻訳文を入力してください。機械翻訳を使うこともできます。
- Pushを押すだけでGitに変更を反映することもできます。
終わりに
SvelteKitとinlangを組み合わせた多言語対応に関する記事は以上です。
今回のプロジェクトのレポジトリを記載しておきます。
何か少しでもご参考になれば幸いです。
inlang自体もまだリリースしたてでかつSvelteKitにもi18n関係の機能が追加されるという噂もあるので、引き続きウォッチしていきたいと思っています。
それでは、お読みいただきありがとうございました。
Discussion