コンテンツにスキップ

Astro Content Loader API

AstroのContent Loader APIを使用することで、ローカルまたはリモートの任意のソースからデータをロードし、Astroのコンテンツレイヤーとやり取りしてコンテンツコレクションを管理できます。

Astroのローダーを使用すると、コンテンツコレクションにデータをロードでき、ページやコンポーネントで使用できます。ビルトインのglob()およびfile()ローダーはファイルシステムからコンテンツをロードするために使用され、他のソースからコンテンツをロードするために独自のローダーを作成することもできます。

各コレクションにはスキーマで定義されたローダーが必要です。プロジェクトのsrc/content.config.tsファイルにインラインでローダーを定義したり、複数のコレクション間で1つのローダーを共有したり、他の人と共有するためにNPMにパッケージとしてローダーを公開して、統合ライブラリに含めることもできます。

Astroには、コレクションを取得するための2つのビルトインローダーが用意されています。どちらも幅広いユースケースに対応するオプションを提供しています。

Type: (options: GlobOptions) => Loader

追加: astro@5.0.0

glob()ローダーは、ファイルシステム上の任意のディレクトリからファイルのエントリを作成します。サポートされているファイルタイプは、Markdown、MDX、Markdoc、JSON、およびYAMLファイルです。

このローダーは、patternbase(オプショナル)、およびgenerateId(オプショナル)のプロパティを持つをオブジェクトを受け入れます。

src/content.config.ts
import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
const pages = defineCollection({
/* pagesディレクトリにあるすべてのマークダウンファイルを取得する。 */
loader: glob({ pattern: "**/*.md", base: "./src/data/pages" }),
schema: /* ... */
});
const blog = defineCollection({
/* blogディレクトリにあるすべてのマークダウン、MDXファイルを取得する。 */
loader: glob({ pattern: "**/*.(md|mdx)", base: "./src/data/blog" }),
schema: /* ... */
});
const authors = defineCollection({
/* 大文字のIDを保持したまま、authorsディレクトリ内のすべてのJSONファイルを取得する。 */
loader: glob({
pattern: '**/*.json',
base: "./src/data/authors",
generateId: ({ entry }) => entry.replace(/\.json$/, ''),
}),
schema: /* ... */
});

Type: string | string[]

patternプロパティは、グロブマッチング(ワイルドカードなど)を使用して文字列または文字列の配列を受け入れます。パターンは、エントリファイルのベースディレクトリに対して相対的である必要があります。

使用する構文の詳細については、micromatchのドキュメントを参照してください。また、DigitalOcean Glob Toolのようなオンラインツールを使用してパターンの有効性を確認することもできます。

Type: string | URL
Default: "."

patternを解決するためのディレクトリへの相対パスまたはURLを指定します。

Type: (options: GenerateIdOptions) => string

エントリごとに一意の文字列を返すコールバック関数です。以下のプロパティを持つオブジェクトをパラメータとして受け取ります。

  • entry - ベースディレクトリに対するエントリファイルのパス
  • base - ベースディレクトリのURL
  • data - パースされた未検証のエントリデータ

デフォルトでは、github-sluggerを使用して、ケバブケースの単語でスラッグを生成します。

Type: (fileName: string, options?: FileOptions) => Loader

追加: astro@5.0.0

file()ローダーは、ユニークなidフィールドを持つオブジェクトの配列を含む単一のファイル、またはIDをキー、エントリを値とするオブジェクトからエントリを作成します。JSONまたはYAMLをサポートしており、デフォルトでは解析できないデータファイルに対してカスタムのparserを提供することができます。

このローダーは、fileNameプロパティとオプションのオブジェクトを第二引数として受け入れます。

src/content.config.ts
import { defineCollection } from 'astro:content';
import { file } from 'astro/loaders';
const authors = defineCollection({
/* JSONファイルからすべてのエントリーを取得する。 */
loader: file("src/data/authors.json"),
schema: /* ... */
});
const products = defineCollection({
/* カスタムのパーサーを使って、CSVファイルからすべてのエントリーを取得する。 */
loader: file("src/data/products.csv", {
parser: (fileContent) => { /* パーサーのロジックを記述 */ },
}),
schema: /* ... */
});

