シリーズ目次 / 前章: 04. Astroのレイアウトとスタイリング / 次章: 06. Astro コンテンツコレクションで記事を管理する
Table of contents
Open Table of contents
この章のねらい
どのURLにアクセスすると、どのページが表示されるか。この対応づけをルーティングと呼びます。
Astroのルーティングは、ファイルの置き場所がそのままURLになるという規則ひとつで成り立っています。設定ファイルにルートを登録する作業はありません。ここでは、その規則と、規則だけでは足りない場面の逃げ道を見ます。
基本の規則
src/pages/ 配下のファイル構成が、そのまま公開URLになります。
| ファイル | URL |
|---|---|
src/pages/index.astro | / |
src/pages/about.astro | /about |
src/pages/about/index.astro | /about |
src/pages/about/me.astro | /about/me |
src/pages/blog/2026/review.md | /blog/2026/review |
index という名前のファイルは、そのディレクトリ自身のURLになります。about.astro と about/index.astro は同じ /about を指すため、両方を置くと衝突します。
ページになれるファイルは .astro、.md、.mdx、そして後述するエンドポイント用の .js / .ts です。
ページから除外したいファイル
ファイル名やディレクトリ名を _(アンダースコア)で始めると、ルーティングの対象外になります。
src/pages/
├── index.astro → /
├── _draft.astro → 公開されない
└── _components/ → 中身は公開されない
└── Hero.astro
ページ専用の部品を src/pages/ の近くに置きたいときに便利です。
ここまでの対応関係は次のとおりです。
動的ルート
商品ページのように「構造は同じで内容だけ違うページ」を大量に作る場合、1ファイルずつ用意するのは現実的ではありません。そこで使うのが動的ルートです。
ファイル名の一部を角かっこで囲むと、その部分が変数(パラメータ)になります。
---
// src/pages/dogs/[dog].astro
export function getStaticPaths() {
return [
{ params: { dog: "clifford" } },
{ params: { dog: "rover" } },
];
}
const { dog } = Astro.params;
---
<h1>{dog}のページ</h1>
これで /dogs/clifford と /dogs/rover の2ページが生成されます。
getStaticPaths()の役割
静的生成では、ビルド時にすべてのURLが確定していなければなりません。そのため、動的ルートのファイルは getStaticPaths() をエクスポートし、生成すべきURLの一覧を返す必要があります。
戻り値は params オブジェクトを持つ配列です。params のキーは、ファイル名の角かっこ内の名前と一致させます。
注意:
getStaticPaths()はビルド時に一度だけ実行されます。ページごとに毎回呼ばれるわけではありません。
1つのファイルと戻り値の配列から、ページが作られるまでの関係は次のとおりです。
propsで追加データを渡す
URLの一覧だけでなく、各ページで使うデータも一緒に渡せます。props プロパティに載せた値は、ページ側で Astro.props から受け取れます。
---
// src/pages/blog/[slug].astro
export async function getStaticPaths() {
const response = await fetch("https://api.example.com/posts");
const posts = await response.json();
return posts.map(post => ({
params: { slug: post.slug },
props: { title: post.title, body: post.body },
}));
}
const { title, body } = Astro.props;
---
<h1>{title}</h1>
<p>{body}</p>
データ取得を getStaticPaths() にまとめられるので、ページ本体はシンプルに保てます。
複数のパラメータ
1つのファイルに複数のパラメータを含められます。
---
// src/pages/[lang]-[version]/info.astro
export function getStaticPaths() {
return [
{ params: { lang: "ja", version: "v1" } },
{ params: { lang: "en", version: "v2" } },
];
}
---
/ja-v1/info と /en-v2/info が生成されます。
restパラメータ:深さが決まらないパス
[...path] のように3点リーダーを付けると、スラッシュを含む任意の深さのパスを1つのパラメータで受け取れます。ドキュメントサイトのように階層が読めない構造で有効です。
---
// src/pages/docs/[...path].astro
export function getStaticPaths() {
return [
{ params: { path: "guide/install" } },
{ params: { path: "guide/config/advanced" } },
{ params: { path: undefined } }, // /docs 自体
];
}
---
params の値を undefined にすると、パラメータ部分のないURL(この例では /docs)を生成できます。
ページネーション
記事一覧のように件数が多いページは、paginate() を使って分割できます。getStaticPaths() の引数から受け取れます。
---
// src/pages/blog/[...page].astro
export const getStaticPaths = ({ paginate }) => {
const posts = [
{ title: "記事A" },
{ title: "記事B" },
{ title: "記事C" },
];
return paginate(posts, { pageSize: 2 });
};
const { page } = Astro.props;
---
<ul>
{page.data.map(post => <li>{post.title}</li>)}
</ul>
<nav>
{page.url.prev && <a href={page.url.prev}>前のページ</a>}
{page.url.next && <a href={page.url.next}>次のページ</a>}
</nav>
page オブジェクトには、そのページに載せるデータ(data)のほか、現在のページ番号(currentPage)、総ページ数、前後のURL(url.prev / url.next)が入っています。ページ送りのUIを自分で計算する必要はありません。
リダイレクトとリライト
設定ファイルでのリダイレクト
URLを変更したときの転送設定は、astro.config.mjs にまとめて書けます。
export default defineConfig({
redirects: {
"/old-page": "/new-page",
"/blog": "https://example.com/blog",
},
});
ステータスコードは既定で301(恒久的な移動)です。必要なら個別に指定できます。
ページ内での動的なリダイレクト
条件によって転送先を変えたい場合は、コンポーネントスクリプトで Astro.redirect() を返します。
---
if (!isLoggedIn(Astro.request.headers.get("cookie"))) {
return Astro.redirect("/login");
}
---
リライト
Astro.rewrite() は、ブラウザのURLを変えずに別のコンテンツを表示します。転送ではなく差し替えです。
---
return Astro.rewrite("/ja/articles/introduction");
---
URLを保ったまま内容を切り替えられるため、多言語対応やA/Bテストで使われます。
転送と差し替えの違いは、ブラウザ側の見え方に現れます。
ルートの優先順位
複数のルートが同じURLに一致してしまうことがあります。たとえば /posts/create は、src/pages/posts/create.astro にも src/pages/posts/[pid].astro にも一致します。
このときAstroは、次の順序で優先するルートを決定します。
先の例では、より具体的な create.astro が選ばれます。具体的な指定ほど優先される。これだけ覚えておけば、直感と大きくずれません。
ページ間のリンク
Astroにリンク専用のコンポーネントはありません。通常の <a> タグを使います。
<a href="/about/">このサイトについて</a>
サイトをサブディレクトリに配置する場合(base オプションを設定する場合)は、import.meta.env.BASE_URL を前置してパスを組み立てると、環境が変わっても壊れません。
<a href={`${import.meta.env.BASE_URL}about/`}>このサイトについて</a>
要点
src/pages/のファイル構成がそのままURLになる。ルート設定ファイルは不要である。_で始まるファイル・ディレクトリはページとして公開されない。[param]で動的ルートを作り、getStaticPaths()で生成するURL一覧を返す。propsで各ページ用のデータも渡せる。[...path]は任意の深さのパスを受け取れる。paginate()で一覧のページ送りを簡単に作れる。- 複数ルートが競合したときは、より具体的なルートが優先される。
参考資料
シリーズ目次 / 前章: 04. Astroのレイアウトとスタイリング / 次章: 06. Astro コンテンツコレクションで記事を管理する