跳转到内容

Astro 内容加载器 API

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

该 API 包含两个可直接使用的加载器,用于加载本地存储的内容。它还提供了用于构建自定义对象的工具,可将任意来源的数据加载到内容集合中。

在内容集合指南中,通过引导式解释和示例用法,了解更多关于 查询从构建时加载器加载的数据从实时加载器访问实时数据 的内容。

构建时加载器是具有 load() 方法 的对象,该方法在构建时被调用以获取数据并更新数据存储。此对象还可以为条目定义一个 schema,用于验证数据并生成静态类型。

Astro 的 glob()file() 加载器是开箱即用的对象加载器示例,用于处理本地内容。对于远程内容,则没有提供预置的加载器。你需要自行构建一个对象加载器,或使用 社区发布的加载器 来获取远程内容并与数据存储进行交互。

对于简单的数据请求,你也可以 将加载器定义为一个异步函数,该函数返回一个包含条目的数组或对象。

类型: (options: GlobOptions) => Loader

添加于: astro@5.0.0

glob() 加载器从文件系统中任何位置的文件目录创建条目。支持的文件类型包括 Markdown、MDX、Markdoc、JSON、YAML 和 TOML 文件。

该加载器接受具有以下属性的对象:patternbase(可选)、generateId(可选)和 retainBody(可选)。

src/content.config.ts
import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
const pages = defineCollection({
/* 检索你 page 目录中的所有 Markdown 文件。 */
loader: glob({ pattern: "**/*.md", base: "./src/data/pages" }),
});
const blog = defineCollection({
/* 检索你 blog 目录中的所有 Markdown 和 MDX 文件。 */
loader: glob({ pattern: "**/*.(md|mdx)", base: "./src/data/blog" }),
});
const notes = defineCollection({
/* 在你的笔记目录中检索所有 Markdown 文件并防止
* 内容文件的原始正文被存储到数据存储中。 */
loader: glob({
pattern: '**/*.md',
base: './src/data/notes',
retainBody: false
}),
});
const authors = defineCollection({
/* 检索你 authors 目录中的所有 JSON 文件,
* 同时保留 ID 中的大写字母。 */
loader: glob({
pattern: '**/*.json',
base: "./src/data/authors",
generateId: ({ entry }) => entry.replace(/\.json$/, ''),
}),
});
export const collections = { pages, blog, authors };

类型: string | string[]

pattern 属性接受使用全局匹配的字符串或字符串数​​组(例如通配符、双星号)。pattern 必须是相对于条目文件的 base 目录才能够匹配。

你可以在 micromatch 文档 中了解到有关应用语法的更多信息。你还可以使用像 DigitalOcean Glob Tool 这样的在线工具来验证 pattern 的有效性。

类型: string | URL
默认值: "."

从中解析 pattern 目录的相对路径或 URL

类型: (options: GenerateIdOptions) => string

返回集合中每个条目的唯一字符串的回调函数。它接受具有以下属性的对象作为参数:

  • entry - 条目文件的路径,相对于 base 目录
  • base - base 目录的 URL
  • data - 条目中已解析、未经验证的数据

默认情况下,它使用 github-slugger 生成遵循 烤串命名法 的 slug。

类型: boolean
默认值: true

添加于: astro@5.17.0

是否在数据存储中保存内容文件的原始正文。

retainBody 设置为 false 时,entry.body 将被设置为 undefined,而不是包含原始文件内容。

将此属性设置为 false 可以显著减少部署的数据存储大小,并有助于避免在拥有非常大集合的网站上触及大小限制。。

对于 Markdown 文件,渲染后的正文仍可在 entry.rendered.html 属性 中获取,且 entry.filePath 属性 仍将指向原始文件。

对于 MDX 集合,这将大幅减小集合的大小,因为存储中将不再保留任何正文。

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

添加于: astro@5.0.0

file() 加载器从单个文件创建条目,该文件包含具有唯一 id 字段的对象数组或是一个以 ID 作为键、条目作为值的对象。