Type: string

ファイルをロードするためのパスを、ルートディレクトリからの相対パスで設定します。

Type: FileOptions

オプションのオブジェクトとして、次のプロパティを持ちます。

Type: (text: string) => Record<string, Record<string, unknown>> | Array<Record<string, unknown>>

ファイルの内容からコレクションを作成するためのコールバック関数です。デフォルトでサポートされていないファイル(例:.csv)を処理する必要がある場合や、ネストされた.jsonドキュメントを使用する場合に使用します。

ローダーは、エントリの配列を返す単純な関数として定義することも、より強力なオブジェクトContent Loader APIを使用してロードプロセスをより詳細に制御することもできます。

インラインローダーは、エントリを含む配列またはオブジェクトを返す非同期関数です。これは、特にsrc/content.config.tsファイルにインラインで定義されるシンプルなローダーに使用します。

この関数は非同期であり、各エントリが一意のidフィールドを含む配列、または各キーが一意のIDで各値がエントリであるオブジェクトを返す必要があります。ローダーが呼び出されるたびに、ストアをクリアしてすべてのエントリを再ロードします。

src/content.config.ts
const countries = defineCollection({
loader: async () => {
const response = await fetch("https://restcountries.com/v3.1/all");
const data = await response.json();
// エントリの配列を返す必要があります(各エントリにはidプロパティが必要)
// またはIDをキー、エントリを値とするオブジェクトを返す必要があります
return data.map((country) => ({
id: country.cca3,
...country,
}));
},
schema: /* ... */
});

ローダーは、ビルド時にデータを取得してデータストアを更新するために呼び出されるload()メソッドを持つオブジェクトです。これにより、エントリを段階的に更新したり、必要に応じてストアをクリアすることができます。また、エントリのスキーマを定義してデータを検証し、静的な型を生成することもできます。

推奨されるパターンは、構成オプションを受け取り、ローダーオブジェクトを返す関数を定義することです。これは、通常AstroインテグレーションやViteプラグインを定義する方法と同じです。

loader.ts
import type { Loader, LoaderContext } from 'astro/loaders';
import { z } from 'astro:content';
import { loadFeedData } from "./feed.js";
// ローダーが必要とするオプションを定義
export function myLoader(options: { url: string, apiKey: string }): Loader {
// ローダーの設定
const feedUrl = new URL(options.url);
// Loaderオブジェクトを返す
return {
name: "my-loader",
// コレクションを更新する際に呼び出されます
load: async (context: LoaderContext): Promise<void> => {
// データをロードしてストアを更新
const response = await loadFeedData(feedUrl, options.apiKey);
},
// オプションで、エントリのスキーマを定義します
// ユーザー定義のスキーマによって上書きされます
schema: async () => z.object({
// ...
})
};
}

これらの構成オプションは、コレクションを定義する際に設定できます。

src/content.config.ts
import { defineCollection, z } from 'astro:content';
import myLoader from '../../loader.ts';
const blog = defineCollection({
loader: myLoader({
url: "https://api.example.com/posts",
apiKey: "my-secret",
}),
schema: /* ... */
});

インラインローダーのAPIは、上述の通り非常にシンプルです。このセクションでは、オブジェクトローダーを定義するためのAPIを示します。

Loaderオブジェクトは、以下のプロパティを持ちます。

Type: string

一意なローダーの名前を示します。ログや条件付きロード (EN)に使用されます。

Type: (context: LoaderContext) => Promise<void>

ビルド時にデータをロードしてストアを更新するために呼び出される非同期関数です。詳細はLoaderContextを参照してください。

Type: ZodSchema | Promise<ZodSchema> | (() => ZodSchema | Promise<ZodSchema>)

オプションで、Zodスキーマでエントリの型を定義します。データの検証と、コレクションのTypeScriptの型の生成に使用されます。

関数が提供された場合、ビルド時にload()の前に呼び出されてスキーマを生成します。これを使用して、構成オプションに基づいてスキーマを動的に生成したり、APIを検証してスキーマを生成したりできます。

