Astro v5 Content Layer API の使い方 - 4. 自作ローダー オブジェクトローダーの作り方
Astro v5になって導入されたContent Layer APIの使い方シリーズその4です。
今回は自作ローダーをオブジェクトローダーで作ってみます。
オブジェクトローダーは Loader 型を返す関数を、 defineCollectionのloaderオプションで呼び出す方法です。
その1で紹介したglobローダー、その2で紹介したサードパーティーローダーなどがオブジェクトローダーです。
その3で紹介したインラインローダーとの違いは2点です。
- content collectionへのデータ登録を自分でやる必要がある
- オブジェクトローダーは
nameプロパティを使って名前をつけられる
では、オブジェクトローダーの例として、Githubからリポジトリ情報を取得するローダーを作ってみます。
まず Loader 型のオブジェクトを返す関数を作ります。
Loader型は name、load、schemaの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の使い方シリーズは終了です