Lingvit
  • Astro
  • i18n
  • ガイド

Astro の国際化:i18n ルーティング vs 自動翻訳

読了時間8分

Astro v3.5 では、ネイティブの i18n ルーティングが導入されました — /fr/、 /de/ のような URL プレフィックス、言語検出、 getRelativeLocaleUrl() などです。しっかりした 基盤ですが、ルーティングは翻訳ではありません。Astro の i18n ルーティングは訪問者をどこに送るかを示すだけで、 そこに到着したときに何が表示されるかまでは翻訳しません。この記事では、Astro の i18n が実際に提供するもの、 提供しないもの、そして実際のコンテンツ翻訳を追加する方法を解説します。

Astro の組み込み i18n ルーティングでできること

v3.5 以降、Astro は astro.config.mjs にファーストパーティの i18n 設定ブロックを提供しています。そこで ロケールを宣言すれば、すぐに URL ベースのルーティングが使えます。

// astro.config.mjs
import { defineConfig } from "astro/config";

export default defineConfig({
  i18n: {
    defaultLocale: "en",
    locales: ["en", "fr", "de", "es"],
    routing: {
      prefixDefaultLocale: false,
    },
  },
});

この設定により、Astro はロケールプレフィックス付きの URL パスを自動生成します — src/pages/fr/ 配下に置いたページは /fr/about、 /fr/pricing のように配信されます。この ルーティングレイヤーは、さらに2つの URL ヘルパーも提供します。

  • getRelativeLocaleUrl(locale, path) — サイトルートからの相対パスに、ロケールプレフィックスを付けて生成します。
  • getAbsoluteLocaleUrl(locale, path) — 同様の機能に加えて完全なオリジンを付与します。canonical タグやサイトマップに便利です。
  • サーバー(SSR)モードでの Accept-Language ヘッダーによる 言語検出 — Astro は訪問者を自動的に希望のロケールへリダイレクトできます。

できないこと:コンテンツの翻訳です。 i18n 設定ブロックを有効にしても、得られるのは URL 構造とルーティングヘルパーだけです。 /fr/about の実際のコンテンツは、 手動翻訳したコピーを含む src/pages/fr/about.astro を作成するか、 ロケールごとのエントリーを持つ Content Collections を使うかして、フランス語で書く必要があります。 ルーティングレイヤーはあくまで構造的なものです。

従来のアプローチ:ロケールごとの Content Collections

多言語対応の Astro サイトで最も一般的なパターンは、ルーティングレイヤーとロケール別のコンテンツ ディレクトリを組み合わせることです。ブログの場合、コンテンツコレクションを言語ごとに構造化します。

src/
  content/
    blog/
      en/
        introducing-our-product.mdx
        how-it-works.mdx
      fr/
        introducing-our-product.mdx   ← 手動でのフランス語翻訳
        how-it-works.mdx              ← 手動でのフランス語翻訳
      de/
        introducing-our-product.mdx   ← 手動でのドイツ語翻訳
        how-it-works.mdx              ← 手動でのドイツ語翻訳

このアプローチは、特定の条件下ではうまく機能します。サイトの規模が小さく、専任の翻訳者が各ロケール ディレクトリを担当し、コンテンツの更新頻度が低い場合です。構造は明確で、出力も監査しやすく、翻訳された ファイルはそれぞれ独自のバージョン履歴を持つ独立した成果物になります。

しかし、メンテナンスの計算は急速に不利になっていきます。5言語で20ページとなると、同期を保つべき ファイルは100個に及びます。英語版のページが更新されるたびに、他の4つのロケール版は翻訳者が追いつくまで 遅れを取ります。英語ページは書き直されたのに、フランス語版は半年前のまま — というコンテンツドリフトが、 このアプローチで最もよく起こる失敗パターンです。規模が大きくなるほど、ロケール間の整合性を保つ負担は 静かに放置されがちになります。

自動翻訳:1つのスクリプトで全言語に対応

代替となるアプローチでは、コンテンツの複製は一切不要です。Astro のレイアウトの </body> 終了タグの直前に、Lingvit の スクリプトを追加します。

---
// src/layouts/Layout.astro
---
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <slot name="head" />
  </head>
  <body>
    <slot />
    <script
      src="https://cdn.lingvit.com/widget/v1/widget.bundle.js"
      data-project-id="YOUR_PROJECT_ID"
      async
    ></script>
  </body>
</html>

これで統合は完了です。あとは Lingvit がレンダリング後の DOM を監視し、ダッシュボードで有効化した ターゲット言語に翻訳します。このアプローチには、いくつか注目すべき特性があります。

すべての Astro 出力モードに対応

静的出力(output: "static")、 サーバーレンダリング(output: "server")、 ハイブリッドモード — いずれも Lingvit が翻訳できる HTML を生成します。ウィジェットはページ読み込み後に クライアントサイドで動作するため、出力モードによる動作の違いはありません。

