Astroで動的ルーティングを実現するgetStaticPathsとは?設定方法や使い方を紹介!

カテゴリー
公開日 最終更新日
Astroで動的ルーティングを実現するgetStaticPathsとは?設定方法や使い方を紹介!

Astroにおけるルーティングは?

Webフレームワークの1つであるAstroでは、ファイルベースのルーティングを採用しており、静的ルーティングと動的ルーティングの両方をサポートしています。

静的ルーティングとは?

Webサイトにおける静的ルーティングとは、特定のURLパスが特定のページやリソースに常に対応しているという概念を意味しています。

src/pages配下に設置された`.astro`, .md, .mdxなどの拡張子のファイルはそのままページディレクトリとなります。具体的には以下のような関係が成立します。

ファイルパス

URL

src/pages/index.astro

/

src/pages/about.astro

/about

src/pages/blog.astro

/blog

src/pages/blog/1.md

/blog/1

src/pages/blog/2.mdx

/blog/2

このように、作成したファイルとそれが表示されるURLが1対1で表示されるということが静的ルーティングです。

動的ルーティングとは?

では、動的ルーティングとは何なのでしょうか。

ウェブサイトにおける動的ルーティングとは、URLにパラメータを指定することで、ページの内容を動的に変更する仕組みです。

動的ルーティングは、以下の場合によく使用されます。

  • 検索結果ページ
  • 商品一覧ページ
  • ブログ記事一覧ページ
  • 商品詳細ページ
  • ユーザーマイページ

たとえば、検索結果ページでは、URLに検索キーワードをパラメータとして指定することで、検索結果を動的に表示することができます。また、商品一覧ページでは、URLに商品カテゴリをパラメータとして指定することで、商品カテゴリごとに商品を表示することができます。

動的ルーティングを活用することで、ユーザーのニーズに合わせたコンテンツを表示でき満足度を高めることができます。また、ページ構造を複雑にせずに複数ページを表示可能なので管理の面でもメリットがあります。

動的ルーティングは、ウェブサイトの開発において、欠かせない技術の一つです。

Astroにおける動的ルーティングは?

Astroにおいて、動的なルーティングを実装するためにはブラケットで囲まれたファイルを作成します。具体的には、ある商品ごとにページを表示するAstroファイルの名前を[productName].astroとすることで各製品へのページを表示できます。

---
export function getStaticPaths() {
  return [
    {params: {productName: 'name1'}},
    {params: {productName: 'name2'}},
    {params: {productName: 'name3'}},
  ];
}
const { productName } = Astro.params;
---
<div>この商品は{productName}といいます</div>

このコードでは、getStaticPaths()という関数においてproductNameの取りうる値を指定しています。この関数は、Astroがページをビルドする際に実行され、getStaticPaths() の戻り値に基づいて、ページはビルドされます。

getStaticPathsとは?

getStaticPaths()は、静的サイトジェネレーターとしてAstroを使用する際に、生成する静的ページのパスの一覧を取得するための関数です。この関数は、ページごとに生成する静的ページのパスの一覧を返します。

getStaticPaths()は、ページのコンポーネントで定義します。コンポーネントの`export`ディレクティブの後に、`getStaticPaths()`関数を定義します。`getStaticPaths()`関数の戻り値は、配列型で各要素が静的ページのパスを表します。

getStaticPaths()には、以下の制限があります。

  • getStaticPaths()は、静的サイトジェネレーターとしてAstroを使用する際にのみ使用可能
  • getStaticPaths()は、ページごとに生成する静的ページのパスの一覧を返す
  • getStaticPaths()の戻り値は、配列型またはオブジェクト型

getStaticPaths()の使い方

getStaticPaths()は、前述したように取りうるパラメータを予め指定しておき、対応するURLにアクセスした際に該当のコードを返します。取りうるパラメータは1つだけでなく複数指定することが可能です。例えば以下のようなコードも動作します。

---
export function getStaticPaths () {
 return [
    {params: {device: 'mobile', os: 'iOS'}},
    {params: {device: 'mobile', os: 'Android'}},
    {params: {device: 'pc', os: 'Windows'}},
    {params: {device: 'pc', os: 'Macintosh'}},
  ];
}
const { device, os } = Astro.params;
---
<p>お使いのデバイスは{device}で、OSは{os}です。</p>

このように記述することで、ビルド時に4つのページが生成されます。

この他にも、柔軟なURLルーティングを実現することが可能です。柔軟なルーティングを実現するためには、レストパラメータ([...path])を使用します。

---
export function getStaticPaths() {
  return [
    {params: {path: 'one/two/three'}},
    {params: {path: 'four'}},
    {params: {path: undefined }} // トップページ
  ]
}
const { path } = Astro.params;
---
...

上のコードは/sequences/one/two/three/sequences/four/sequencesを生成します。(レストパラメーターを`undefined`に設定することで、トップレベルのページにマッチさせられます。)

getCollection()を使用した動的ルーティング

このセクションでは上記までとは異なり、自動で動的ルーティングを行う方法を紹介します。上記までの方法では、取りうる値を逐次指定しなければならずブログ目的などで運用を行う場合であればやや面倒であり、また、取りうる値が多い場合は記述量も多くなります。

Astroでは、src/content配下にmdやmdx形式のファイルを置き、適切な設定を行うことで動的ルーティングを実現できます。ブログなどで運用する場合に、コンテンツのファイルと.astroファイルの配置場所を分けたい場合には有効です。

この設定を行うために以下のようなフォルダ構成を想定しています。

```

src
├── content
│   ├── blog
│   │   ├── images
│   │   │   └──1.png
│   │   ├── 1.mdx
│   │   ├── 2.mdx
│   │   └── 3.mdx
|   └── config.ts
├── pages
│   └── blog
│       ├── [slug].astro
│       └── index.astro
└── layouts
    └── BlogLayout.astro

src/pages/blog/[slug].astroには以下のようにして記述をします。

import { type CollectionEntry, getCollection } from 'astro:content';
import BlogPost from '../layouts/BlogPost.astro';
export async function getStaticPaths() {
	const posts = await getCollection('blog');
	return posts.map((post) => ({
		params: { slug: post.slug },
		props: post,
	}));
}
type Props = CollectionEntry<'blog'>;
const post = Astro.props;
const { Content } = await post.render();
---
<BlogPost {...post.data}>
	<Content />
</BlogPost>

getStaticPaths()blogコレクションに従って生成し、その上で各postについて、slugをパラメータとして指定します。また、propsにはpostの内容を指定します。これによりビルド時に各postに対応するページが生成されます。blogコレクションには以下のように設定されています。

import { defineCollection, z } from 'astro:content';

const blog = defineCollection({
	schema: z.object({
		title: z.string(),
		description: z.string(),
		pubDate: z.coerce.date(),
		updatedDate: z.coerce.date().optional(),
		heroImage: z.string().optional(),
	}),
});

export const collections = { blog };

これにより、ブログポストで設定することができる項目が定義されます。また、配列を設定する際には`z.array(z.string())`を使用します。これにより文字列の配列を設定可能です。

まとめ

いかがでしたでしょうか。このページではAstroの`getStaticPaths()`と`getCollection()`を使って動的ルーティングを実現する方法を紹介しました。

静的なルーティングでは、URLに指定されたパスと一致するページが表示されます。一方、動的ルーティングでは、URLに指定されたパスとパラメータを組み合わせることで、複数のページを表示することができます。

これらをうまく使い分けることで、より使いやすいサイトを作ることができます。

動的ルーティングについて悩んでいる方の手助けとなれば幸いです。