它支持 JSON、YAML 或者 TOML 文件,你可以为默认情况下无法解析的数据文件提供一个自定义 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"),
});
const products = defineCollection({
/* 使用自定义 parser 从一个 CSV 文件中检索所有条目。 */
loader: file("src/data/products.csv", {
parser: (fileContent) => { /* 你的 parser 逻辑 */ },
}),
});
export const collections = { authors, products };

类型: string

设置要加载的文件的路径,相对于根目录。

类型: FileOptions

具有以下属性的可选对象:

类型: (text: string) => Record<string, Record<string, unknown>> | Array<Record<string, unknown>> | Promise<Record<string, Record<string, unknown>> | Array<Record<string, unknown>>>

回调函数,用于从文件内容创建一个集合。当你需要处理 JSON, YAML 或者 TOML 之外的默认情况下不支持的文件(例如 .csv)或使用 嵌套的 .json 文档 时,请使用它。

Content Loader API 灵活且功能完善,支持多种数据获取方式。你可以构建简单或复杂的加载器。你的自定义加载器将取决于数据的来源和结构,以及你选择如何管理持久化数据存储层。

大多数加载器会导出一个函数,该函数接受配置选项并返回一个 加载器对象,其中包括加载器的 name、一个 load() 方法以及定义条目的 schema

loader 对象中返回的 load() 函数定义了如何获取、解析、验证和更新你的内容。它接受一个 context 对象,允许你以多种方式自定义数据处理并与数据存储进行交互。一个典型的 load() 函数将会:

  • 从数据源获取你的数据。
  • 清除现有的数据存储。
  • 根据提供的模式解析并验证你的数据条目。
  • 使用新条目更新数据存储。

load() 方法还提供了一些辅助功能,用于将消息记录到控制台、将内容渲染为 HTML、在开发模式下监听变化并重新加载数据、提供对元数据乃至完整 Astro 配置的访问,以及更多其他功能。

查看完整的 LoaderContext 属性列表,了解 load() 函数的所有可用选项。

在加载器中提供 Zod schema 模式,可让你在将获取的内容条目添加到数据 存储 之前,使用 parseData() 对其进行验证。当 src/content.config.ts 中不存在 schema 模式时,该模式还将作为集合的默认模式,以提供类型安全和编辑器工具支持。如果加载器已提供此属性,则无需在内容集合中再额外定义模式。

但是,如果内容集合也 定义了 schema 模式,则将使用该模式而非加载器的模式。这是为了允许加载器的用户扩展其 schema 模式,或转换数据以在其项目中使用。如果你正在 发布和分发供他人使用的加载器,你可能希望记录此行为,并建议用户不要自行定义集合模式,或者如果他们需要以不同格式返回数据时,应如何安全地执行此操作。

如果你需要根据配置选项或通过内省 API 来动态生成模式,可以改用 createSchema()

以下示例展示了一个加载器,它从提供的 feed URL 获取数据(使用自定义的 loadFeedData 工具),并在每次构建网站时将新条目更新到数据存储中:

src/feed-loader.ts
// 1. 导入 `Loader` 类型以及其他所需的依赖项
import type { Loader } from 'astro/loaders';
import { z } from 'astro/zod';
import { loadFeedData } from "./feed.js";
// 2. 定义你的加载器所需的任何选项
export function feedLoader(options: { url: string, apiKey: string }) {
const feedUrl = new URL(options.url);
// 3. 返回一个加载器对象
return {
name: "feed-loader",
load: async ({ store, parseData }) => {
const feed = await loadFeedData(feedUrl, options.apiKey);
store.clear();
for (const item of feed.items) {
const id = item.guid;
const data = await parseData({
id,
data: item,
});
store.set({
id,
data,
});
}
},
// 4. 定义条目的模式
schema: z.object({
// ...
})
} satisfies Loader;
}

src/content.config.ts 中定义集合时,将自定义加载器作为 loader 属性的值使用。配置选项可以作为参数传递给加载器:

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

对于不需要自定义数据存储处理、验证、日志记录或 构建时加载器对象 所提供的任何其他辅助功能的简单数据获取,你可以将加载器定义为一个函数。

该函数可以是异步的,且必须返回一个数组(数组中每个条目都包含唯一的 id 字段),或者返回一个对象(其中每个键是唯一的 ID,每个值是对应的条目)。

