Astro v5 Content Layer API の使い方 - 4. 自作ローダー オブジェクトローダーの作り方

[Astro]

[Content Layer API]

[フロントエンド]

Astro v5になって導入されたContent Layer APIの使い方シリーズその4です。

今回は自作ローダーをオブジェクトローダーで作ってみます。

オブジェクトローダーは Loader 型を返す関数を、 defineCollectionloaderオプションで呼び出す方法です。 その1で紹介したglobローダー、その2で紹介したサードパーティーローダーなどがオブジェクトローダーです。

その3で紹介したインラインローダーとの違いは2点です。

  1. content collectionへのデータ登録を自分でやる必要がある
  2. オブジェクトローダーはnameプロパティを使って名前をつけられる

では、オブジェクトローダーの例として、Githubからリポジトリ情報を取得するローダーを作ってみます。

まず Loader 型のオブジェクトを返す関数を作ります。 Loader型は nameloadschemaの3つのプロパティを持ちます。

import type { Loader } from 'astro/loaders'
export const githubLoader = (): Loader => ({
name: 'github',
load: async ({ store }) => {
},
schema: {}, // ここにスキーマを書く
})

load 関数の中にGithub APIを使ってリポジトリ情報を取得する処理を書きます。

import type { Loader } from 'astro/loaders'
import { Octokit } from 'octokit'
import { z } from 'astro:content'
export const githubLoader = (): Loader => ({
name: 'github',
load: async ({ store }) => {
const api = new Octokit()
const res = await api.rest.repos.listForUser({
username: 'TanStack',
})
const json = res.data
},
schema: {},
})

最後に取得したデータをcontent collectionに登録します。

import type { Loader } from 'astro/loaders'
import { Octokit } from 'octokit'
import { z } from 'astro:content'
export const githubLoader = (): Loader => ({
name: 'github',
load: async ({ store }) => {
const api = new Octokit()
const res = await api.rest.repos.listForUser({
username: 'TanStack',
})
const json = res.data
store.clear()
json.forEach((x) => {
store.set({
id: `${x.id}`,
data: x,
digest: generateDigest(`${x.updated_at}`),
})
});
},
schema: z.object({
id: z.number(),
name: z.string(),
html_url: z.string(),
description: z.string(),
stargazers_count: z.number()
})
})

この例ではいったん store.clear() でcollectionを消去してから、 store.set() でデータを登録しています。 store.get() を使ってすでにあるデータを確認し、無いものだけを登録することもできます。

21行目で generateDigest() を使ってデータの更新日時をハッシュ化しています。digest の値はオプションで、なくてもかまいません。

digestがあると、開発環境でデータを更新する際に参照され、必要がなければコンテンツの再生成をスキップします。(今回はstore.clear()でcollectionを消去しているので、digestは意味がありません)

これでオブジェクトローダーが完成しました。以下のようにcontent.config.ts で使うことができます。

import { defineCollection } from 'astro:content'
import { githubLoader } from './loaders/github'
export const github = defineCollection({
loader: githubLoader(),
})
export const collections = { github }

以上でContent Layer APIの使い方シリーズは終了です

Astro v5 Content Layer API の使い方 - 3. 自作ローダー インラインローダーの作り方
firefox, zen browserで開発ツールのフォントサイズを大きくする