SvelteKitで多言語対応ブログを簡単に構築する方法

こんにちは！SvelteKitは軽量でパワフルなフレームワークですが、多言語対応（i18n）を実装する方法はあまり知られていません。この記事では、SvelteKitと**sveltekit-i18n**ライブラリを使って、ブログを日本語、英語、ベトナム語に対応させる方法を解説します。コード例を交えながら、簡単に多言語対応を実現しましょう！

---

## なぜ多言語対応が必要か？

ブログの読者層を広げるには、複数の言語でコンテンツを提供することが重要です。例えば、技術ブログを英語やベトナム語でも読めるようにすれば、グローバルなコミュニティにリーチできます。SvelteKitには多言語対応のための組み込み機能はありませんが、**sveltekit-i18n**を使うことで、ルーティングや翻訳を簡単に管理できます。

---

## プロジェクトのセットアップ

新しいSvelteKitプロジェクトを作成します：

```bash
npm create svelte@latest i18n-blog
cd i18n-blog
npm install
```

**sveltekit-i18n**をインストール：

```bash
npm install sveltekit-i18n
```

---

## 多言語対応の設定

### 1. 翻訳ファイルの準備
`src/lib/i18n`フォルダを作成し、翻訳ファイルを定義します。`ja.json`（日本語）：

```json
{
  "common": {
    "welcome": "ようこそ！",
    "blog": "ブログ",
    "about": "私について"
  },
  "home": {
    "title": "私の技術ブログ",
    "description": "SvelteKitで作られたブログです。"
  }
}
```

`en.json`（英語）：

```json
{
  "common": {
    "welcome": "Welcome!",
    "blog": "Blog",
    "about": "About"
  },
  "home": {
    "title": "My Tech Blog",
    "description": "A blog built with SvelteKit."
  }
}
```

`vi.json`（ベトナム語）：

```json
{
  "common": {
    "welcome": "Chào mừng!",
    "blog": "Blog",
    "about": "Giới thiệu"
  },
  "home": {
    "title": "Blog Công Nghệ Của Tôi",
    "description": "Một blog được xây dựng bằng SvelteKit."
  }
}
```

### 2. i18nの初期化
`src/lib/i18n/index.ts`を作成：

```ts
import { init, register, getLocaleFromNavigator } from 'sveltekit-i18n';

register('ja', () => import('./ja.json'));
register('en', () => import('./en.json'));
register('vi', () => import('./vi.json'));

const config = {
  fallbackLocale: 'ja',
  initialLocale: getLocaleFromNavigator()
};

export const { t, locale, locales, loading } = init(config);
```

- **解説**：
  - `register`で各言語の翻訳ファイルを登録。
  - `fallbackLocale`を日本語に設定。
  - `getLocaleFromNavigator`でブラウザの言語をデフォルトに。

### 3. 多言語ルーティング
SvelteKitの動的ルートを使って、言語をURLに組み込みます。`src/routes/[lang]/+layout.svelte`を作成：

```svelte
<script>
  import { t, locale } from '$lib/i18n';
  import { AppBar, AppShell } from '@skeletonlabs/skeleton';
  import { goto } from '$app/navigation';
  export let data;

  function changeLanguage(newLang) {
    locale.set(newLang);
    goto(`/${newLang}${data.pathname.replace(/^\/[^/]+/, '')}`);
  }
</script>

<svelte:head>
  <title>{$t('home.title')}</title>
  <meta name="description" content={$t('home.description')} />
</svelte:head>

<AppShell>
  <svelte:fragment slot="header">
    <AppBar background="bg-primary-500">
      <svelte:fragment slot="lead">
        <h1 class="text-2xl font-bold text-white">{$t('home.title')}</h1>
      </svelte:fragment>
      <svelte:fragment slot="trail">
        <a href="/{$locale}/" class="btn variant-ghost-surface">{$t('common.welcome')}</a>
        <a href="/{$locale}/blog" class="btn variant-ghost-surface">{$t('common.blog')}</a>
        <a href="/{$locale}/about" class="btn variant-ghost-surface">{$t('common.about')}</a>
        <select bind:value={$locale} on:change={(e) => changeLanguage(e.target.value)} class="btn variant-ghost-surface">
          <option value="ja">日本語</option>
          <option value="en">English</option>
          <option value="vi">Tiếng Việt</option>
        </select>
      </svelte:fragment>
    </AppBar>
  </svelte:fragment>
  <slot />
</AppShell>
```

`src/routes/[lang]/+layout.server.ts`で言語を検証：

```ts
import { redirect } from '@sveltejs/kit';

export const load = ({ params, url }) => {
  const validLocales = ['ja', 'en', 'vi'];
  if (!validLocales.includes(params.lang)) {
    throw redirect(302, '/ja' + url.pathname);
  }
  return {
    lang: params.lang,
    pathname: url.pathname
  };
};
```

### 4. ホームページの実装
`src/routes/[lang]/+page.svelte`を作成：

```svelte
<script>
  import { t } from '$lib/i18n';
  import { Card } from '@skeletonlabs/skeleton';
</script>

<div class="container mx-auto p-8">
  <Card class="p-6">
    <h1 class="h1 mb-4">{$t('home.title')}</h1>
    <p class="text-lg">{$t('home.description')}</p>
  </Card>
</div>
```

### 5. 動作確認
プロジェクトを起動：

```bash
npm run dev
```

以下のURLを試す：
- `http://localhost:5173/ja`：日本語のホームページ。
- `http://localhost:5173/en`：英語のホームページ。
- `http://localhost:5173/vi`：ベトナム語のホームページ。

言語セレクターで言語を切り替えると、URLとコンテンツが即座に更新されます。Reactの**react-i18next**では、ルーティングと翻訳の統合に追加の設定が必要ですが、SvelteKitとsveltekit-i18nはシンプルで直感的です。

---

## やってみよう！（チャレンジ）
ブログ記事ページ（例：`/ja/blog`）を追加し、各記事のタイトルと本文を翻訳してみましょう！翻訳ファイルに以下のような構造を追加：

```json
{
  "blog": {
    "post1": {
      "title": "SvelteKitの基本",
      "content": "SvelteKitの基本を学びましょう。"
    }
  }
}
```

また、Svelteのストアを使って、言語切り替え時にアニメーション（例：`transition:fade`）を適用してみてください。以下は例：

```svelte
<div transition:fade={{ duration: 300 }}>
  <h1 class="h1">{$t('home.title')}</h1>
</div>
```

---

## まとめ
この記事では、**sveltekit-i18n**を使ってSvelteKitで多言語対応ブログを構築しました。日本語、英語、ベトナム語を簡単に切り替えられるUIを、**Skeleton UI**でモダンに仕上げました。Reactのi18nライブラリと比べ、SvelteKitのシンプルなルーティングと翻訳管理は、少ないコードで柔軟な実装が可能です。

この記事が役に立ったと思ったら、**LGTM**や**ストック**していただけると嬉しいです！多言語対応で困った点やアイデアがあれば、コメントで教えてください。また会いましょう！