该模式提供了一种便捷的简写方式,用于完成通常由 load() 函数执行的基本任务,即 将集合加载到数据存储中。在构建时,加载器将自动清除数据存储并重新加载所有条目。不提供任何进一步的自定义选项或数据处理辅助工具。

这些加载器通常足够简单,你可以选择在 src/content.config.ts 文件中以内联方式定义它们:

src/content.config.ts
import { defineCollection } from "astro:content";
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,
}));
},
});
export const collections = { countries };

实时加载器 API 专为实时查询任意数据而构建。实时加载器可以过滤传入数据,并通过类型安全验证内容。由于实时加载器在每次请求时都会重新获取最新数据,因此无需更新数据存储。实时加载器设计为返回数据或 Error 对象,以便你能够优雅地处理错误。

大多数实时加载器会导出一个函数,该函数接受配置选项并返回一个 实时加载器对象,其中包括加载器的 name 以及两个用于定义如何加载条目集合和如何加载单个条目的方法:loadCollection()loadEntry()

要返回有关集合的数据,你必须提供一个用于获取数据的 loadCollection() 函数,并返回一个内容 entries 数组或一个错误。

要返回单个实时集合条目,你必须提供一个获取按给定 id 过滤的数据的 loadEntry() 函数,返回单个 entryundefined 或一个错误。

这两个函数的数据获取通常使用 try...catch 语句处理访问实时数据时的错误

请查看完整的 实时加载器 API,了解更多用于构建实时加载器的函数和类型的内容。

实时加载器不包含 schema 模式属性。相反,你可以通过在 src/live.config.ts为你的集合定义 Zod 模式,或者通过将泛型类型传递给 LiveLoader 接口来为其返回的数据提供类型安全。

以下示例展示了一个实时加载器,它定义了从 CMS 获取数据的方式(使用自定义的 fetchFromCMS 工具),涵盖条目集合和单个条目的获取,包括类型安全和错误处理:

src/article-loader.ts
import type { LiveLoader } from 'astro/loaders';
import { fetchFromCMS } from './cms-client.js';
interface Article {
id: string;
title: string;
htmlContent: string;
author: string;
}
interface EntryFilter {
id: string;
}
interface CollectionFilter {
author?: string;
}
export function articleLoader(config: { apiKey: string }): LiveLoader<Article, EntryFilter, CollectionFilter> {
return {
name: 'article-loader',
loadCollection: async ({ filter }) => {
try {
const articles = await fetchFromCMS({
apiKey: config.apiKey,
type: 'article',
filter,
});
return {
entries: articles.map((article) => ({
id: article.id,
data: article,
})),
};
} catch (error) {
return {
error: new Error('Failed to load articles', { cause: error }),
};
}
},
loadEntry: async ({ filter }) => {
try {
// 当使用字符串调用时,filter 将为 { id: "some-id" }
const article = await fetchFromCMS({
apiKey: config.apiKey,
type: 'article',
id: filter.id,
});
if (!article) {
return {
error: new Error('Article not found'),
};
}
return {
id: article.id,
data: article,
rendered: {
html: article.htmlContent,
},
};
} catch (error) {
return {
error: new Error('Failed to load article', { cause: error }),
};
}
},
};
}

src/live.config.ts 中定义集合时,将自定义实时加载器作为 loader 属性的值使用。配置选项可以作为参数传递给加载器:

src/live.config.ts
import { defineLiveCollection } from 'astro:content';
import { articleLoader } from './article-loader.ts';
const blog = defineLiveCollection({
loader: articleLoader({
apiKey: "my-secret",
}),
});
export const collections = { blog };

实时加载器为错误返回一个 Error 子类。如果需要,你可以创建 自定义错误类型 并将其用于更具体的错误处理。如果在实时加载器中抛出错误,它将被捕获并返回,包装在 LiveCollectionError 中。

Astro 将根据实时加载器的响应自行生成一些错误:

  • 如果 loadEntry 返回 undefined, Astro 将会返回 LiveEntryNotFoundError 给用户。
  • 如果为集合定义了 schema 且数据与 schema 不匹配,Astro 将会返回 LiveCollectionValidationError
  • 如果加载器返回了无效的缓存提示,Astro 将会返回 LiveCollectionCacheHintErrorcacheHint 字段是可选的,因此如果你没有有效的数据可返回,可以直接省略它。
