API de Cargador de Contenido de Astro
La API de Cargador de Contenido de Astro te permite cargar tus datos desde cualquier origen, local o remoto, e interactuar con la capa de contenido de Astro para gestionar tus colecciones de contenido.
Esta API incluye dos cargadores listos para usar para contenido almacenado localmente. También proporciona herramientas para construir tus propios objetos personalizados que pueden cargar datos desde cualquier origen en colecciones de contenido.
Cargadores en tiempo de construcción
Sección titulada “Cargadores en tiempo de construcción”Los cargadores en tiempo de construcción son objetos con un método load() que se llama en tiempo de construcción para recuperar datos y actualizar el almacén de datos. Este objeto también puede definir un esquema para las entradas, que se puede utilizar para validar los datos y generar tipos estáticos.
Los cargadores glob() y file() de Astro son ejemplos de cargadores de objetos que se proporcionan de forma predeterminada para su uso con contenido local. Para contenido remoto, no se proporcionan cargadores preconstruidos. Tendrás que construir un cargador de objetos o utilizar un cargador publicado por la comunidad para recuperar contenido remoto e interactuar con el almacén de datos.
Para una recuperación de datos simple, también puedes definir un cargador como una función asíncrona que devuelva un array u objeto que contenga las entradas.
cargador glob()
Sección titulada “cargador glob()”Type: (options: GlobOptions) => Loader
astro@5.0.0
El cargador glob() crea entradas a partir de directorios de archivos de cualquier parte del sistema de archivos. Los tipos de archivos admitidos son archivos Markdown, MDX, Markdoc, JSON, YAML y TOML.
Este cargador acepta un objeto con las siguientes propiedades: pattern, base (opcional), generateId (opcional) y retainBody (opcional).
import { defineCollection } from 'astro:content';import { glob } from 'astro/loaders';
const pages = defineCollection({ /* Retrieve all Markdown files in your pages directory. */ loader: glob({ pattern: "**/*.md", base: "./src/data/pages" }),});const blog = defineCollection({ /* Retrieve all Markdown and MDX files in your blog directory. */ loader: glob({ pattern: "**/*.(md|mdx)", base: "./src/data/blog" }),});const notes = defineCollection({ /* Retrieve all Markdown files in your notes directory and prevent * the raw body of content files from being stored in the data store. */ loader: glob({ pattern: '**/*.md', base: './src/data/notes', retainBody: false }),});const authors = defineCollection({ /* Retrieve all JSON files in your authors directory while retaining * uppercase letters in the ID. */ loader: glob({ pattern: '**/*.json', base: "./src/data/authors", generateId: ({ entry }) => entry.replace(/\.json$/, ''), }),});
export const collections = { pages, blog, authors };pattern
Sección titulada “pattern”Type: string | string[]
La propiedad pattern acepta una cadena o un array de cadenas utilizando coincidencias de glob (por ejemplo, comodines, globstars). Los patrones deben ser relativos al directorio base de los archivos de entrada a coincidir.
Puedes aprender más sobre la sintaxis a utilizar en la documentación de micromatch. También puedes verificar la validez de tu patrón utilizando una herramienta en línea como DigitalOcean Glob Tool.
Type: string | URL
Default: "."
Una ruta relativa o URL al directorio desde el cual resolver el pattern.
generateId()
Sección titulada “generateId()”Type: (options: GenerateIdOptions) => string
Una función callback que devuelve una cadena única por entrada en una colección. Acepta un objeto como parámetro con las siguientes propiedades:
entry- la ruta al archivo de entrada, relativa al directorio basebase- la URL del directorio basedata- los datos analizados y no validados de la entrada
Por defecto utiliza github-slugger para generar un slug con palabras en kebab-case.
retainBody
Sección titulada “retainBody”Type: boolean
Default: true
astro@5.17.0
Indica si se debe almacenar o no el cuerpo sin procesar (raw body) de los archivos de contenido en el almacén de datos.
Cuando retainBody es false, entry.body será undefined en lugar de contener el contenido del archivo sin procesar.
Establecer esta propiedad en false reduce significativamente el tamaño desplegado del almacén de datos y ayuda a evitar alcanzar los límites de tamaño para sitios con colecciones muy grandes.
Para archivos Markdown, el cuerpo renderizado seguirá estando disponible en la propiedad entry.rendered.html, y la propiedad entry.filePath seguirá apuntando al archivo original.
Para colecciones de MDX, esto reducirá drásticamente el tamaño de la colección, ya que ya no se conservará ningún cuerpo en el almacén.
cargador file()
Sección titulada “cargador file()”Type: (fileName: string, options?: FileOptions) => Loader
astro@5.0.0
El cargador file() crea entradas a partir de un solo archivo que contiene un array de objetos con un campo id único, o un objeto con IDs como claves y entradas como valores.
Soporta archivos JSON, YAML o TOML y puedes proporcionar un parser personalizado para archivos de datos que no puede analizar por defecto, o para analizar datos de forma asíncrona.
Este cargador acepta una propiedad fileName y un objeto de opciones opcional como segundo argumento:
import { defineCollection } from 'astro:content';import { file } from 'astro/loaders';
const authors = defineCollection({ /* Retrieve all entries from a JSON file. */ loader: file("src/data/authors.json"),});const products = defineCollection({ /* Retrieve all entries from a CSV file using a custom parser. */ loader: file("src/data/products.csv", { parser: (fileContent) => { /* your parser logic */ }, }),});
export const collections = { authors, products };fileName
Sección titulada “fileName”Type: string
Establece la ruta al archivo a cargar, relativa al directorio raíz.
Opciones
Sección titulada «Opciones»Type: FileOptions
Un objeto opcional con las siguientes propiedades:
parser()
Sección titulada “parser()”Tipo: (text: string) => Record<string, Record<string, unknown>> | Array<Record<string, unknown>> | Promise<Record<string, Record<string, unknown>> | Array<Record<string, unknown>>>
Una función callback para crear una colección a partir del contenido de un archivo. Úsala cuando necesites procesar archivos distintos de JSON, YAML o TOML que no sean compatibles por defecto (por ejemplo, .csv) o al usar documentos .json anidados.
Construir un cargador
Sección titulada “Construir un cargador”La API de Cargador de Contenido es flexible y completa, lo que permite una variedad de opciones de recuperación de datos. Es posible construir cargadores tanto simples como complejos. Tu cargador personalizado dependerá tanto del origen como de la forma de tus datos, así como de cómo elijas gestionar la capa de almacenamiento persistente de datos.
La mayoría de los cargadores exportarán una función que acepta opciones de configuración y devuelve un objeto cargador que incluye un nombre (name) para tu cargador, un método load() y un esquema (schema) que define tus entradas.
Cargar colecciones en el almacén de datos
Sección titulada “Cargar colecciones en el almacén de datos”La función load() devuelta en el objeto cargador define cómo se recupera, analiza, valida y actualiza tu contenido. Acepta un objeto context que te permite personalizar el manejo de tus datos de diversas maneras e interactuar con el almacén de datos. Una función load() típica hará lo siguiente:
- Recupera tus datos de un origen.
- Limpia el almacén de datos existente.
- Analiza y valida tus entradas de datos de acuerdo con un esquema proporcionado.
- Actualiza el almacén de datos con las nuevas entradas.
El método load() también proporciona funciones auxiliares para registrar mensajes en la consola, renderizar contenido a HTML, vigilar cambios en modo de desarrollo y recargar datos, proporcionar acceso a metadatos e incluso a la configuración completa de Astro, y más.
LoaderContext para conocer todas las opciones disponibles para la función load().
Proporcionar un esquema
Sección titulada “Proporcionar un esquema”Proporcionar un esquema (schema) de Zod en tu cargador te permite validar tus entradas de contenido recuperadas con parseData() antes de agregarlas al almacén (store) de datos. Este esquema también se utilizará como el esquema predeterminado de la colección cuando no exista uno en src/content.config.ts para proporcionar seguridad de tipos y herramientas de edición. Tampoco necesitas un esquema definido en la colección de contenido si el cargador proporciona esta propiedad.
Sin embargo, si la colección de contenido también define un esquema, se utilizará ese esquema en lugar del esquema de tu cargador. Esto es para permitir a los usuarios de tu cargador extender su esquema, o transformar datos para su uso en su proyecto. Si estás publicando y distribuyendo un cargador para que otros lo usen, es posible que desees documentar este comportamiento y alentar a los usuarios a no definir un esquema de colección ellos mismos, o cómo hacerlo de manera segura si necesitan que los datos se devuelvan en un formato diferente.
Si necesitas generar dinámicamente el esquema basado en las opciones de configuración o introspeccionando una API, ya puedes usar createSchema() en su lugar.
Ejemplo de cargador
Sección titulada “Ejemplo de cargador”El siguiente ejemplo muestra un cargador que recupera datos de una URL de feed proporcionada (utilizando una utilidad personalizada loadFeedData) y actualiza el almacén de datos con nuevas entradas cada vez que se construye el sitio:
// 1. Import the `Loader` type and any other dependencies neededimport type { Loader } from 'astro/loaders';import { z } from 'astro/zod';import { loadFeedData } from "./feed.js";
// 2. Define any options that your loader needsexport function feedLoader(options: { url: string, apiKey: string }) { const feedUrl = new URL(options.url); // 3. Return a loader object 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. Define the schema of an entry. schema: z.object({ // ... }) } satisfies Loader;}Definir tu colección con tu cargador
Sección titulada “Definir tu colección con tu cargador”Usa tu cargador personalizado como el valor de la propiedad loader cuando definas tu colección en src/content.config.ts. Las opciones de configuración se pueden pasar a tu cargador como argumentos:
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 };Definir un cargador como una función
Sección titulada “Definir un cargador como una función”Para recuperaciones de datos simples que no necesitan un manejo personalizado del almacén de datos, validación, registro o cualquier otra ayuda proporcionada por el objeto cargador en tiempo de construcción, puedes definir tu cargador como una función.
La función puede ser asíncrona y debe devolver un array de entradas donde cada una contenga un campo id único, o bien un objeto donde cada clave sea un ID único y cada valor sea la entrada.
Este patrón proporciona un atajo conveniente para lograr las tareas básicas que normalmente realiza la función load() para cargar colecciones en el almacén de datos. En el tiempo de construcción, el cargador limpiará automáticamente el almacén de datos y volverá a cargar todas las entradas. No se proporcionan más opciones de personalización ni funciones auxiliares para el manejo de datos.
Estos cargadores suelen ser lo suficientemente simples como para que puedas elegir definirlos en línea en el archivo 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(); // 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, })); },});
export const collections = { countries };Cargadores en tiempo real (Live Loaders)
Sección titulada “Cargadores en tiempo real (Live Loaders)”La API de Cargador en Tiempo Real (Live Loader API) está diseñada para manejar la consulta de cualquier dato en tiempo real. Los cargadores en tiempo real pueden filtrar los datos entrantes y verificar el contenido con seguridad de tipos. Dado que los cargadores en tiempo real recuperan datos frescos en cada solicitud, no hay almacén de datos que actualizar. Estos cargadores están diseñados para devolver datos o un objeto Error para permitirte manejar los errores de manera elegante.
Construir un cargador en tiempo real
Sección titulada “Construir un cargador en tiempo real”La mayoría de los cargadores en tiempo real exportarán una función que acepta opciones de configuración y devuelve un objeto cargador en tiempo real que incluye un nombre (name) para tu cargador y dos métodos para definir cómo cargar tu colección de entradas y cómo cargar una sola entrada: loadCollection() y loadEntry().
Cargar datos en tiempo real
Sección titulada “Cargar datos en tiempo real”Para devolver datos sobre tu colección, debes proporcionar una función loadCollection() que recupere los datos y devuelva un array de entradas (entries) de contenido o un error.
Para devolver una sola entrada de la colección en tiempo real, debes proporcionar una función loadEntry() que recupere los datos filtrados para un id determinado y devuelva una sola entrada (entry), undefined o un error.
La recuperación de datos para ambas funciones se realiza normalmente utilizando una declaración try...catch para manejar errores al acceder a datos en tiempo real.
Proporcionar un esquema para cargadores en tiempo real
Sección titulada “Proporcionar un esquema para cargadores en tiempo real”Los cargadores en tiempo real no incluyen una propiedad de esquema. En su lugar, puedes proporcionar seguridad de tipos definiendo un esquema de Zod para tu colección en src/live.config.ts, o pasando tipos genéricos a la interfaz LiveLoader para los datos que devuelven.
Ejemplo de cargador en tiempo real
Sección titulada “Ejemplo de cargador en tiempo real”El siguiente ejemplo muestra un cargador en tiempo real que define la recuperación de datos desde un CMS (utilizando una utilidad personalizada fetchFromCMS) tanto para una colección de entradas como para una sola entrada, incluyendo seguridad de tipos y manejo de errores:
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 will be { id: "some-id" } when called with a string 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 }), }; } }, };}Definir tu colección en tiempo real con tu cargador
Sección titulada “Definir tu colección en tiempo real con tu cargador”Usa tu cargador en tiempo real personalizado como el valor de la propiedad loader cuando definas tu colección en src/live.config.ts. Las opciones de configuración se pueden pasar a tu cargador como argumentos:
import { defineLiveCollection } from 'astro:content';import { articleLoader } from './article-loader.ts';
const blog = defineLiveCollection({ loader: articleLoader({ apiKey: "my-secret", }),});
export const collections = { blog };Manejo de errores en cargadores en tiempo real
Sección titulada “Manejo de errores en cargadores en tiempo real”Los cargadores en tiempo real devuelven una subclase de Error para los errores. Puedes crear tipos de error personalizados y usarlos para un manejo de errores más específico si es necesario. Si se lanza un error en el cargador en tiempo real, se capturará y se devolverá envuelto en un LiveCollectionError.
El propio Astro generará algunos errores, dependiendo de la respuesta del cargador en tiempo real:
- Si
loadEntrydevuelveundefined, Astro devolverá unLiveEntryNotFoundErroral usuario. - Si se define un esquema para la colección y los datos no coinciden con el esquema, Astro devolverá un
LiveCollectionValidationError. - Si el cargador devuelve una pista de caché no válida, Astro devolverá un
LiveCollectionCacheHintError. El campocacheHintes opcional, por lo que si no tienes datos válidos para devolver, simplemente puedes omitirlo.
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 your custom error type return { error: new MyLoaderError('Failed to load', 'LOAD_ERROR'), }; }, // ... };}Crear tipos de error de cargador en tiempo real
Sección titulada “Crear tipos de error de cargador en tiempo real”Puedes crear tipos de error personalizados para los errores devueltos por tu cargador y pasarlos como un genérico para obtener un tipado correcto:
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 your custom error type return { error: new MyLoaderError('Failed to load', 'LOAD_ERROR'), }; }, // ... };}Cuando usas getLiveCollection() o getLiveEntry(), TypeScript inferirá el tipo de error personalizado, permitiéndote manejarlo de manera adecuada:
---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');}---Definir tipos de filtro personalizados
Sección titulada “Definir tipos de filtro personalizados”Los cargadores en tiempo real pueden definir tipos de filtro personalizados tanto para getLiveCollection() como para getLiveEntry(). Esto permite realizar consultas seguras en cuanto a tipos que coincidan con las capacidades de tu API, lo que facilita a los usuarios descubrir los filtros disponibles y asegurarse de que se utilicen correctamente. Si incluyes comentarios JSDoc en tus tipos de filtro, el usuario los verá en su IDE como sugerencias al usar el cargador.
import type { LiveLoader } from 'astro/loaders';import { fetchProduct, fetchCategory, type Product } from './store-client';
interface CollectionFilter { category?: string; /** Minimum price to filter products */ minPrice?: number; /** Maximum price to filter products */ maxPrice?: number;}
interface EntryFilter { /** Alias for `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 is typed as 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 is typed as 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, }; }, };}Pistas de caché (cache hints)
Sección titulada “Pistas de caché (cache hints)”Los cargadores en tiempo real pueden proporcionar pistas de caché para ayudar con el almacenamiento en caché de respuestas. Puedes usar estos datos para enviar cabeceras de caché HTTP o informar de alguna otra manera tu estrategia de almacenamiento en caché.
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, // You can optionally provide cache hints for each entry cacheHint: { tags: [`product-${item.id}`, `category-${item.category}`], }, })), cacheHint: { // All fields are optional, and are combined with each entry's cache hints // tags are merged from all entries // lastModified is the most recent lastModified of all entries and the collection 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}`], }, }; }, };}Luego puedes usar estas pistas en tus páginas. Si has configurado un proveedor de caché, pasa las pistas de caché directamente a Astro.cache.set():
---export const prerender = false; // Not needed in 'server' mode
import { getLiveEntry } from 'astro:content';
const { entry, error, cacheHint } = await getLiveEntry('products', Astro.params.id);
if (error) { return Astro.redirect('/404');}
// Pass cache hints to route cachingif (cacheHint) { Astro.cache.set(cacheHint);}Astro.cache.set({ maxAge: 300 });---
<h1>{entry.data.name}</h1><p>{entry.data.description}</p>Sin un proveedor de caché, puedes usar pistas de caché para establecer cabeceras de respuesta manualmente para tu propia estrategia de almacenamiento en caché:
---export const prerender = false; // Not needed in 'server' mode
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>Las pistas de caché no hacen automáticamente que Astro almacene en caché la respuesta. Proporcionan valores que puedes pasar al almacenamiento en caché de rutas o usar para implementar tu propia estrategia de almacenamiento en caché.
Distribuir tu cargador
Sección titulada “Distribuir tu cargador”Los cargadores se pueden definir en tu sitio o como un paquete npm independiente. Si deseas compartir tu cargador con la comunidad, puedes publicarlo en npm con las palabras clave withastro y astro-loader.
Un cargador debe exportar una función que devuelva un objeto LiveLoader para cargadores en tiempo real o un objeto Loader para cargadores en tiempo de construcción, lo que permite a los usuarios configurarlo con sus propios ajustes.
API de cargador de objetos
Sección titulada “API de cargador de objetos”Añadido en:
astro@5.0.0
Esta sección muestra la API para definir un cargador de objetos en tiempo de construcción.
El objeto Loader
Sección titulada “El objeto Loader”Type: Loader
Una función de cargador devuelve un objeto con dos propiedades obligatorias. Además de proporcionar un nombre para el cargador, este objeto describe cómo recuperar los datos de la colección.
Opcionalmente, puedes devolver una tercera propiedad que defina un esquema para validar las entradas de tu colección. Usa el operador satisfies de TypeScript en lugar de una anotación de tipo de retorno para proporcionar seguridad de tipos dentro de tu objeto cargador y preservar la inferencia de tipos cuando se use tu cargador en una colección.
Loader.name
Sección titulada “Loader.name”Type: string
astro@5.0.0
Un nombre único para el cargador, utilizado en los registros y para la carga condicional.
Loader.load()
Sección titulada “Loader.load()”Type: (context: LoaderContext) => Promise<void>
astro@5.0.0
Una función asíncrona que se llama en tiempo de construcción para cargar datos y actualizar el almacén. Se le pasa un objeto LoaderContext que contiene funciones auxiliares y propiedades para escribir la lógica de implementación de tu cargador, así como la base de datos del almacén (store) y métodos para interactuar con ella.
Loader.schema
Sección titulada “Loader.schema”Type: ZodSchema
astro@5.0.0
Un esquema de Zod opcional que define la forma de las entradas. Se utiliza tanto para validar los datos como para generar tipos de TypeScript para la colección.
Cuando necesites generar dinámicamente el esquema en tiempo de construcción basándote en las opciones de configuración o introspeccionando una API, usa createSchema() en su lugar.
Si está presente, será anulado por cualquier esquema de Zod definido para la colección en el archivo src/content.config.ts.
Loader.createSchema()
Sección titulada “Loader.createSchema()”Type: () => Promise<{ schema: ZodSchema; types: string }>
astro@6.0.0
Una función asíncrona opcional que devuelve un objeto que contiene un esquema de Zod y tipos. Se utiliza para generar dinámicamente el esquema en tiempo de construcción basándose en las opciones de configuración o introspeccionando una API.
Cuando solo necesites proporcionar un esquema estático, proporciona un objeto de validación de Zod utilizando schema en su lugar.
Si está presente, será anulado por cualquier esquema de Zod definido para la colección en el archivo src/content.config.ts.
El contenido de los tipos devuelto se escribirá en un archivo TypeScript y debe exportar un tipo o interfaz de Entry:
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;}LoaderContext
Sección titulada “LoaderContext”Este objeto se pasa al método load() del cargador y contiene las siguientes propiedades:
LoaderContext.collection
Sección titulada “LoaderContext.collection”Type: string
astro@5.0.0
El nombre único de la colección. Esta es la clave en el objeto collections en el archivo src/content.config.ts.
LoaderContext.store
Sección titulada “LoaderContext.store”Type: DataStore
astro@5.0.0
Una base de datos para almacenar los datos reales. Usa esto para actualizar el almacén con nuevas entradas. Consulta DataStore para obtener más información.
LoaderContext.meta
Sección titulada “LoaderContext.meta”Type: MetaStore
astro@5.0.0
Un almacén de clave-valor limitado a la colección, diseñado para cosas como tokens de sincronización y tiempos de última modificación. Estos metadatos se persisten entre construcciones junto con los datos de la colección, pero solo están disponibles dentro del cargador.
const lastModified = meta.get("lastModified");// ...meta.set("lastModified", new Date().toISOString());LoaderContext.logger
Sección titulada “LoaderContext.logger”Type: AstroIntegrationLogger
astro@5.0.0
Un registrador (logger) que se puede utilizar para registrar mensajes en la consola. Úsalo en lugar de console.log para obtener registros más útiles que incluyan contenido específico del cargador, como el nombre del cargador o información sobre el proceso de carga en el mensaje de registro. Consulta AstroIntegrationLogger para obtener más información.
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); } }); },};LoaderContext.config
Sección titulada “LoaderContext.config”Type: AstroConfig
astro@5.0.0
El objeto de configuración de Astro completo y resuelto con todos los valores predeterminados aplicados. Consulta la referencia de configuración para obtener más información.
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); } }); },};LoaderContext.parseData()
Sección titulada “LoaderContext.parseData()”Tipo: (props: ParseDataOptions<TData>) => Promise<TData>
astro@5.0.0
Valida y analiza los datos según el esquema de la colección. Pasa datos a esta función para validarlos y analizarlos antes de guardarlos en el almacén de datos.
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;}LoaderContext.renderMarkdown()
Sección titulada “LoaderContext.renderMarkdown()”Tipo: (content: string, options?: { fileURL?: URL }) => Promise<RenderedContent>
astro@5.9.0
Renderiza una cadena Markdown a HTML, devolviendo un objeto RenderedContent.
Esto te permite renderizar contenido Markdown directamente dentro de tus cargadores usando el mismo procesamiento de Markdown que el cargador glob() incorporado de Astro y proporciona acceso a la función render() y al componente <Content /> para renderizar el contenido del cuerpo.
Asigna este objeto al campo rendered del objeto DataEntry para permitir a los usuarios renderizar el contenido en una página. Si el contenido de Markdown incluye frontmatter, se analizará y estará disponible en metadata.frontmatter. El frontmatter se excluirá de la salida HTML.
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, // Assume each entry has a 'content' field with markdown content rendered: await renderMarkdown(entry.content), }); } }, } satisfies Loader;}fileURL
Sección titulada “fileURL”Type: URL
astro@6.0.0
Especifica la ruta del archivo a usar para resolver rutas de imágenes relativas en el contenido de Markdown.
El siguiente ejemplo utiliza el directorio raíz configurado para resolver las rutas de las imágenes:
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), }), });}LoaderContext.generateDigest()
Sección titulada “LoaderContext.generateDigest()”Type: (data: Record<string, unknown> | string) => string
astro@5.0.0
Genera un resumen de contenido (digest) no criptográfico de un objeto o cadena. Esto se puede usar para rastrear si los datos han cambiado estableciendo el campo digest de una entrada.
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;}LoaderContext.watcher
Sección titulada “LoaderContext.watcher”Type: FSWatcher
astro@5.0.0
Cuando se ejecuta en modo de desarrollo, este es un vigilante (watcher) del sistema de archivos que se puede usar para activar actualizaciones. Consulta ViteDevServer para obtener más información.
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); } }); },};LoaderContext.refreshContextData
Sección titulada “LoaderContext.refreshContextData”Type: Record<string, unknown>
astro@5.0.0
Si el cargador ha sido activado por una integración, este puede contener opcionalmente datos adicionales establecidos por esa integración. Solo se establece cuando el cargador es activado por una integración. Consulta la referencia del gancho (hook) astro:server:setup para obtener más información.
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;}DataStore
Sección titulada “DataStore”El almacén de datos es la interfaz de un cargador a los datos de la colección de contenido. Es un almacén de clave-valor (KV), limitado a la colección, y por lo tanto un cargador solo puede acceder a los datos de su propia colección.
DataStore.get()
Sección titulada “DataStore.get()”Type: (key: string) => DataEntry | undefined
astro@5.0.0
Obtiene una entrada del almacén por su ID. Devuelve undefined si la entrada no existe.
const existingEntry = store.get("my-entry");El objeto devuelto es un objeto DataEntry.
DataStore.set()
Sección titulada “DataStore.set()”Type: (entry: DataEntry) => boolean
astro@5.0.0
Se utiliza después de que los datos hayan sido validados y analizados para agregar una entrada al almacén, devolviendo true si se estableció la entrada. Esto devuelve false cuando la propiedad digest determina que una entrada no ha cambiado y no debe actualizarse.
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, }); }DataStore.entries()
Sección titulada “DataStore.entries()”Type: () => Array<[id: string, DataEntry]>
astro@5.0.0
Obtiene todas las entradas de la colección como un array de pares clave-valor.
DataStore.keys()
Sección titulada “DataStore.keys()”Type: () => Array<string>
astro@5.0.0
Obtiene todas las claves de las entradas en la colección.
DataStore.values()
Sección titulada “DataStore.values()”Type: () => Array<DataEntry>
astro@5.0.0
Obtiene todas las entradas de la colección como un array.
DataStore.delete()
Sección titulada “DataStore.delete()”Type: (key: string) => void
astro@5.0.0
Elimina una entrada del almacén por su ID.
DataStore.clear()
Sección titulada “DataStore.clear()”Type: () => void
astro@5.0.0
Limpia todas las entradas de la colección.
DataStore.has()
Sección titulada “DataStore.has()”Type: (key: string) => boolean
astro@5.0.0
Comprueba si existe una entrada en el almacén por su ID.
DataEntry
Sección titulada “DataEntry”Este es el tipo del objeto que se almacena en el almacén de datos. Tiene las siguientes propiedades:
DataEntry.id
Sección titulada “DataEntry.id”Type: string
astro@5.0.0
Un identificador para la entrada, que debe ser único dentro de la colección. Esto se usa para buscar la entrada en el almacén y es la clave utilizada con getEntry() para esa colección.
DataEntry.data
Sección titulada “DataEntry.data”Type: Record<string, unknown>
astro@5.0.0
Los datos reales de la entrada. Cuando un usuario acceda a la colección, esta tendrá tipos de TypeScript generados de acuerdo con el esquema de la colección.
Es responsabilidad del cargador usar parseData() para validar y analizar los datos antes de guardarlos en el almacén de datos: no se realiza ninguna validación al obtener o establecer los datos.
DataEntry.filePath
Sección titulada “DataEntry.filePath”Type: string | undefined
astro@5.0.0
Una ruta al archivo que es el origen de esta entrada, relativa a la raíz del sitio. Esto solo se aplica a los cargadores basados en archivos y se utiliza para resolver rutas como imágenes u otros recursos.
Si no se establece, cualquier campo del esquema que use la función auxiliar image() será tratado como rutas públicas y no se transformará.
DataEntry.body
Sección titulada “DataEntry.body”Type: string | undefined
astro@5.0.0
El cuerpo sin procesar (raw body) de la entrada, si corresponde. Si la entrada incluye contenido renderizado, entonces este campo se puede usar para almacenar el origen sin procesar. Esto es opcional y no se usa internamente.
DataEntry.digest
Sección titulada “DataEntry.digest”Type: string | undefined
astro@5.0.0
Un resumen de contenido (digest) opcional para la entrada. Esto se puede utilizar para comprobar si los datos han cambiado.
Al establecer una entrada, la entrada solo se actualizará si el resumen (digest) no coincide con una entrada existente con el mismo ID.
El formato del resumen (digest) depende del cargador, pero debe ser una cadena que cambie cuando cambien los datos. Esto se puede hacer con la función generateDigest.
DataEntry.rendered
Sección titulada “DataEntry.rendered”Type: RenderedContent | undefined
astro@5.0.0
Almacena un objeto con el contenido renderizado de una entrada y los metadatos si se ha renderizado a HTML. Por ejemplo, esto se puede utilizar para almacenar el contenido renderizado de una entrada de Markdown, o el HTML de un CMS.
Si se proporciona este campo, entonces la función render() y el componente <Content /> están disponibles para renderizar la entrada en una página.
Si la entrada tiene contenido Markdown, puedes usar la función renderMarkdown() para generar este objeto a partir de la cadena de Markdown.
DataEntry.rendered.html
Sección titulada “DataEntry.rendered.html”Type: string
Contiene la cadena HTML renderizada. Esto lo usa render() para devolver un componente que renderiza este HTML.
DataEntry.rendered.metadata
Sección titulada “DataEntry.rendered.metadata”Type: object | undefined
Describe los metadatos presentes en este archivo. Esto incluye los imagePaths, los headings, el frontmatter y cualquier otro metadato presente en el archivo. Cuando el archivo no se ha renderizado como HTML, este valor será undefined.
DataEntry.rendered.metadata.imagePaths
Sección titulada “DataEntry.rendered.metadata.imagePaths”Type: string[]
Especifica la lista de rutas de imágenes presentes en esta entrada. Cada ruta es relativa al archivo filePath de la entrada.
DataEntry.rendered.metadata.headings
Sección titulada “DataEntry.rendered.metadata.headings”Type: MarkdownHeading[]
Especifica la lista de encabezados presentes en este archivo. Cada encabezado se describe mediante una profundidad (depth) determinada por el nivel del encabezado (h1 -> h6), un slug (slug) generado con github-slugger y su contenido de texto (text).
DataEntry.rendered.metadata.frontmatter
Sección titulada “DataEntry.rendered.metadata.frontmatter”Type: Record<string, any>
Describe el frontmatter original, analizado del archivo. Esto puede incluir datos inyectados mediante programación desde plugins de Markdown.
API de cargador en tiempo real
Sección titulada “API de cargador en tiempo real”Añadido en:
astro@6.0.0
Esta sección muestra la API para definir un cargador en tiempo real.
El objeto LiveLoader
Sección titulada “El objeto LiveLoader”Tipo: LiveLoader<TData, TEntryFilter, TCollectionFilter, TError>
astro@6.0.0
Una función de cargador en tiempo real devuelve un objeto con tres propiedades obligatorias del cargador en tiempo real. Además de proporcionar un nombre para el cargador, este objeto describe cómo recuperar tanto entradas individuales como una colección completa desde tu origen de datos en tiempo real.
Usa el tipo genérico LiveLoader para proporcionar seguridad de tipos en tu cargador. Este tipo acepta los siguientes parámetros de tipo, en este orden:
TData(por defectoRecord<string, unknown>): La estructura de datos de cada entrada devuelta por el cargador.TEntryFilter(por defectonever): El tipo de objeto de filtro aceptado porgetLiveEntry()y accesible enloadEntry(). Usanevercuando no admitas el filtrado de entradas individuales.TCollectionFilter(por defectonever): El tipo de objeto de filtro aceptado porgetLiveCollection()y accesible enloadCollection(). Usanevercuando no admitas el filtrado de colecciones.TError(por defectoError): Una claseErrorpersonalizada que puede ser devuelta por el cargador para un manejo de errores más detallado.
LiveLoader.name
Sección titulada “LiveLoader.name”Type: string
astro@6.0.0
Un nombre único para el cargador, utilizado en los registros.
LiveLoader.loadCollection()
Sección titulada “LiveLoader.loadCollection()”Tipo: (context: LoadCollectionContext<TCollectionFilter>) => Promise<LiveDataCollection<TData> | { error: TError; }>
astro@6.0.0
Define un método para cargar una colección de entradas. Esta función recibe un objeto de contexto que contiene una propiedad filter opcional y debe devolver los datos asociados con esta colección o los errores.
LiveLoader.loadEntry()
Sección titulada “LiveLoader.loadEntry()”Tipo: (context: LoadEntryContext<TEntryFilter>) => Promise<LiveDataEntry<TData> | undefined | { error: TError; }>
astro@6.0.0
Define un método para cargar una sola entrada. Esta función recibe un objeto de contexto que contiene una propiedad filter y devuelve los datos asociados con la entrada solicitada, undefined cuando la entrada no se puede encontrar, o los errores.
LoadCollectionContext
Sección titulada “LoadCollectionContext”Type: { filter?: TCollectionFilter; }
astro@6.0.0
Este objeto se pasa al método loadCollection() del cargador y contiene las siguientes propiedades:
LoadCollectionContext.filter
Sección titulada "LoadCollectionContext.filter"Type: Record<string, any> | never
Default: never
astro@6.0.0
Un objeto que describe los filtros soportados por tu cargador.
LoadEntryContext
Sección titulada "LoadEntryContext"Type: { filter: TEntryFilter; }
astro@6.0.0
Este objeto se pasa al método loadEntry() del cargador y contiene las siguientes propiedades:
LoadEntryContext.filter
Sección titulada "LoadEntryContext.filter"Type: Record<string, any> | never
Default: never
astro@6.0.0
Un objeto que describe los filtros soportados por tu cargador.
LiveDataEntry
Sección titulada "LiveDataEntry"Tipo: { id: string; data: TData; rendered?: { html: string }; cacheHint?: CacheHint; }
astro@6.0.0
Este es el objeto de tipo que devuelve el método loadEntry(). Contiene las siguientes propiedades:
LiveDataEntry.id
Sección titulada "LiveDataEntry.id"Type: string
astro@6.0.0
Un identificador para la entrada, que debe ser único dentro de la colección. Esta es la clave utilizada con getLiveEntry() para esa colección.
LiveDataEntry.data
Sección titulada "LiveDataEntry.data"Type: Record<string, unknown>
astro@6.0.0
Los datos reales de la entrada. Cuando un usuario acceda a la colección, esta tendrá tipos de TypeScript generados de acuerdo con el esquema de la colección.
Es responsabilidad del cargador validar y analizar los datos antes de devolverlos.
LiveDataEntry.rendered
Sección titulada "LiveDataEntry.rendered"Type: { html: string }
astro@6.0.0
Un objeto con el contenido renderizado de una entrada si se ha renderizado a HTML. Por ejemplo, este puede ser el contenido renderizado de una entrada de Markdown, o el HTML de un CMS.
Si se proporciona este campo, entonces la función render() y el componente <Content /> están disponibles para renderizar la entrada en una página.
Si el cargador no devuelve una propiedad rendered para una entrada, el componente <Content /> no renderizará nada.
LiveDataEntry.cacheHint
Sección titulada "LiveDataEntry.cacheHint"Type: CacheHint
astro@6.0.0
Un objeto opcional para proporcionar una pista sobre cómo almacenar en caché esta entrada específica.
LiveDataCollection
Sección titulada "LiveDataCollection"Type: { entries: Array<LiveDataEntry<TData>>; cacheHint?: CacheHint; }
astro@6.0.0
Este es el objeto de tipo que devuelve el método loadCollection(). Contiene las siguientes propiedades:
LiveDataCollection.entries
Sección titulada "LiveDataCollection.entries"Type: Array<LiveDataEntry<TData>>
astro@6.0.0
Un array de objetos LiveDataEntry.
LiveDataCollection.cacheHint
Sección titulada "LiveDataCollection.cacheHint"Type: CacheHint
astro@6.0.0
Un objeto opcional que proporciona orientación sobre cómo almacenar en caché esta colección. Este objeto se fusionará con las pistas de caché definidas para cada entrada individual, si se proporcionan.
CacheHint
Sección titulada "CacheHint"Un objeto que los cargadores pueden devolver a través de la propiedad cacheHint en LiveDataCollection o LiveDataEntry para proporcionar indicaciones que ayuden a almacenar en caché la respuesta. Contiene las siguientes propiedades:
CacheHint.tags
Sección titulada "CacheHint.tags"Type: Array<string>
astro@6.0.0
Un array de identificadores de cadena que permite un control de caché de grano fino. Esto te permite agrupar contenido relacionado e invalidar selectivamente las respuestas almacenadas en caché cuando cambia un contenido específico.
El siguiente ejemplo define etiquetas de pistas de caché para una colección de publicaciones filtradas por autor:
return { /* ... */ cacheHint: { tags: ["posts", `posts-${filter.author}`], },};CacheHint.lastModified
Sección titulada "CacheHint.lastModified"Type: Date
astro@6.0.0
La fecha de la última modificación del contenido (por ejemplo, la última actualización de una entrada en una colección). Esto se puede usar para establecer cabeceras de caché HTTP como Last-Modified e If-Modified-Since.
El siguiente ejemplo define una pista de caché para un solo producto utilizando su fecha de última actualización:
return { /* ... */ cacheHint: { lastModified: new Date(product.updatedAt) },};