Skip to content

Astro 内容加载器 API

Astro 的内容加载器 API 允许你从任何来源(本地或远程)加载数据,并与 Astro 的内容层交互以管理你的 内容集合

¥Astro’s Content Loader API allows you to load your data from any source, local or remote, and interact with Astro’s content layer to manage your content collections.

¥What is a loader?

Astro 加载器允许你将数据加载到 内容集合,然后可以在页面和组件中使用。内置 glob()file() 加载器 用于从文件系统加载内容,你可以创建自己的加载器来从其他来源加载内容。

¥Astro loaders allow you to load data into content collections, which can then be used in pages and components. The built-in glob() and file() loaders are used to load content from the file system, and you can create your own loaders to load content from other sources.

每个集合都需要 在其模式中定义的加载器。你可以在项目的 src/content.config.ts 文件中内联定义加载器,在多个集合之间共享一个加载器,甚至可以使用 将你的加载器作为包发布到 NPM 与他人共享并包含在我们的集成库中。

¥Each collection needs a loader defined in its schema. You can define a loader inline in your project’s src/content.config.ts file, share one loader between multiple collections, or even publish your loader to NPM as a package to share with others and be included in our integrations library.

¥Loader types

加载器可以定义为返回条目数组的简单函数,也可以使用更强大的对象内容加载器 API 来更好地控制加载过程。

¥Loaders can be defined either as a simple function that returns an array of entries or with the more powerful object Content Loader API for more control over the loading process.

¥Inline loaders

内联加载器是一个异步函数,它返回包含条目的数组或对象。将其用于简单的加载器,特别是在 src/content.config.ts 文件中内联定义的加载器。

¥An inline loader is an async function that returns an array or object containing entries. Use this for simple loaders, particularly those that are defined inline in the src/content.config.ts file.

该函数可以是异步的,并且必须返回一个条目数组,每个条目包含一个唯一的 id 字段,或者一个对象,其中每个键都是一个唯一的 ID,每个值都是条目。每当调用加载器时,它都会清除存储并重新加载所有条目。

¥The function can be async and must return either an array of entries that each contain a unique id field, or an object where each key is a unique ID and each value is the entry. Whenever the loader is invoked, it will clear the store and reload all the entries.

src/content.config.ts
const countries = defineCollection({
loader: async () => {
const response = await fetch("https://restcountries.com/v3.1/all");
const data = await response.json();
// Must return an array of entries with an id property
// or an object with IDs as keys and entries as values
return data.map((country) => ({
id: country.cca3,
...country,
}));
},
schema: /* ... */
});

¥Object loaders

加载器是一个具有 load() 方法的对象,在构建时调用该方法来获取数据并更新数据存储。它允许逐步更新条目,或者仅在必要时清除商店。它还可以为条目定义模式,可用于验证数据和生成静态类型。

¥A loader is an object with a load() method that is called at build time to fetch data and update the data store. It allows entries to be updated incrementally, or for the store to be cleared only when necessary. It can also define a schema for the entries, which can be used to validate the data and generate static types.

推荐的模式是定义一个接受配置选项并返回加载器对象的函数,就像你通常定义 Astro 集成或 Vite 插件一样。

¥The recommended pattern is to define a function that accepts configuration options and returns the loader object, in the same way that you would normally define an Astro integration or Vite plugin.

loader.ts
import type { Loader, LoaderContext } from 'astro/loaders';
import { z } from 'astro:content';
import { loadFeedData } from "./feed.js";
// Define any options that the loader needs
export function myLoader(options: { url: string, apiKey: string }): Loader {
// Configure the loader
const feedUrl = new URL(options.url);
// Return a loader object
return {
name: "my-loader",
// Called when updating the collection.
load: async (context: LoaderContext): Promise<void> => {
// Load data and update the store
const response = await loadFeedData(feedUrl, options.apiKey);
},
// Optionally, define the schema of an entry.
// It will be overridden by user-defined schema.
schema: async () => z.object({
// ...
})
};
}

然后可以在定义集合时设置这些配置选项:

¥These configuration options can then be set when defining a collection:

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: /* ... */
});

¥Loader API

内联加载器 的 API 非常简单,如上所示。本节展示用于定义对象加载器的 API。

¥The API for inline loaders is very simple, and is shown above. This section shows the API for defining an object loader.

¥The Loader object

加载器对象具有以下属性:

¥The loader object has the following properties:

类型:string

¥Type: string

加载器的唯一名称,用于日志和 用于条件加载

¥A unique name for the loader, used in logs and for conditional loading.

类型:(context: LoaderContext) => Promise<void>

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

在构建时调用的异步函数,用于加载数据和更新商店。请参阅 LoaderContext 了解更多信息。