my-loader.ts
import type { LiveLoader } from 'astro/loaders';
import type { MyData } from "./types";
import { MyLoaderError } from './errors';
export function myLoader(config): LiveLoader<MyData, never, never, MyLoaderError> {
return {
name: 'my-loader',
loadCollection: async () => {
// 返回你的自定义错误类型
return {
error: new MyLoaderError('Failed to load', 'LOAD_ERROR'),
};
},
// ...
};
}

你可以为 加载器返回的错误 创建自定义错误类型,并将它们作为泛型传递以获得正确的类型:

my-loader.ts
import type { LiveLoader } from "astro/loaders";
import type { MyData } from "./types"
export class MyLoaderError extends Error {
constructor(message: string, public code?: string) {
super(message);
this.name = 'MyLoaderError';
}
}
export function myLoader(config): LiveLoader<MyData, never, never, MyLoaderError> {
return {
name: 'my-loader',
loadCollection: async () => {
// 返回你的自定义错误类型
return {
error: new MyLoaderError('Failed to load', 'LOAD_ERROR'),
};
},
// ...
};
}

当你使用 getLiveCollection()getLiveEntry() 时,TypeScript 会推断自定义错误类型,让你能够对应地处理它:

---
export const prerender = false; // Not needed in 'server' mode
import { getLiveEntry } from 'astro:content';
import { MyLoaderError } from "../my-loader";
const { entry, error } = await getLiveEntry('products', '123');
if (error) {
if (error instanceof MyLoaderError) {
console.error(`Loader error: ${error.message} (code: ${error.code})`);
} else {
console.error(`Unexpected error: ${error.message}`);
}
return Astro.rewrite('/500');
}
---

实时加载器可以为 getLiveCollection()getLiveEntry() 定义自定义筛选器类型。这会启用匹配你的 API 能力的类型安全的查询,让用户更容易发现可用的筛选器并确保正确使用。如果在筛选器类型中包含 JSDoc 注释,用户在使用加载器时将在其 IDE 中看到这些提示。

store-loader.ts
import type { LiveLoader } from 'astro/loaders';
import { fetchProduct, fetchCategory, type Product } from './store-client';
interface CollectionFilter {
category?: string;
/** 筛选产品的最低价格 */
minPrice?: number;
/** 筛选产品的最高价格 */
maxPrice?: number;
}
interface EntryFilter {
/** `sku` 的别名 */
id?: string;
slug?: string;
sku?: string;
}
export function productLoader(config: {
apiKey: string;
endpoint: string;
}): LiveLoader<Product, EntryFilter, CollectionFilter> {
return {
name: 'product-loader',
loadCollection: async ({ filter }) => {
// filter 被类型化为 CollectionFilter
const data = await fetchCategory({
apiKey: config.apiKey,
category: filter?.category ?? 'all',
minPrice: filter?.minPrice,
maxPrice: filter?.maxPrice,
});
return {
entries: data.products.map((product) => ({
id: product.sku,
data: product,
})),
};
},
loadEntry: async ({ filter }) => {
// filter 被类型化为 EntryFilter | { id: string }
const product = await fetchProduct({
apiKey: config.apiKey,
slug: filter.slug,
sku: filter.sku || filter.id,
});
if (!product) {
return {
error: new Error('Product not found'),
};
}
return {
id: product.sku,
data: product,
};
},
};
}

实时加载器可以提供缓存提示,以帮助进行响应缓存。你可以使用这些数据来发送 HTTP 缓存头,或以其他方式告知你的缓存策略。

