title | sidebar | i18nReady | ||
---|---|---|---|---|
Astro Content Loader API |
|
true |
import Since from '~/components/Since.astro';
AstroのContent Loader APIを使用することで、ローカルまたはリモートの任意のソースからデータをロードし、Astroのコンテンツレイヤーとやり取りしてコンテンツコレクションを管理できます。
{/* TODO: /ja/guides/content-collections/#built-in-loaders
does not exist yet. #built-in-loaders
will be added when the fragment link destination is specified. */}
Astroのローダーを使用すると、コンテンツコレクションにデータをロードでき、ページやコンポーネントで使用できます。ビルトインのglob()
およびfile()
ローダーはファイルシステムからコンテンツをロードするために使用され、他のソースからコンテンツをロードするために独自のローダーを作成することもできます。
{/* TODO: /ja/guides/content-collections/#defining-the-collection-loader
does not exist yet. #defining-the-collection-loader
will be added when the fragment link destination is specified. */}
各コレクションにはスキーマで定義されたローダーが必要です。プロジェクトのsrc/content.config.ts
ファイルにインラインでローダーを定義したり、複数のコレクション間で1つのローダーを共有したり、他の人と共有するためにNPMにパッケージとしてローダーを公開して、統合ライブラリに含めることもできます。
Astroには、コレクションを取得するための2つのビルトインローダーが用意されています。どちらも幅広いユースケースに対応するオプションを提供しています。
Type: (options: GlobOptions) => Loader
glob()
ローダーは、ファイルシステム上の任意のディレクトリからファイルのエントリを作成します。サポートされているファイルタイプは、Markdown、MDX、Markdoc、JSON、およびYAMLファイルです。
このローダーは、pattern
、base
(オプショナル)、およびgenerateId
(オプショナル)のプロパティを持つをオブジェクトを受け入れます。
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
- ベースディレクトリのURLdata
- パースされた未検証のエントリデータ
デフォルトでは、github-slugger
を使用して、ケバブケースの単語でスラッグを生成します。
Type: (fileName: string, options?: FileOptions) => Loader
file()
ローダーは、ユニークなid
フィールドを持つオブジェクトの配列、または文字列キーを持つオブジェクトを含む単一のファイルからエントリを作成します。JSONまたはYAMLをサポートしており、デフォルトでは解析できないデータファイルに対してカスタムparser
を提供することができます。
このローダーは、fileName
プロパティとオプションのオブジェクトを第二引数として受け入れます。
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>>
{/* TODO: /ja/guides/content-collections/#nested-json-documents
does not exist yet. #nested-json-documents
will be added when the fragment link destination is specified. */}
ファイルの内容からコレクションを作成するためのコールバック関数です。デフォルトでサポートされていないファイル(例:.csv
)を処理する必要がある場合や、ネストされた.json
ドキュメントを使用する場合に使用します。
ローダーは、エントリの配列を返す単純な関数として定義することも、より強力なオブジェクトContent Loader APIを使用してロードプロセスをより詳細に制御することもできます。
インラインローダーは、エントリを含む配列またはオブジェクトを返す非同期関数です。これは、特にsrc/content.config.ts
ファイルにインラインで定義されるシンプルなローダーに使用します。
この関数は非同期であり、各エントリが一意のid
フィールドを含む配列、または各キーが一意のIDで各値がエントリであるオブジェクトを返す必要があります。ローダーが呼び出されるたびに、ストアをクリアしてすべてのエントリを再ロードします。
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プラグインを定義する方法と同じです。
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({
// ...
})
};
}
これらの構成オプションは、コレクションを定義する際に設定できます。
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
一意なローダーの名前を示します。ログや条件付きロードに使用されます。
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
コンソールにメッセージを出力するために使用できるロガーです。console.log
の代わりにこれを使用すると、ローダー名を含むより有用なログが得られます。詳細はAstroIntegrationLogger
を参照してください。
Type: AstroConfig
すべてのデフォルト値が適用された完全な解決済みAstro構成オブジェクトです。詳細は設定方法を参照してください。
Type: (props: ParseDataOptions<TData>) => Promise<TData>
コレクションスキーマに従って、データを検証および解析します。この関数にデータを渡して、データストアに保存する前に検証および解析します。
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
フィールドを設定してデータが変更されたかどうかを追跡するために使用できます。
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
を参照してください。
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
フックリファレンスを参照してください。
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
を返却します。
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;
};
}