このオブジェクトはローダーのload()メソッドの引数に渡されるもので、以下のプロパティを持ちます。

Type: string

一意なコレクションの名前を示します。これは、src/content.config.tsファイルのcollectionsオブジェクトのキーです。

Type: DataStore

実際のデータを保持するデータベースです。これを使用して、新しいエントリでストアを更新します。詳細はDataStoreを参照してください。

Type: MetaStore

コレクションにスコープされたキーと値のストアで、同期トークンや最終更新時刻などに使用されます。このメタデータはビルド間でコレクションデータと共に保持されますが、ローダー内でのみ利用可能です。

const lastModified = meta.get("lastModified");
// ...
meta.set("lastModified", new Date().toISOString());

Type: AstroIntegrationLogger (EN)

コンソールにメッセージを出力するために使用できるロガーです。console.logの代わりにこれを使用すると、ローダー名を含むより有用なログが得られます。詳細はAstroIntegrationLogger (EN)を参照してください。

Type: AstroConfig

すべてのデフォルト値が適用された完全な解決済みAstro構成オブジェクトです。詳細は設定方法を参照してください。

Type: (props: ParseDataOptions<TData>) => Promise<TData>

コレクションスキーマに従って、データを検証および解析します。この関数にデータを渡して、データストアに保存する前に検証および解析します。

loader.ts
import type { Loader } from "astro/loaders";
import { loadFeed } from "./feed.js";
export function feedLoader({ url }): Loader {
const feedUrl = new URL(url);
return {
name: "feed-loader",
load: async ({ store, logger, parseData, meta, generateDigest }) => {
logger.info("Loading posts");
const feed = loadFeed(feedUrl);
store.clear();
for (const item of feed.items) {
const data = await parseData({
id: item.guid,
data: item,
});
store.set({
id,
data,
});
}
},
};
}

Type: (data: Record<string, unknown> | string) => string

オブジェクトや文字列の暗号化を伴わないコンテンツダイジェストを生成します。これは、エントリのdigestフィールドを設定してデータが変更されたかどうかを追跡するために使用できます。

loader.ts
import type { Loader } from "astro/loaders";
import { loadFeed } from "./feed.js";
export function feedLoader({ url }): Loader {
const feedUrl = new URL(url);
return {
name: "feed-loader",
load: async ({ store, logger, parseData, meta, generateDigest }) => {
logger.info("Loading posts");
const feed = loadFeed(feedUrl);
store.clear();
for (const item of feed.items) {
const data = await parseData({
id: item.guid,
data: item,
});
const digest = generateDigest(data);
store.set({
id,
data,
digest,
});
}
},
};
}

Type: FSWatcher

開発モードで実行している場合に、これは更新をトリガーするために使用できるファイルシステムウォッチャーです。詳細はViteDevServerを参照してください。

Extract from the file() loader
return {
name: 'file-loader',
load: async ({ config, store, watcher }) => {
const url = new URL(fileName, config.root);
const filePath = fileURLToPath(url);
await syncData(filePath, store);
watcher?.on('change', async (changedPath) => {
if (changedPath === filePath) {
logger.info(`Reloading data from ${fileName}`);
await syncData(filePath, store);
}
});
},
};

Type: Record<string, unknown>

ローダーがインテグレーションでトリガーされた場合、オプションでインテグレーションによって設定された追加データを含むことがあります。これはローダーがインテグレーションによってトリガーされた場合にのみ設定されます。詳細はastro:server:setup (EN)フックリファレンスを参照してください。

loader.ts
export function myLoader(options: { url: string }): Loader {
return {
name: "my-loader",
load: async ({ refreshContextData, store, logger }) => {
if(refreshContextData?.webhookBody) {
logger.info("Webhook triggered with body");
processWebhook(store, refreshContextData.webhookBody);
}
// ...
},
};
}

DataStoreは、ローダーがコンテンツコレクションデータにアクセスするためのインターフェースです。これはキーと値のストアで、コレクションにスコープされているため、ローダーは自分のコレクションのデータにのみアクセスできます。