my-loader.ts
import type { LiveLoader } from "astro/loaders";
import { loadStoreProduct, loadStoreProducts, getLastModifiedDate } from "./store";
import type { Product, ProductEntryFilter, ProductCollectionFilter } from "./types";
export function myLoader(config): LiveLoader<Product, ProductEntryFilter, ProductCollectionFilter> {
return {
name: 'cached-loader',
loadCollection: async ({ filter }) => {
const products = await loadStoreProducts(filter);
return {
entries: products.map((item) => ({
id: item.id,
data: item,
// 你可以为每个条目选择性地提供缓存提示
cacheHint: {
tags: [`product-${item.id}`, `category-${item.category}`],
},
})),
cacheHint: {
// 所有字段都是可选的,并与每个条目的缓存提示合并
// tags 从所有条目中合并
// lastModified 是所有条目和集合中最新的 lastModified
lastModified: getLastModifiedDate(products),
tags: ['products'],
},
};
},
loadEntry: async ({ filter }) => {
const item = await loadStoreProduct(filter);
return {
id: item.id,
data: item,
cacheHint: {
lastModified: new Date(item.lastModified),
tags: [`product-${item.id}`, `category-${item.category}`],
},
};
},
};
}

然后你可以在你的页面中使用这些提示。如果你启用了 实验性路由缓存 (EN),请直接将缓存提示传递给 Astro.cache.set():

src/pages/store/[id].astro
---
export const prerender = false; // 无需 'server' 模式
import { getLiveEntry } from 'astro:content';
const { entry, error, cacheHint } = await getLiveEntry('products', Astro.params.id);
if (error) {
return Astro.redirect('/404');
}
// 传递缓存提示给路由缓存
if (cacheHint) {
Astro.cache.set(cacheHint);
}
Astro.cache.set({ maxAge: 300 });
---
<h1>{entry.data.name}</h1>
<p>{entry.data.description}</p>

在未启用路由缓存的情况下,你可以使用缓存提示手动设置响应标头,以实现你自己的缓存策略:

src/pages/store/[id].astro
---
export const prerender = false; // 无需 'server' 模式
import { getLiveEntry } from 'astro:content';
const { entry, error, cacheHint } = await getLiveEntry('products', Astro.params.id);
if (error) {
return Astro.redirect('/404');
}
if (cacheHint?.tags) {
Astro.response.headers.set('Cache-Tag', cacheHint.tags.join(','));
}
if (cacheHint?.lastModified) {
Astro.response.headers.set('Last-Modified', cacheHint.lastModified.toUTCString());
}
---
<h1>{entry.data.name}</h1>
<p>{entry.data.description}</p>

加载器可以在你的网站中定义,也可以作为单独的 npm 包。如果你想与社区分享你的加载器,可以 使用 withastro 和 astro-loader 关键词将其发布到 npm (EN)

加载器应导出一个函数,该函数为实时加载器返回 LiveLoader 对象,或为构建时加载器返回 Loader 对象,从而允许用户使用他们自己的设置进行配置。

添加于: astro@5.0.0

本节展示了用于定义 构建时对象加载器 的 API。

类型: Loader

加载器函数返回一个包含两个必需属性的对象。除了为加载器提供名称外,该对象还描述了如何获取集合数据。

可选地,你可以返回第三个属性来定义一个用于验证集合条目的模式。使用 TypeScript 的 satisfies 操作符,而不是返回类型注解,以便在加载器对象内部提供类型安全,并在加载器用于集合时保留类型推断。

类型: string

添加于: astro@5.0.0

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

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

添加于: astro@5.0.0

它会接收一个 LoaderContext 对象,该对象包含用于编写加载器实现逻辑的辅助函数和属性,以及 store 数据库和与其交互的方法。

类型: ZodSchema

添加于: astro@5.0.0

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

当你需要基于配置选项或通过内省 API 在构建时动态生成模式时,请改用 createSchema()

如果存在,它将被 src/content.config.ts 文件中为集合定义的任何 Zod schema 覆盖。

类型: () => Promise<{ schema: ZodSchema; types: string }>

添加于: astro@6.0.0

一个可选的异步函数,返回一个包含 Zod 模式 和类型的对象。它用于在构建时根据配置选项或通过 API 自省来动态生成模式。

当你只需要提供一个静态模式时,请改用 schema 提供一个 Zod 验证对象。

如果存在,它将被 src/content.config.ts 文件中为该集合定义的任何 Zod schema 覆盖。

