国際化
Xingluo は中英二カ国語の UI サポートを備え、prefixDefaultLocale: false ルーティング戦略を使用して、デフォルト言語に URL プレフィックスが付かないようにしています。
ルーティング戦略
Astro の i18n 設定(astro.config.ts を参照):
tsi18n: { locales: ["zh-cn", "en"], defaultLocale: "zh-cn", routing: { prefixDefaultLocale: false }, }
重要:prefixDefaultLocale: false はローカライズされたページコピーを自動生成しません — [locale]/ ミラールートを手動で維持する必要があります。
Xingluo のアプローチ:
- ルートページ = デフォルト言語(
zh-cn)、URL プレフィックスなし(例:/posts/welcome/) src/pages/[locale]/が全ページをミラーリング。getStaticPathsはgetLocaleParams()を使用して非デフォルトロケールのみを生成(例:/en/posts/welcome/)- ミラーページも薄いラッパーであり、同じ View コンポーネントをレンダリングロジックに再利用
/ → ホーム (zh-cn) /en/ → ホーム (en) /posts/welcome/ → 投稿 (zh-cn) /en/posts/welcome/ → 投稿 (en)
Locale 解決
View コンポーネントは Astro.currentLocale を自動解決に使用します:
- ルートページ →
zh-cn [locale]セグメントページ →en(またはその他の非デフォルトロケール)
コンポーネント層でのパスチェックは不要です。useTranslations(locale) が対応する文字列を直接取得します。
i18n モジュール構造
| ファイル | 責務 |
|---|---|
index.ts | import.meta.glob("./lang/*.ts", {eager:true}) が言語をロード。DEFAULT_LOCALE、LOCALES、useTranslations(locale)、tplStr をエクスポート |
types.ts | 完全な UIStrings インターフェース(ローカライズする全文字列) |
routing.ts | getLocalePrefix、withLocale(path, locale)、parseLocaleFromPath(pathname) |
staticPaths.ts | NON_DEFAULT_LOCALES、getLocaleParams() |
format.ts | tplStr(template, vars) — {{key}} プレースホルダー置換 |
lang/zh-cn.ts | 簡体字中国語(デフォルト) |
lang/en.ts | 英語 |
UIStrings 構造
UIStrings インターフェースは、ローカライズするすべての UI 文字列をグループ化して定義します:
nav: ナビゲーション(home/posts/tags/about/archives/search/rss)post: 投稿(日付、共有、タグ、戻る、編集、目次、コードコピー、画像ライトボックスなど)pagination: ページネーションhome: ホームページ(ソーシャルリンク、注目、最新)archives: アーカイブ(カウント、月)footer: フッター(著作権)pages: ページタイトルと説明a11y: アクセシビリティラベルlanguageSwitcher: 言語切り替えnotFound: 404comments: コメントセクション
テンプレート文字列
プレースホルダー付きの文字列は {{key}} を使用し、tplStr で置換されます:
tsimport { tplStr } from "@/i18n"; // archives.postCount = "{{count}} posts" tplStr(t.archives.postCount, { count: 5 }); // "5 posts"
SEO 多言語宣言
Layout.astro の head が出力:
- 各言語の
<link rel="alternate" hreflang="..." href="..."> x-defaultはデフォルト言語を指す- sitemap 統合が i18n 設定を有効にして hreflang を自動生成
- 非デフォルトロケールの投稿は canonical がデフォルトロケールのオリジナルを指す(重複コンテンツペナルティを回避。詳細は SEO を参照)
言語の追加
例:日本語 ja を追加する場合:
astro.config.ts:i18n.localesに"ja"を追加し、sitemapi18n.localesに"ja": "ja-JP"マッピングを追加src/i18n/lang/:完全なUIStringsをエクスポートするja.tsを作成(en.tsをコピーして翻訳)src/i18n/staticPaths.ts:NON_DEFAULT_LOCALESが自動的にjaを含める(LOCALESから計算)src/pages/[locale]/:ミラーページが自動的にjaバージョンを生成(getLocaleParamsがカバー)- 言語切り替え:
zh-cn.tsとen.tsのlanguageSwitcher.namesに"ja": "日本語"を追加
コンテンツレベルの翻訳
Xingluo は locale と translationKey のフロントマターフィールドを介して、投稿の多言語コンテンツをサポートします。
基本的な使い方
- デフォルト言語の投稿:
src/content/posts/<slug>.mdに配置し、translationKeyをグループ識別子として設定:
yaml# src/content/posts/welcome.md --- title: "欢迎来到星罗" locale: zh-cn translationKey: welcome-to-xingluo tags: [公告, Astro] ---
- 翻訳:言語サブディレクトリ
src/content/posts/<locale>/<slug>.mdに配置し、同じtranslationKeyを使用:
yaml# src/content/posts/en/welcome.md --- title: "Welcome to Xingluo" locale: en translationKey: welcome-to-xingluo tags: [announcement, Astro] ---
ディレクトリ構造
src/content/posts/ ├── welcome.md # デフォルト言語 (zh-cn) ├── en/ │ └── welcome.md # 英語翻訳 ├── ja/ │ └── welcome.md # 日本語翻訳 └── another-post.md # 独立した投稿 (translationKey なし)
- 言語サブディレクトリ名は
astro.config.tsのi18n.localesの言語コードと一致する必要があります - 言語サブディレクトリは URL スラッグからフィルタリングされます(例:
/posts/welcome/、/posts/en/welcome/ではありません) translationKeyのない投稿は独立しており、言語間でリンクされません
ルーティング動作
| シナリオ | 動作 |
|---|---|
デフォルトロケールでの zh-cn 投稿へのアクセス | デフォルト言語のオリジナルをレンダリング |
| 翻訳がある非デフォルトロケール | 対応する翻訳をレンダリング |
| 翻訳がない非デフォルトロケール | デフォルト言語のオリジナルにフォールバック(同一コンテンツ、canonical が SEO を保護) |
リストの重複排除
リストページ(ホーム、投稿リスト、タグ、アーカイブ、RSS)は getPostsForLocale を使用して言語ごとに代表投稿を選択します。各翻訳グループは対象言語のカードを1つだけ表示し、同じトピックの重複エントリを防ぎます。
canonical と SEO
- 独立した翻訳がある場合:canonical は翻訳自身の URL を指し、検索エンジンが個別にインデックス可能
- 翻訳がない場合(フォールバック):canonical はデフォルト言語のオリジナルを指し、重複コンテンツペナルティを回避
- hreflang 宣言が全言語をカバーし、言語バージョン間の関係を検索エンジンに伝達
詳細は SEO を参照。
関連記事
デプロイ
1 分で読了Xingluo デプロイガイド。静的ホスティングプラットフォーム(Netlify/Vercel/GitHub Pages)、Nginx セルフホスティング、Docker、環境変数をカバーします。