Type: (key: string) => DataEntry | undefined

ストアから指定したIDのエントリを取得します。エントリが存在しない場合はundefinedを返却します。

const existingEntry = store.get("my-entry");

返却されるオブジェクトはDataEntryオブジェクトです。

Type: (entry: DataEntry) => boolean

データが検証および解析された後にエントリをストアに追加するために使用され、エントリが設定された場合はtrueを返却します。エントリが変更されておらず更新する必要がないとdigestプロパティが判断した場合はfalseを返却します。

loader.ts
for (const item of feed.items) {
const data = await parseData({
id: item.guid,
data: item,
});
const digest = generateDigest(data);
store.set({
id,
data,
rendered: {
html: data.description ?? "",
},
digest,
});
}

Type: () => Array<[id: string, DataEntry]>

コレクション内のすべてのエントリをキーと値のペアの配列で取得します。

Type: () => Array<string>

コレクション内のすべてのエントリのキーを取得します。

Type: () => Array<DataEntry>

コレクション内のすべてのエントリを配列で取得します。

Type: (key: string) => void

ストアから指定したIDのエントリを削除します。

Type: () => void

コレクションからすべてのエントリを削除します。

Type: (key: string) => boolean

ストアに指定したIDのエントリが存在するかどうかを確認します。

これはデータストアに保存されるオブジェクトの型です。以下のプロパティを持ちます。

Type: string

エントリの識別子で、コレクション内で一意である必要があります。これはストア内でエントリを検索するために使用され、getEntryでそのコレクションに使用されるキーです。

Type: Record<string, unknown>

エントリの実際のデータです。ユーザーがコレクションにアクセスする際、これはコレクションスキーマに従って生成されたTypeScriptの型を持ちます。

データストアに保存する前にデータを検証および解析するためにparseDataを使用するのはローダーの責任です。データの取得や設定時には検証は行われません。

Type: string | undefined

このエントリのソースとなるファイルへのパスです。サイトのルートからの相対パスです。これはファイルベースのローダーにのみ適用され、画像やその他のアセットのパスを解決するために使用されます。

設定されていない場合、スキーマ内でimage()ヘルパーを使用するフィールドはpublicパスとして扱われ、変換されません。

Type: string | undefined

エントリの生のボディです(該当する場合)。エントリにレンダリングされたコンテンツが含まれている場合、このフィールドを使用して生のソースを保存できます。これはオプションであり、内部的には使用されません。

Type: string | undefined

任意のエントリのコンテンツダイジェストです。これを使用してデータが変更されたかどうかを確認できます。

エントリを設定する際、同じIDの既存エントリとダイジェストが一致しない場合にのみエントリが更新されます。

ダイジェストの形式はローダー次第ですが、データが変更されたときに変わる文字列でなければなりません。これはgenerateDigest関数を使用して行えます。

Type: RenderedContent | undefined

エントリがHTMLにレンダリングされている場合、そのレンダリングされたコンテンツとメタデータを含むオブジェクトを保存します。例えば、Markdownエントリのレンダリングされたコンテンツや、CMSからのHTMLを保存するために使用できます。

このフィールドが提供されている場合、render()関数と<Content />コンポーネントを使用してページ内でエントリをレンダリングできます。

RenderedContentオブジェクトの形式は次の通りです。

{
/** レンダリングされたHTML文字列。これが存在する場合、`render(entry)`はこのHTMLをレンダリングするコンポーネントを返します。 */
html: string;
metadata?: {
/** このエントリに含まれる画像。{@link DataEntry}のfilePathに対して相対的です。 */
imagePaths?: Array<string>;
/** このファイルに含まれる見出し。`render()`から`headings`として返されます。 */
headings?: MarkdownHeading[];
/** ファイルから解析された生のフロントマター。これにはremarkプラグインからのデータが含まれる場合があります。 */
frontmatter?: Record<string, any>;
/** このファイルに含まれるその他のメタデータ。 */
[key: string]: unknown;
};
}
貢献する コミュニティ Sponsor
京ICP备15031610号-99