返回的 types 内容将被写入一个 TypeScript 文件,并且必须导出一个 Entry 类型或接口:

src/feed-loader.ts
import type { Loader } from 'astro/loaders';
import { z } from 'astro/zod';
import { loadFeedData, getSchema, getTypes } from "./feed.js";
export function myLoader(options: { url: string, apiKey: string }) {
const feedUrl = new URL(options.url);
return {
name: "feed-loader",
load: async ({ store, parseData }) => {
const feed = await loadFeedData(feedUrl, options.apiKey);
store.clear();
for (const item of feed.items) {
const id = item.guid;
const data = await parseData({
id,
data: item,
});
store.set({
id,
data,
});
}
},
createSchema: async () => {
const schema = await getSchema();
const types = await getTypes();
return {
schema,
types: `export type Entry = ${types}`,
};
},
} satisfies Loader;
}

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

类型: string

添加于: astro@5.0.0

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

类型: DataStore

添加于: astro@5.0.0

存储实际数据的数据库。使用它可以用新条目更新存储部分。有关更多信息,请参阅 DataStore

类型: MetaStore

添加于: astro@5.0.0

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

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

类型: AstroIntegrationLogger

添加于: astro@5.0.0

一个可用于向控制台记录消息的日志记录器。请使用此工具代替 console.log,以获得更有帮助的日志,其中包含加载器特定的内容,例如加载器名称或日志消息中有关加载过程的信息。有关更多信息,请参阅 AstroIntegrationLogger

Extract from the file() loader
return {
name: 'file-loader',
load: async ({ config, store, logger, 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);
}
});
},
};

类型: AstroConfig

添加于: astro@5.0.0

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

Extract from the file() loader
return {
name: 'file-loader',
load: async ({ config, store, logger, 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);
}
});
},
};

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

添加于: astro@5.0.0

根据集合模式验证和解析数据。将数据传递给该函数以在将其存储到数据存储中之前,对其进行验证和解析。

loader.ts
import type { Loader } from "astro/loaders";
import { loadFeed } from "./feed.js";
export function feedLoader({ url }) {
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 id = item.guid;
const data = await parseData({
id,
data: item,
});
store.set({
id,
data,
});
}
},
} satisfies Loader;
}

类型: (content: string, options?: { fileURL?: URL }) => Promise<RenderedContent>

添加于: astro@5.9.0

用于将 Markdown 字符串渲染为 HTML,返回一个 RenderedContent 对象。

该功能允许你在加载器中直接渲染 Markdown 内容,其处理逻辑与 Astro 内置的 glob() 加载器完全一致,该功能可以调用 render() 函数处理原始内容,并使用 <Content /> 组件 渲染正文内容

将该对象分配给 DataEntry 对象的 rendered 字段,以允许用户 在页面中渲染内容。如果 Markdown 内容包含 frontmatter,它将被解析并可在 metadata.frontmatter 中使用。frontmatter 将被排除在 HTML 输出之外。

loader.ts
import type { Loader } from 'astro/loaders';
import { loadFromCMS } from './cms.js';
export function myLoader(settings) {
return {
name: 'cms-loader',
async load({ renderMarkdown, store }) {
const entries = await loadFromCMS();
store.clear();
for (const entry of entries) {
store.set({
id: entry.id,
data: entry,
// 假设每个条目都包含一个带有 markdown 内容的 'content' 字段
rendered: await renderMarkdown(entry.content),
});
}
},
} satisfies Loader;
}

类型: URL

添加于: astro@6.0.0

指定用于解析 Markdown 内容中相对图片路径的文件路径。

以下示例使用 配置的根目录 来解析图片路径:

loader.ts
for (const file of files) {
const content = await readFile(file.path, 'utf8');
store.set({
id: file.id,
data: file.data,
rendered: await renderMarkdown(content, {
fileURL: new URL(file.path, config.root),
}),
});
}

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

添加于: astro@5.0.0

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

loader.ts
import type { Loader } from "astro/loaders";
import { loadFeed } from "./feed.js";
export function feedLoader({ url }) {
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 id = item.guid;
const data = await parseData({
id,
data: item,
});
const digest = generateDigest(data);
store.set({
id,
data,
digest,
});
}
},
} satisfies Loader;
}

