nextjsと比べてastroで動的ルーティングをするのは少しわかりにくかったので、備忘録としてまとめます

公式ドキュメント

https://docs.astro.build/ja/guides/routing/#dynamic-routes

動的ルーティング

基礎

ルーティング方法はドキュメントの通り。 それほど難しくはないと思います。

動的ルーティングの指定は、nextjsのように []で囲って行う。

Astro.paramsからURLパラメータを取得できる。

const { dog } = Astro.params

ここからが追加の設定で、 公式ドキュメント曰く以下のような getStaticPaths()の設定が必須。

export function getStaticPaths() {
  return [
    { params: { dog: "clifford" }},
    { params: { dog: "rover" }},
    { params: { dog: "spot" }},
  ];
}

これで、

  • /dogs/clifford
  • /dogs/rover
  • /dogs/spot

のページが生成される。

単純にURLのパラメータを用いるだけならこのようにして、

<html>
  <body>
    param = { dog }
  </body>
</html>

として、表示すればいい。

md等の別ファイルを表示したい

ブログなどの場合、大幅に別の内容を表示したいです。 例えば、

  • /dogs/cliffordの場合、 clifford.mdを表示させたい。
  • /dogs/roverの場合、 rover.mdを表示させたい。

というような場合、少し追加の実装が必要です。

docs:https://docs.astro.build/en/guides/content-collections/#querying-collections

astroではコンテンツコレクションというものがあります。 ブログの記事等をここに登録して、表示させます。

load

詳細はドキュメントをご覧ください。 https://docs.astro.build/en/guides/content-collections/#defining-collections

src/content.config.tsを作成し、

次のように記述します。

import { glob } from "astro/loaders";
import { defineCollection, z } from "astro:content";

const posts = defineCollection({
    loader: glob({
            pattern: "**/*.md",
            base: "./src/content/",
        }),
    schema: //schema
});

export const collections = { dogs };

これで dogsというコンテンツコレクションが作成されます。

get

https://docs.astro.build/en/guides/content-collections/#querying-collections

コンテンツコレクションから内容を取得します。

const entry =await getEntry("dogs",dog);

文字列でコンテンツコレクションを設定するのはなんか気に入りませんが、こうするみたいです。 dogsコレクションの中の、dogにマッチするコンテンツを取得できます。

render

https://docs.astro.build/en/reference/modules/astro-content/#render

取得したコンテンツをレンダリング用にコンパイルします。

const {Content, headings } = await render(entry);
<html>
    <Content/>
</html>

とすることでようやく動的にページ内容を表示できます。

補足

マッチング方法

 getEntry("dogs",dog);

loader: glob(...) を使用している場合、ファイルパスが自動的に id として割り当てられる。 つまり、dogsコレクションのid(filepath)がdogであるものを取得している。

defineCollectionのschema

---
title: "title"
launch_date: 2025-12-21
status: "Active"
tags: ["tag"]
destination: "Web Development"
---
blog

astroのmdでは頭にこのように記述することができる。 この場合、schemaは

schema: z.object({
        title: z.string(),
        launch_date: z.date(),
        status: z.enum(['Active', 'Inactive', 'Decommissioned']),
        tags: z.string().array(),
        destination: z.string(),
    }),

とするのがいいかもしれない。 こうすることで、

entry.data.title

のように使うことができる。