¥An async function that is called at build time to load data and update the store. See LoaderContext for more information.

类型:ZodSchema | Promise<ZodSchema> | (() => ZodSchema | Promise<ZodSchema>)

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

定义条目形状的可选 Zod 模式。它既用于验证数据,也用于为集合生成 TypeScript 类型。

¥An optional Zod schema that defines the shape of the entries. It is used to both validate the data and also to generate TypeScript types for the collection.

如果提供了函数,它将在构建时在 load() 之前调用以生成架构。你可以使用它根据配置选项或通过自省 API 动态生成架构。

¥If a function is provided, it will be called at build time before load() to generate the schema. You can use this to dynamically generate the schema based on the configuration options or by introspecting an API.

此对象传递给加载器的 load() 方法,并包含以下属性:

¥This object is passed to the load() method of the loader, and contains the following properties:

类型:string

¥Type: string

集合的唯一名称。这是 src/content.config.ts 文件中 collections 对象中的键。

¥The unique name of the collection. This is the key in the collections object in the src/content.config.ts file.

类型:DataStore

¥Type: DataStore

用于存储实际数据的数据库。使用它来用新条目更新商店。请参阅 DataStore 了解更多信息。

¥A database to store the actual data. Use this to update the store with new entries. See DataStore for more information.

类型:MetaStore

¥Type: MetaStore

一个范围为集合的键值存储,用于同步令牌和上次修改时间等内容。此元数据与集合数据一起在构建之间保留,但仅在加载器内部可用。

¥A key-value store scoped to the collection, designed for things like sync tokens and last-modified times. This metadata is persisted between builds alongside the collection data but is only available inside the loader.

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

类型:AstroIntegrationLogger

¥Type: AstroIntegrationLogger

可用于将消息记录到控制台的记录器。使用它代替 console.log 可获得更有用的日志,这些日志在日志消息中包含加载器名称。请参阅 AstroIntegrationLogger 了解更多信息。

¥A logger that can be used to log messages to the console. Use this instead of console.log for more helpful logs that include the loader name in the log message. See AstroIntegrationLogger for more information.

类型:AstroConfig

¥Type: AstroConfig

已应用所有默认值的完整、已解析的 Astro 配置对象。请参阅 配置参考 了解更多信息。

¥The full, resolved Astro configuration object with all defaults applied. See the configuration reference for more information.

类型:(props: ParseDataOptions<TData>) => Promise<TData>

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

根据集合架构验证和解析数据。将数据传递给此函数以进行验证和解析,然后再将其存储在数据存储中。

¥Validates and parses the data according to the collection schema. Pass data to this function to validate and parse it before storing it in the data store.

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,
});
}
},
};
}

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

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

生成对象或字符串的非加密内容摘要。这可用于通过设置条目的 digest 字段 来跟踪数据是否已更改。

¥Generates a non-cryptographic content digest of an object or string. This can be used to track if the data has changed by setting the digest field of an entry.

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,
});
}
},
};
}

类型:FSWatcher

¥Type: FSWatcher

在开发模式下运行时,这是一个文件系统监视器,可用于触发更新。请参阅 ViteDevServer 了解更多信息。

¥When running in dev mode, this is a filesystem watcher that can be used to trigger updates. See ViteDevServer for more information.

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);
}
});
},
};

类型:Record<string, unknown>

¥Type: Record<string, unknown>

如果加载器已由集成触发,则这可能可选地包含由该集成设置的额外数据。它仅在加载器由集成触发时设置。有关更多信息,请参阅 astro:server:setup 钩子参考。

¥If the loader has been triggered by an integration, this may optionally contain extra data set by that integration. It is only set when the loader is triggered by an integration. See the astro:server:setup hook reference for more information.

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);
}
// ...
},
};
}

数据存储是加载器与内容集合数据的接口。它是一个键值 (KV) 存储,作用域为集合,因此加载器只能访问其自己集合的数据。

¥The data store is a loader’s interface to the content collection data. It is a key-value (KV) store, scoped to the collection, and therefore a loader can only access the data for its own collection.

类型:(key: string) => DataEntry | undefined

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

通过 ID 从存储中获取条目。如果条目不存在,则返回 undefined

¥Get an entry from the store by its ID. Returns undefined if the entry does not exist.

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

返回的对象是 DataEntry 对象。

¥The returned object is a DataEntry object.

类型:(entry: DataEntry) => boolean

¥Type: (entry: DataEntry) => boolean

在数据已 已验证和解析 后用于将条目添加到商店,如果设置了条目,则返回 true。当 digest 属性确定条目未更改且不应更新时,这将返回 false