Astro アイランドも翻訳

React、Vue、Svelte、Solid で構築されたアイランドは、クライアントサイドでハイドレートされ、その 出力を DOM に描画します。Lingvit の MutationObserver は、アイランドがどのフレームワークで動いていても、 どのハイドレーションディレクティブ(client:load、 client:visible など)が使われていても、 表示された時点でノードを検知します。

新しいコンテンツも自動的に翻訳される

新しいブログ記事を公開したり、ランディングページを更新したりすると、次回のページ読み込み時に 翻訳版へ反映されます。更新すべきロケールファイルも、待たせる翻訳者のキューもありません。

ダッシュボードによる編集コントロール

自動翻訳された文字列は、Lingvit ダッシュボードからいつでも確認・上書きできます。上書きは保持され、 フランス語の製品名やブランド用語を修正すれば、その文字列が登場するたびに修正内容が適用されます。

Astro の i18n ルーティングと自動翻訳は組み合わせられますか?

はい。SEO を重視するサイトには、この組み合わせが推奨されるアプローチです。2つの仕組みは異なる レイヤーで動作するため、きれいに補完し合います。

Astro の組み込みルーティングは URL 構造を担当します。 /fr/about や /de/pricing のような URL は、検索エンジンが 多言語コンテンツをインデックスする際に使うものです — 各ロケールはクロール可能な独自の URL、独自の canonical、独自の hreflang シグナルを持ちます。これは 多言語 SEO の正しい基盤であり、Astro のルーティングレイヤーはそれをしっかり提供してくれます。

Lingvit はそれらの URL 内の実際のコンテンツ翻訳を担当します。手動翻訳したコピーを含む src/pages/fr/about.astro を別途 維持する代わりに、単一のソースファイルだけを保持し、Lingvit にレンダリング後の出力を自動翻訳させます。 結果として、言語ごとに SEO インデックスされた URL と、自動コンテンツ翻訳、編集コントロールが、 ソースファイルを複製することなく実現できます。

組み合わせ設定の概要

  1. astro.config.mjs の i18n ブロックで、ターゲットとする ロケールを設定します。これにより URL 構造が確立されます。
  2. src/layouts/Layout.astro の </body> 直前に、Lingvit の スクリプトタグを追加します。これがコンテンツ翻訳を担当します。
  3. ページごとに単一のソースファイルを維持します。コンテンツは1つの言語で書いて管理するだけで、 他のロケール版はすべて Lingvit が自動的に処理します。

どちらのアプローチを使うべきか

常に自動翻訳が正解とは限りません。従来のロケールファイル方式が明らかに適している場面もあります。

Astro ルーティング + ロケールファイル

  • 言語ごとに専任の翻訳者がいる小規模サイト
  • 公開後にほとんど更新されないコンテンツ
  • 文字列ごとの明示的な承認が必要な法務・規制関連のコピー
  • コミュニティが翻訳を担うオープンソースプロジェクト

Astro ルーティング + 自動翻訳

  • ロケールファイルの整合性維持が難しい大規模サイト
  • 頻繁に更新されるコンテンツ(ブログ、変更履歴、ドキュメント)
  • 専任の翻訳リソースを持たないチーム
  • i18n 未対応の既存 Astro サイトへの言語追加

よくある質問

自動翻訳は Astro のアイランドでも機能しますか?

はい。React、Vue、Svelte、Solid のアイランドはクライアントサイドでハイドレートされ、その出力を DOM に描画します。Lingvit の MutationObserver はこのコンテンツが表示されるとすぐに検知して翻訳します — アイランドがどのフレームワークを使っていても関係ありません。

Astro の静的出力(SSG)でも動作しますか?

はい。Lingvit はページ読み込み後、完全にクライアントサイドで動作します。静的出力の場合、HTML はビルド時に事前生成され、Lingvit がブラウザー内でそれを翻訳します。SSR の場合、Lingvit はハイドレーション後に動作します。Lingvit の視点からはどちらも同じように機能します。

Lingvit は Astro の組み込み i18n ルーティングとどう連携しますか?

両者は異なるレイヤーで動作します。Astro のルーティングは URL 構造(/fr/、/de/)とリダイレクトを担当します。Lingvit は実際のテキストコンテンツの翻訳を担当します。両方を組み合わせて使うことができます — ルーティングは Astro、コンテンツは Lingvit というように。

Astro の Content Collections も翻訳できますか?

はい。Content Collection のコンテンツ(MDX、Markdown)は、ビルド時に Astro によって HTML に変換されます。その HTML は、訪問者のブラウザーでページが読み込まれた際に Lingvit によって監視され、クライアントサイドで翻訳されます。