シリーズ目次 前章: 10. AstroPaperでOG画像の自動生成とSEO 次章: 12. AstroPaperのビルドとデプロイ
Table of contents
Open Table of contents
この章のねらい
AstroPaperのテンプレートには、Recent Posts、Search、Back to top といった英語のUI文言が入っています。日本語で運用するなら、当然ここを直したくなります。仕組みと変更手順、それから翻訳ファイルだけでは変わらない部分への対処を見ていきます。
文言はどこにあるのか
UI文言は src/i18n/ にまとまっています。
src/i18n/
├── index.ts # ロケールに応じて文言を選ぶ
├── format.ts # {{変数}} を差し替える
├── types.ts # 文言の型定義
└── lang/
└── en.ts # 英語の文言
lang/en.ts の中身は、用途ごとにグループ分けされたオブジェクトです。
export default {
nav: {
home: "Home",
posts: "Posts",
tags: "Tags",
about: "About",
archives: "Archives",
search: "Search",
},
post: {
publishedAt: "Published at",
updatedAt: "Updated",
sharePostOn: "Share this post on {{platform}}",
// ...
},
// ...
} satisfies UIStrings;src/i18n/lang/en.ts
グループは次のように分かれています。
| グループ | 対象 |
|---|---|
nav | ヘッダーのメニュー |
post | 記事詳細ページの各種ラベル |
pagination | ページ送り |
home | トップページの見出し |
footer | フッター |
pages | 一覧系ページのタイトルと説明 |
a11y | 読み上げソフト向けのラベル |
notFound | 404ページ |
グループ名と、画面のどこを受け持つかを対応させると次のようになります。
文言が選ばれる流れ
選択を担当しているのは src/i18n/index.ts です。
const modules = import.meta.glob<{ default: UIStrings }>("./lang/*.ts", {
eager: true,
});
const translations: Record<string, UIStrings> = {};
for (const [path, mod] of Object.entries(modules)) {
const locale = path.slice("./lang/".length, -".ts".length);
translations[locale] = mod.default;
}
export function useTranslations(locale: string = "en"): UIStrings {
return translations[locale] ?? translations["en"];
}src/i18n/index.ts
やっていることは3つです。
import.meta.globでlang/内のファイルをすべて読み込む- ファイル名がそのままロケール名になる(
ja.ts→ja) - 該当する言語がなければ英語にフォールバックする
つまり、ファイルを1つ足すだけで新しい言語が登録される設計です。一覧に追記するような作業は不要です。
ここで引っかかります。フォールバックはファイル単位です。translations[locale] が見つからなければ丸ごと英語になりますが、ja.ts がある状態で個々のキーが欠けていても、そこだけ英語で補われることはありません。欠けたキーは実行時に undefined になり、画面には何も出ません。一部だけ翻訳しておく、という運用はできません。
各ページでは、次のように呼び出されています。
const locale = Astro.currentLocale ?? config.site.lang;
const t = useTranslations(locale);
Astro.currentLocale はAstroが判定した現在のロケールです。取得できない場面では、設定の site.lang が使われます。
変数の差し替え
一部の文言には {{platform}} のような差し込み位置があります。
sharePostOn: "Share this post on {{platform}}",src/i18n/lang/en.ts
これを実際の値に置き換えるのが tplStr です。
export function tplStr(
template: string,
vars: Record<string, string | number>
): string {
return template.replace(/\{\{(\w+)\}\}/g, (_, key: string) => {
const value = vars[key];
return value !== undefined && value !== null ? String(value) : "";
});
}src/i18n/format.ts
言語によって語順が変わっても困らないよう、埋め込み位置を文中の好きなところに置けるようになっています。
日本語にする手順
1. 翻訳ファイルを作る
src/i18n/lang/en.ts をコピーして src/i18n/lang/ja.ts を作り、値を日本語に書き換えます。
import type { UIStrings } from "../types";
export default {
nav: {
home: "ホーム",
posts: "記事一覧",
tags: "タグ",
about: "このサイトについて",
archives: "アーカイブ",
search: "検索",
},
post: {
publishedAt: "公開日",
updatedAt: "更新日",
sharePostIntro: "この記事を共有する:",
sharePostOn: "{{platform}}でこの記事を共有する",
sharePostViaEmail: "メールでこの記事を共有する",
tagLabel: "タグ",
backToTop: "ページ先頭へ戻る",
goBack: "戻る",
editPage: "このページを編集",
previousPost: "前の記事",
nextPost: "次の記事",
},
// 以下、すべてのグループを同様に翻訳する
} satisfies UIStrings;src/i18n/lang/ja.ts
2. 型チェックに頼る
末尾の satisfies UIStrings を落とさないでください。これは「このオブジェクトは UIStrings の形を満たしている」と宣言する記法で、項目を書き忘れるとエラーになります。
pnpm astro check
これで翻訳漏れがその場で出ます。手作業で見比べる必要はありません。
3. 設定の言語を合わせる
site: {
lang: "ja",
},astro-paper.config.ts
これで <html lang="ja"> になり、useTranslations にも "ja" が渡ります。
4. Astroのi18n設定を確認する
astro.config.ts には、Astro本体のi18n設定があります。
i18n: {
locales: ["ja"],
defaultLocale: "ja",
routing: {
prefixDefaultLocale: false,
},
},astro.config.ts
locales:対応する言語の一覧defaultLocale:既定の言語prefixDefaultLocale: false:既定言語のURLに言語コードを付けない
false なら、URLは /posts/ のままです。単一言語のサイトはこれでいいので、触らないでください。
true にすると、getRelativeLocaleUrl が生成するリンクが /ja/posts/ のような接頭辞付きになります。ただし設定を変えるだけでは動きません。Astroのルーティングはファイルベースなので、src/pages/posts/ などを src/pages/ja/posts/ へ移して、実際にそのURLのページを生成させる必要があります。移さずに true にすると、リンク先にページがなくて404です。
locales に書いた言語コードと src/i18n/lang/ のファイル名は、必ず対応させてください。
ここまでの4つを順に済ませれば、UI文言は日本語になります。
翻訳ファイルで変わらないもの
ja.ts を作っただけでは変わらない部分があります。
日付の表示形式
日付は src/components/Datetime.astro が組み立てています。
const date = datetime.format("D MMM, YYYY");src/components/Datetime.astro
2 Aug, 2026 のような英語式の表記になります。日本語式にしたければ、この書式を書き換えます。
const date = datetime.format("YYYY年M月D日");
dayjs の書式記号で指定します。月名を日本語で出したい場合は、dayjs の日本語ロケールを読み込む必要があります。
なお、アーカイブページの月名は Intl.DateTimeFormat を使っており、site.lang に応じて自動で切り替わります。こちらは設定だけで日本語になります。
トップページの文章
src/pages/index.astro の冒頭にある紹介文は、コードに直接書かれています。翻訳ファイルではどうにもならないので、ファイルを開いて自分の言葉に置き換えてください。
<h1 class="my-4 inline-block text-4xl font-bold sm:my-8 sm:text-5xl">
Mingalaba
</h1>src/pages/index.astro
見出しの文言もここにあります。
固定ページと記事
src/content/pages/about.md と各記事は、当然ながら自分で書くものです。翻訳の仕組みとは関係ありません。
この3か所は、それぞれ別のファイルを直接編集する必要があります。
複数言語で運用する場合
同じサイトを複数言語で公開したい場合は、次の作業が追加で必要になります。
astro.config.tsのlocalesに言語を追加するsrc/i18n/lang/に言語ごとのファイルを置く- 記事そのものを言語ごとに用意し、URLで切り分ける
- 言語を切り替えるUIを自分で追加する
READMEの表現は i18n ready、つまり多言語対応の準備ができている、です。多言語サイト機能が完成しているとは書いていません。UI文言の切り替え基盤だけが用意されていて、その上の記事の多言語運用は自分で組み立てる。そういう線引きです。
どこまでが用意されていて、どこからが自分の仕事なのかを分けておきます。
URLの組み立てには、テーマ内でも使われている getRelativeLocaleUrl が使えます。Astroが提供する関数で、設定に応じた言語接頭辞を自動で付けてくれます。
import { getRelativeLocaleUrl } from "astro:i18n";
const url = getRelativeLocaleUrl(locale, "posts");
また、src/utils/withBase.ts には接頭辞を取り除く補助関数も用意されています。
export function stripLocale(pathname: string, locale: string): string {
const prefix = `/${locale}`;
if (pathname === prefix) return "/";
if (pathname.startsWith(`${prefix}/`)) return pathname.slice(prefix.length);
return pathname;
}src/utils/withBase.ts
作業チェックリスト
日本語化を一通り終えるための確認項目です。
| 作業 | 対象 |
|---|---|
| UI文言の翻訳 | src/i18n/lang/ja.ts |
| 言語設定 | astro-paper.config.ts の site.lang |
| ロケール宣言 | astro.config.ts の i18n |
| 日付の書式 | src/components/Datetime.astro |
| トップページの紹介文 | src/pages/index.astro |
| 「このサイトについて」 | src/content/pages/about.md |
| タイムゾーン | astro-paper.config.ts の site.timezone |
| 翻訳漏れの確認 | pnpm astro check |
要点
- UI文言は
src/i18n/lang/にあり、ファイルを1つ追加するだけで新しい言語として登録される。 - 英語へのフォールバックは「言語ファイルごと存在しない場合」に限られ、ファイル内のキー不足は補われないため、翻訳は全項目そろえる必要がある。
satisfies UIStringsにより項目の書き忘れが型エラーとして検出されるので、pnpm astro checkで翻訳漏れを確認できる。- 日付の書式やトップページの紹介文は翻訳ファイルの外にあり、該当ファイルを直接編集する必要がある。
- i18n ready はUI文言の切り替え基盤が整っている状態を指す。記事の多言語運用は自分で設計する。
参考資料
- テンプレート同梱ソース
src/i18n/index.ts/format.ts/types.ts— 文言の選択と差し替え - テンプレート同梱ソース
src/i18n/lang/en.ts— 翻訳対象の全項目 - テンプレート同梱ソース
src/components/Datetime.astro— 日付の書式とタイムゾーン変換 - テンプレート同梱ソース
src/utils/withBase.ts— ロケール接頭辞の除去 - Astro: Internationalization (i18n) Routing —
i18n設定とgetRelativeLocaleUrl - Astro: import.meta.glob — ファイルの一括読み込み
- Day.js ドキュメント — 日付の書式記号
シリーズ目次 前章: 10. AstroPaperでOG画像の自動生成とSEO 次章: 12. AstroPaperのビルドとデプロイ