¥Used after data has been validated and parsed to add an entry to the store, returning true if the entry was set. This returns false when the digest property determines that an entry has not changed and should not be updated.

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,
});
}

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

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

将集合中的所有条目作为键值对数组获取。

¥Get all entries in the collection as an array of key-value pairs.

类型:() => Array<string>

¥Type: () => Array<string>

获取集合中所有条目的键。

¥Get all the keys of the entries in the collection.

类型:() => Array<DataEntry>

¥Type: () => Array<DataEntry>

将集合中的所有条目作为数组获取。

¥Get all entries in the collection as an array.

类型:(key: string) => void

¥Type: (key: string) => void

通过其 ID 从存储中删除条目。

¥Delete an entry from the store by its ID.

类型:() => void

¥Type: () => void

清除集合中的所有条目。

¥Clear all entries from the collection.

类型:(key: string) => boolean

¥Type: (key: string) => boolean

通过 ID 检查商店中是否存在条目。

¥Check if an entry exists in the store by its ID.

这是存储在数据存储中的对象的类型。它具有以下属性:

¥This is the type of the object that is stored in the data store. It has the following properties:

类型:string

¥Type: string

条目的标识符,在集合中必须是唯一的。这用于查找存储中的条目,并且是与 getEntry 一起用于该集合的键。

¥An identifier for the entry, which must be unique within the collection. This is used to look up the entry in the store and is the key used with getEntry for that collection.

类型:Record<string, unknown>

¥Type: Record<string, unknown>

条目的实际数据。当用户访问集合时,将根据集合架构生成 TypeScript 类型。

¥The actual data for the entry. When a user accesses the collection, this will have TypeScript types generated according to the collection schema.

加载器有责任在将数据存储到数据存储之前使用 parseData 来验证和解析数据:获取或设置数据时不进行验证。

¥It is the loader’s responsibility to use parseData to validate and parse the data before storing it in the data store: no validation is done when getting or setting the data.

类型:string | undefined

¥Type: string | undefined

相对于站点根目录的文件路径,该文件是此条目的源。这仅适用于基于文件的加载器,用于解析图片或其他资源等路径。

¥A path to the file that is the source of this entry, relative to the root of the site. This only applies to file-based loaders and is used to resolve paths such as images or other assets.

如果未设置,则架构中使用 image() 助手 的任何字段都将被视为 公共路径 并且不会进行转换。

¥If not set, then any fields in the schema that use the image() helper will be treated as public paths and not transformed.

类型:string | undefined

¥Type: string | undefined

条目的原始主体(如果适用)。如果条目包含 渲染的内容,则此字段可用于存储原始源。这是可选的,不在内部使用。

¥The raw body of the entry, if applicable. If the entry includes rendered content, then this field can be used to store the raw source. This is optional and is not used internally.

类型:string | undefined

¥Type: string | undefined

条目的可选内容摘要。这可用于检查数据是否已更改。

¥An optional content digest for the entry. This can be used to check if the data has changed.

设置条目 时,只有当摘要与具有相同 ID 的现有条目不匹配时,条目才会更新。

¥When setting an entry, the entry will only update if the digest does not match an existing entry with the same ID.

摘要的格式由加载器决定,但它必须是在数据更改时更改的字符串。这可以通过 generateDigest 函数完成。

¥The format of the digest is up to the loader, but it must be a string that changes when the data changes. This can be done with the generateDigest function.

类型:RenderedContent | undefined

¥Type: RenderedContent | undefined

如果已渲染为 HTML,则将对象与条目的渲染内容和元数据一起存储。例如,这可用于存储 Markdown 条目的渲染内容或来自 CMS 的 HTML。

¥Stores an object with an entry’s rendered content and metadata if it has been rendered to HTML. For example, this can be used to store the rendered content of a Markdown entry, or HTML from a CMS.

如果提供了此字段,则 render() 函数和 <Content /> 组件 可用于在页面中渲染条目。

¥If this field is provided, then the render() function and <Content /> component are available to render the entry in a page.

RenderedContent 对象的格式为:

¥The format of the RenderedContent object is:

{
/** Rendered HTML string. If present then `render(entry)` will return a component that renders this HTML. */
html: string;
metadata?: {
/** Any images that are present in this entry. Relative to the {@link DataEntry} filePath. */
imagePaths?: Array<string>;
/** Any headings that are present in this file. Returned as `headings` from `render()` */
headings?: MarkdownHeading[];
/** Raw frontmatter, parsed from the file. This may include data from remark plugins. */
frontmatter?: Record<string, any>;
/** Any other metadata that is present in this file. */
[key: string]: unknown;
};
}
Astro 中文网 - 粤ICP备13048890号