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の使い方シリーズは終了です