类型:: FSWatcher

添加于: astro@5.0.0

当在开发模式下运行时,这是一个文件系统监听器,可用于触发更新。有关更多信息,请参阅 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);
}
});
},
};

类型: Record<string, unknown>

添加于: astro@5.0.0

如果加载器已经由集成触发,则可以选择性地包含该由集成所设置的额外数据。仅当加载器是被集成触发时才会设置。有关更多信息,请参阅 astro:server:setup 钩子参考。

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

数据存储是内容集合数据的加载器接口。它是一个键值(KV)存储,范围仅限于集合,因此加载器只能访问其自己集合的数据。

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

添加于: astro@5.0.0

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

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

返回的对象是一个 DataEntry 对象。

类型: (entry: DataEntry) => boolean

添加于: astro@5.0.0

在数据被 验证和解析 之后使用,从而将条目添加到存储中。如果设置了条目则返回 true。当 digest 属性确定条目未更改且不应更新时,则返回 false

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

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

添加于: astro@5.0.0

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

类型: () => Array<string>

添加于: astro@5.0.0

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

类型: () => Array<DataEntry>

添加于: astro@5.0.0

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

类型: (key: string) => void

添加于: astro@5.0.0

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

类型: () => void

添加于: astro@5.0.0

清除集合中的所有条目。

类型: (key: string) => boolean

添加于: astro@5.0.0

通过条目的 ID 从存储中检查是否存在该条目。

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

类型: string

添加于: astro@5.0.0

条目的标识符,在集合中必须是唯一的。它用于查找存储中的条目,同时也是与该集合的 getEntry() 一起使用的键。

类型: Record<string, unknown>

添加于: astro@5.0.0

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

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

类型: string | undefined

添加于: astro@5.0.0

作为此条目源的文件路径(相对于站点的根目录)。这仅适用于基于文件的加载器,并用于解析图像或其他资源等路径。

如果未设置,则模式中使用 image() 助手函数 的任何字段都将被视为位于 public 路径 下而跳过图像优化。

类型: string | undefined

添加于: astro@5.0.0

条目的原始正文(如果适用的话)。如果条目包含了 渲染内容,则该字段可用于存储原始源。该属性为可选项,内部不使用。

类型: string | undefined

添加于: astro@5.0.0

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

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

摘要的格式由加载器决定,但它必须是一个随数据变化而变化的字符串。这可以通过 generateDigest 函数来完成。

类型: RenderedContent | undefined

添加于: astro@5.0.0

存储带有条目的渲染内容和元数据(如果已渲染为 HTML)的对象。例如,这可用于存储 Markdown 条目的渲染内容或 CMS 中的 HTML。

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

如果条目包含 Markdown 内容,则可以使用 renderMarkdown() 函数从 Markdown 字符串生成此对象。

类型: string

包含渲染后的 HTML 字符串。这用于 render() 返回一个渲染此 HTML 的组件。

类型: object | undefined

描述此文件中存在的元数据。这包括 imagePathsheadingsfrontmatter 和文件中存在的任何其他元数据。当文件尚未渲染为 HTML 时,此值将为 undefined。

类型: string[]

指定此条目中存在的图像路径列表。每个路径相对于 条目的 filePath

类型: MarkdownHeading[]

指定此文件中存在的标题列表。每个标题由标题级别(h1 -> h6)确定的 depth、由 github-slugger 生成的 slug 和其 text 内容描述。

类型: Record<string, any>

描述从文件中解析的原始前置数据。这可能包括 由 remark 插件以编程方式注入的数据

添加于: astro@6.0.0

本部分展示了用于定义 实时加载器 的 API。

类型: LiveLoader<TData, TEntryFilter, TCollectionFilter, TError>

添加于: astro@6.0.0

实时加载器函数返回一个具有三个必需的实时加载器属性的对象。除了为加载器提供名称外,该对象还描述了如何从实时数据源中获取单个条目和整个集合。

