[Astro] 静的サイトジェネレーター [ルーティング]
ルーティング
静的ルーティング
src/pages
ディレクトリにある、Astro コンポーネント (.astro) と Markdown ファイル (.md) は自動的にウェブサイトのページとなります。
動的ルーティング
1つの Astro ページコンポーネントは、ファイル名に動的ルーティングパラメータを指定して、指定した条件に合致する複数のルーティングを生成することもできます。
名前付きパラメータ
以下のように getStaticPaths()
関数を使用する値を指定することで、名前付きパラメータを持つルーティングを生成できます。
src/pages/dogs/[dog].astro
---
export function getStaticPaths() {
return [
// 生成対象: /dogs/clifford
{ params: { dog: 'clifford' } },
// 生成対象: /dogs/rover
{ params: { dog: 'rover' } },
// 生成対象: /dogs/spot
{ params: { dog: 'spot' } },
];
}
---
動的にルーティングを生成する Astro コンポーネントは、各ルーティングに対して Astro.params
オブジェクトを利用できます。
src/pages/posts/[id].astro
---
const { id } = Astro.params;
---
<p>post: { id }</p>
// ルーティング '/post/abc' に渡される Astro.params オブジェクト
{ "id": "abc" }
複数の動的ルーティングセグメントを組み合わせて、同じように動作させることができます。
src/pages/post/[id]/[comment].astro
---
const { id, comment } = Astro.params;
---
// ルーティング '/post/abc/a-comment' に渡される Astro.params オブジェクト
{ "id": "abc", "comment": "a-comment" }
レストパラメーター
URLルーティングに柔軟性が必要な場合は、.Astro ファイル名にレストパラメーターを使用します。これは、ブラケット内に3つのドット (…) を追加して、深さに関係なく、ファイルパスをすべて受け取れます。
ルーティングの優先順位
・パスパラメーターを持たない静的ルーティングは、他のすべてのルーティングよりも優先
・名前付きパラメーターを使用する動的ルーティングは、レストパラメーターよりも優先
・レストパラメーターはもっとも低い優先度
・同順位はアルファベット順に解決される
ページ分割
Astro は、複数のページに分割する必要がある大規模なデータコレクションのために、ビルトインのページ分割をサポートしています。Astro は、前ページ/次ページの URL、総ページ数など、一般的なページネーションプロパティを生成します。
/src/pages/astronauts/[page].astro
---
export async function getStaticPaths({ paginate }) {
const astronautPages = [{
astronaut: 'ニール・アームストロング',
}, {
astronaut: 'バズ・オルドリン',
}, {
astronaut: 'サリー・ライド',
}, {
astronaut: 'ジョン・グレン',
}];
// 宇宙飛行士の配列から、1ページに2人づつ入るようにページを生成する
return paginate(astronautPages, { pageSize: 2 });
}
// ページ分割されたデータは、すべて "page" プロパティとして渡される
const { page } = Astro.props;
---
<!-- 現在のページ番号を表示します。Astro.params.page も使用可能です -->
<h1>{ page.currentPage }page</h1>
<ul>
<!-- 宇宙飛行士情報の配列を列挙する -->
{ page.data.map(({ astronaut }) => <li>{ astronaut }</li>) }
</ul>
page プロパティ
paginate() 関数を使用すると、各ページのデータは page プロパティで渡されます。page プロパティは多くの便利なプロパティを持っていますが、ここではそのハイライトを紹介します。
/src/pages/astronauts/[page].astro
---
// 前の例と同じように、{ astronaut } オブジェクトのリストをページ分割します
export async function getStaticPaths({ paginate }) { /* ... */ }
const { page } = Astro.props;
---
<h1>{ page.currentPage }page</h1>
<ul>
{ page.data.map(({ astronaut }) => <li>{ astronaut }</li>) }
</ul>
{ page.url.prev ? <a href={ page.url.prev }>Previous</a> : null }
{ page.url.next ? <a href={ page.url.next }>Next</a> : null }
ネストされたページ分割
ページ分割のより高度なユースケースはネストされたページ分割です。これは、ページ分割を他の動的ルーティングパラメーターと組み合わせた場合です。ネストされたページ分割を使用すると、ページ分割されたコレクションを何らかのプロパティやタグでグループ化できます。
/src/pages/[tag]/[page].astro
---
export function getStaticPaths({paginate}) {
const allTags = ['red', 'blue', 'green'];
const allPosts = await Astro.glob('../../posts/*.md');
// すべてのタグに対して、paginate() の結果を返す
// 必ず、'{ params: { tag } }' を 'paginate()' に渡してください
// そうすれば、Astroは結果がどのタググループに対するものか分かります
return allTags.map((tag) => {
const filteredPosts = allPosts.filter((post) => post.frontmatter.tag === tag);
return paginate(filteredPosts, {
params: { tag },
pageSize: 10
});
});
}
const { page } = Astro.props;
const params = Astro.params;