Skip to content
Cloud AI エンジニア入門ガイド
Go back

05. Astroのファイルベースルーティング

この章の全体像として、基本、動的ルート、ページネーション、優先順位の4つを番号順に並べ、URL設計をファイル構成で表現できるようになることを示した図

シリーズ目次前章: 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.astroabout/index.astro は同じ /about を指すため、両方を置くと衝突します。

ページになれるファイルは .astro.md.mdx、そして後述するエンドポイント用の .js / .ts です。

ページから除外したいファイル

ファイル名やディレクトリ名を _(アンダースコア)で始めると、ルーティングの対象外になります。

src/pages/
├── index.astro          → /
├── _draft.astro         → 公開されない
└── _components/         → 中身は公開されない
    └── Hero.astro

ページ専用の部品を src/pages/ の近くに置きたいときに便利です。

ここまでの対応関係は次のとおりです。

src/pages配下のファイル構成がそのまま公開URLになり、indexはそのディレクトリ自身のURLに、アンダースコアで始まるファイルはページにならないことを、ファイル名とURLを左右に並べて対応づけた図

動的ルート

商品ページのように「構造は同じで内容だけ違うページ」を大量に作る場合、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つのファイルと戻り値の配列から、ページが作られるまでの関係は次のとおりです。

角かっこを含む1つのファイルに対してgetStaticPathsがパラメータの配列を返し、その要素の数だけページが作られることを、ファイル・パラメータ一覧・生成されるURLの三段で示した図

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が転送先に書き換わるのに対し、リライトはURLをそのままにして表示する中身だけを別のコンテンツへ差し替えることを、アドレスバーの変化で比較した図

ルートの優先順位

複数のルートが同じURLに一致してしまうことがあります。たとえば /posts/create は、src/pages/posts/create.astro にも src/pages/posts/[pid].astro にも一致します。

このときAstroは、次の順序で優先するルートを決定します。

複数のルートが一致した際に、予約ルート・セグメント数・静的優先・名前付きパラメータ優先・プリレンダー優先・エンドポイント優先の順で1つに絞り込まれる流れを示した図

先の例では、より具体的な create.astro が選ばれます。具体的な指定ほど優先される。これだけ覚えておけば、直感と大きくずれません。

ページ間のリンク

Astroにリンク専用のコンポーネントはありません。通常の <a> タグを使います。

<a href="/about/">このサイトについて</a>

サイトをサブディレクトリに配置する場合(base オプションを設定する場合)は、import.meta.env.BASE_URL を前置してパスを組み立てると、環境が変わっても壊れません。

<a href={`${import.meta.env.BASE_URL}about/`}>このサイトについて</a>

要点

参考資料


シリーズ目次前章: 04. Astroのレイアウトとスタイリング次章: 06. Astro コンテンツコレクションで記事を管理する


Share this post:

Previous Post
06. Astro コンテンツコレクションで記事を管理する
Next Post
04. Astroのレイアウトとスタイリング