使用 LiveLoader 泛型为你的加载器提供类型安全。此类型按以下顺序接受以下类型参数:

  • TData (默认为 Record<string, unknown>):加载器返回的每个条目的数据结构。
  • TEntryFilter (默认为 never):getLiveEntry() 接受的筛选对象类型,在 loadEntry() 中可访问。当不支持筛选单个条目时,使用 never
  • TCollectionFilter (默认为 never):getLiveCollection() 接受的筛选对象类型,在 loadCollection() 中可访问。当不支持筛选单个条目时,使用 never
  • TError (默认为 Error):加载器可以返回的 自定义 Error,用于更细粒度的错误处理。

类型: string

添加于: astro@6.0.0

加载器的唯一名称,用于日志中。

类型: (context: LoadCollectionContext<TCollectionFilter>) => Promise<LiveDataCollection<TData> | { error: TError; }>

添加于: astro@6.0.0

定义一个加载条目集合的方法。此函数接收一个包含可选 filter 属性的 上下文对象,并且必须返回与此集合关联的数据或错误。

类型: (context: LoadEntryContext<TEntryFilter>) => Promise<LiveDataEntry<TData> | undefined | { error: TError; }>

添加于: astro@6.0.0

定义了一个加载单个条目的方法。此函数接收一个包含 filter 属性的 上下文对象,并返回与请求的条目相关联的数据、当找不到该条目时返回 undefined,或返回错误信息。

类型: { filter?: TCollectionFilter; }

添加于: astro@6.0.0

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

类型: Record<string, any> | never
默认值: never

添加于: astro@6.0.0

一个描述 你的加载器支持的筛选器 的对象。

类型: { filter: TEntryFilter; }

添加于: astro@6.0.0

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

类型: Record<string, any> | never
默认值: never

添加于: astro@6.0.0

一个描述 你的加载器支持的筛选器 的对象。

类型: { id: string; data: TData; rendered?: { html: string }; cacheHint?: CacheHint; }

添加于: astro@6.0.0

这是由 loadEntry() 方法返回的类型对象。它包含以下属性:

类型: string

添加于: astro@6.0.0

条目的标识符,在集合中必须是唯一的。这是与该集合的 getLiveEntry()方法一起使用的键。

类型: Record<string, unknown>

添加于: astro@6.0.0

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

加载器负责在返回数据之前验证和解析数据。

类型: { html: string }

添加于: astro@6.0.0

一个包含条目已渲染内容的对象,如果该内容已被渲染为 HTML。例如,这可以是 Markdown 条目的渲染内容,或来自 CMS 的 HTML。

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

如果加载器没有为条目返回 rendered 属性,<Content /> 组件将不会渲染任何内容。

类型: CacheHint

添加于: astro@6.0.0

一个可选对象,用于提供关于如何缓存此特定条目的提示。

类型: { entries: Array<LiveDataEntry<TData>>; cacheHint?: CacheHint; }

添加于: astro@6.0.0

这是由 loadCollection() 方法返回的类型对象。它包含以下属性:

类型: Array<LiveDataEntry<TData>>

添加于: astro@6.0.0

一个 LiveDataEntry 对象数组。

类型: CacheHint

添加于: astro@6.0.0

一个可选对象,提供关于如何缓存此集合的指导。如果提供了此对象,它将与为每个单独条目定义的缓存提示合并。

一个对象,加载器可以通过 LiveDataCollectionLiveDataEntry 中的 cacheHint 属性返回该对象,以提供提示来协助缓存响应。该对象包含以下属性:

类型: Array<string>

添加于: astro@6.0.0

一个字符串标识符数组,允许细粒度的缓存控制。这使你能够对相关内容进行分组,并在特定内容更改时选择性地使缓存的响应失效。

以下示例为按作者筛选的文章集合定义了缓存提示标签:

return {
/* ... */
cacheHint: {
tags: ["posts", `posts-${filter.author}`],
},
};

类型: Date

添加于: astro@6.0.0

内容的最后修改日期(例如,集合中条目的最后更新时间)。这可用于设置 HTTP 缓存头,如 Last-ModifiedIf-Modified-Since

以下示例使用产品的最后更新日期为单个产品定义缓存提示:

return {
/* ... */
cacheHint: {
lastModified: new Date(product.updatedAt)
},
};
贡献 社区 赞助