Referencia de la API JavaScript

En esta página

Esta página describe la API pública que usan las páginas, los layouts y los componentes de Astro para leer y presentar un sitio EmDash. No inventaría todas las exportaciones de la raíz del paquete emdash: los repositorios de base de datos, los manejadores de la API, las utilidades de migración, las API para crear plugins y otros elementos internos del servidor tienen referencias propias o están pensados para el código de integración con el framework.

El contrato de API de plantillas de sitio de esta referencia enumera todas las funciones que las plantillas de sitio mantenidas por EmDash importan desde emdash. Las importaciones que solo son de tipo, como MediaValue, pertenecen a la documentación del modelo de datos correspondiente. Las funciones relacionadas se documentan en las mismas secciones cuando resultan útiles para quien crea un sitio, pero la página no cubre exportaciones de la raíz que no tengan relación.

Contrato de API de plantillas de sitio

Las plantillas mantenidas llaman a estos helpers de tiempo de ejecución:

FunciónSe usa para
decodeSlugDecodificar un parámetro de ruta dinámica antes de la consulta
getEmDashCollectionLeer y filtrar las entradas de una colección
getEmDashEntryLeer una entrada por ID o slug
getMenuWithCacheHintRenderizar un menú de navegación con invalidación de caché
getSeoMetaResolver los valores del panel SEO de una entrada y los valores de respaldo de la plantilla
getSiteSettingsLeer la identidad pública del sitio y otros ajustes globales
getSiteSettingsWithCacheHintLeer los ajustes globales con invalidación de caché
getTaxonomyTermsWithCacheHintRenderizar filtros de taxonomía con invalidación de caché
getTermsForEntriesCargar por lotes una taxonomía para una lista de entradas
sanitizeHrefRechazar esquemas de URL inseguros antes de renderizar enlaces almacenados
searchBuscar contenido publicado en todas las colecciones

Consultas de contenido

Las funciones de consulta de EmDash siguen el patrón de las colecciones de contenido en vivo de Astro y devuelven { entries, error } o { entry, error } para gestionar los errores con elegancia.

getEmDashCollection()

Obtiene todas las entradas de una colección. El siguiente ejemplo carga todas las publicaciones y comprueba si hay un error:

import { getEmDashCollection } from "emdash";

const { entries: posts, error } = await getEmDashCollection("posts");

if (error) {
	console.error("Failed to load posts:", error);
}

Parámetros

ParámetroTipoDescripción
collectionstringSlug de la colección
optionsCollectionFilterOpciones de filtro opcionales

Opciones

El parámetro options acepta el siguiente filtro:

interface WhereRange {
	gt?: string;
	gte?: string;
	lt?: string;
	lte?: string;
}

interface CollectionFilter {
	status?: "draft" | "published" | "archived";
	limit?: number;
	cursor?: string; // Keyset pagination — pass a previous `nextCursor`
	offset?: number; // Offset pagination — skip N entries (use with `limit`)
	where?: Record<string, string | string[] | WhereRange>;
	orderBy?: Record<string, "asc" | "desc">;
	locale?: string;
}

cursor y offset son mutuamente excluyentes. Las claves de where pueden nombrar campos de contenido, taxonomías o byline; los objetos de rango sirven para comparaciones ordenadas.

Valor devuelto

La función se resuelve en un CollectionResult:

interface CollectionResult<T> {
	entries: ContentEntry<T>[]; // Empty array if error or none found
	error?: Error; // Set if query failed
	cacheHint: CacheHint; // Tags and last-modified time for Astro route caching
	nextCursor?: string; // Cursor for the next keyset page, if any
	hasMore?: boolean; // Whether more entries exist beyond this page (when `limit` is set)
}

Ejemplos

Los siguientes ejemplos filtran por estado y taxonomía, limitan los resultados y gestionan los errores:

// Get all published posts
const { entries: posts } = await getEmDashCollection("posts", {
	status: "published",
});

// Get latest 5 posts
const { entries: latest } = await getEmDashCollection("posts", {
	limit: 5,
	status: "published",
});

// Filter by taxonomy
const { entries: newsPosts } = await getEmDashCollection("posts", {
	status: "published",
	where: { category: "news" },
});

// Numbered archive page (e.g. /page/3) with offset pagination
const perPage = 20;
const page = Number(Astro.params.page ?? 1);
const { entries: pagePosts, hasMore } = await getEmDashCollection("posts", {
	status: "published",
	limit: perPage,
	offset: (page - 1) * perPage,
	orderBy: { published_at: "desc" },
});

// Handle errors
const { entries, error } = await getEmDashCollection("posts");
if (error) {
	return new Response("Server error", { status: 500 });
}

getEmDashEntry()

Obtiene una única entrada por slug o ID. El siguiente ejemplo carga una publicación y renderiza la página 404 del sitio cuando no existe:

import { getEmDashEntry } from "emdash";

const { entry: post, error } = await getEmDashEntry("posts", "my-post-slug");

if (!post) {
	return Astro.rewrite("/404");
}

Parámetros

ParámetroTipoDescripción
collectionstringSlug de la colección
slugOrIdstringSlug o ID de la entrada
options{ locale?: string; references?: ReferenceSelection }Opcional. Locale para resolver el slug y los campos de referencia que se cargarán

El modo de vista previa se gestiona automáticamente: cuando la solicitud tiene un token _preview válido, la consulta sirve el contenido en borrador. El estado de vista previa no requiere ningún parámetro.

references nombra los campos de referencia que se cargarán, indexados por el slug del campo. true solicita la primera página con el límite predeterminado de 50 entradas; la forma de objeto acepta un limit (como máximo 100) y el cursor de una página anterior. Los campos omitidos no se leen, y una llamada que omite la opción no ejecuta ninguna consulta de referencias.

Valor devuelto

La función se resuelve en un EntryResult:

interface EntryResult<T, R> {
	entry: ContentEntry<T, R> | null; // null if not found
	error?: Error; // Set only for actual errors, not "not found"
	isPreview: boolean; // true if draft content is being served
	fallbackLocale?: string; // Set when locale fallback returned another locale
	cacheHint: CacheHint; // Tags and last-modified time for Astro route caching
}

Ejemplos

Los siguientes ejemplos obtienen entradas por slug y por ID, leen el estado de vista previa y distinguen los errores de «no encontrado»:

// Get by slug
const { entry: post } = await getEmDashEntry("posts", "hello-world");

// Get by ID
const { entry: post } = await getEmDashEntry("posts", "01HXK5MZSN0FVXT2Q3KPRT9M7D");

// Preview is automatic — isPreview is true when a valid _preview token is present
const { entry, isPreview, error } = await getEmDashEntry("posts", slug);

// Handle errors vs not-found
if (error) {
	return new Response("Server error", { status: 500 });
}
if (!entry) {
	return Astro.rewrite("/404");
}

getTranslations()

Obtiene las traducciones disponibles de una entrada a partir del slug de la colección y del ID de base de datos:

import { getTranslations } from "emdash";

const { translations, error } = await getTranslations("posts", post.data.id);

El resultado contiene el translationGroup compartido, un array translations y un error opcional. Cada resumen de traducción incluye id, locale, slug y status.

resolveEmDashPath()

Resuelve una ruta pública según los patrones de URL configurados para las colecciones enrutables:

import { resolveEmDashPath } from "emdash";

const result = await resolveEmDashPath("/blog/hello-world");

if (result) {
	console.log(result.collection, result.entry.data.title);
}

El resultado contiene la collection coincidente, la entry y los params de la ruta. La función devuelve null cuando ningún patrón de URL configurado coincide.

getEditMeta()

Lee los metadatos de edición visual no enumerables adjuntos a un valor de Portable Text:

import { getEditMeta } from "emdash";

const meta = getEditMeta(post.data.content);

Devuelve { collection, id, field } para un valor con anotación, o undefined cuando el valor no tiene ninguna.

Tipos de contenido

ContentEntry

Las funciones de consulta devuelven las entradas con la siguiente forma:

interface ContentEntry<T = Record<string, unknown>, R = ReferencePages> {
	id: string;
	data: T;
	references?: R; // One page per reference field requested; absent otherwise
	edit: EditProxy; // Visual editing annotations
}

El proxy edit proporciona anotaciones de edición visual. Propáguelo sobre los elementos para habilitar la edición en línea: {...entry.edit.title}. Fuera del modo de edición no produce ninguna salida.

El objeto data contiene todos los campos de contenido más los campos del sistema:

  • id - Identificador único
  • slug - Identificador apto para URL
  • status - “draft” | “published” | “archived”
  • createdAt - Fecha de creación como Date
  • updatedAt - Fecha de la última actualización como Date
  • publishedAt - Fecha de publicación como Date, o null; se conserva cuando el contenido se despublica
  • Además de todos los campos personalizados definidos en el esquema de su colección

ReferencePage

entry.references contiene una página por cada campo de referencia que se haya pedido a getEmDashEntry, indexada por el slug del campo:

interface ReferencePage<T = Record<string, unknown>> {
	entries: ContentEntry<T>[];
	nextCursor?: string; // Set when the field holds more entries than the limit
}

Cada entrada se mapea igual que una entrada cargada directamente, con una excepción: los bylines y los términos de taxonomía no se hidratan, por lo que data.bylines y data.terms no existen.

getEmDashReferences()

Obtiene una página de un único campo de referencia, sin volver a leer la entrada de la que depende. Utilícela para avanzar más allá de la primera página con el nextCursor que devolvió esa página.

ParámetroTipoDescripción
collectionstringSlug de la colección de la entrada que contiene el campo
slugOrIdstringSlug o ID de la entrada
fieldstringSlug del campo de referencia
options{ limit?: number; cursor?: string; locale?: string }Opcional. De forma predeterminada 50 entradas, como máximo 100

El siguiente ejemplo carga las 20 entradas vinculadas siguientes:

import { getEmDashReferences } from "emdash";

const { entries, nextCursor, error } = await getEmDashReferences(
	"posts",
	post.id,
	"related_posts",
	{ cursor, limit: 20 },
);

error solo se establece ante errores reales. Un campo desconocido, una entrada inexistente o una entrada que la solicitud no puede ver se resuelven todos en un array entries vacío.

El resultado también incluye un cacheHint que nombra las filas que leyó la página. Una ruta que almacena en caché lo que renderiza debería fusionarlo con su propia pista, como hace getEmDashEntry({ references }) con la de la primera página, para que escribir en una de esas entradas haga caducar la página.

Helpers de URL

decodeSlug() y slugify()

Use decodeSlug() con un parámetro de ruta dinámica antes de pasarlo a una consulta de contenido. Devuelve undefined si falta el parámetro o si la cadena codificada con porcentaje está mal formada y, en caso contrario, devuelve el slug decodificado:

function decodeSlug(raw: string | undefined): string | undefined;
import { decodeSlug, getEmDashEntry } from "emdash";

const slug = decodeSlug(Astro.params.slug);
const { entry } = slug ? await getEmDashEntry("posts", slug) : { entry: null };

slugify(value) convierte texto en un slug en minúsculas separado por guiones. Úselo cuando una plantilla necesite construir un slug a partir de una etiqueta; los slugs de las entradas almacenadas ya los genera EmDash.

sanitizeHref() y isSafeHref()

Estos helpers aceptan http:, https:, mailto:, tel:, rutas relativas al sitio y fragmentos. Rechazan los esquemas capaces de ejecutar scripts, las URL relativas al protocolo, las formas que empiezan por barra invertida que los navegadores resuelven hacia otro sitio y los caracteres de control. isSafeHref(value) devuelve un booleano. sanitizeHref(value) devuelve la URL segura original o "#" cuando el valor está vacío o no es seguro.

import { sanitizeHref } from "emdash";

const href = sanitizeHref(menuItem.url);

Sistema de preview

generatePreviewToken()

Genera un token de vista previa para contenido en borrador. El siguiente ejemplo crea un token que caduca en una hora:

import { generatePreviewToken } from "emdash";

const token = await generatePreviewToken({
	contentId: "posts:01HXK5MZSN...",
	secret: process.env.EMDASH_PREVIEW_SECRET!,
	expiresIn: 3600, // 1 hour
});

contentId debe usar el formato collection:id. expiresIn acepta segundos o una duración que termine en s, m, h, d o w, y su valor predeterminado es "1h". Mantenga el secreto de firma en el servidor.

verifyPreviewToken()

Verifica un token de vista previa y lee su carga útil:

import { verifyPreviewToken } from "emdash";

const result = await verifyPreviewToken({
	token,
	secret: process.env.EMDASH_PREVIEW_SECRET!,
});

if (result.valid) {
	const { cid, exp, iat } = result.payload;
	// cid is "collection:id" format, e.g. "posts:my-draft-post"
}

Pase token o url junto con el secret de firma. Un token no válido devuelve { valid: false, error }, donde error es "none", "malformed", "invalid" o "expired".

parseContentId()

Divide en dos partes el valor collection:id de la carga útil de una vista previa:

import { parseContentId } from "emdash";

const parsed = parseContentId(result.payload.cid);

Devuelve { collection, id } y lanza una excepción cuando el valor no tiene el separador de dos puntos.

getPreviewUrl() y buildPreviewUrl()

getPreviewUrl() crea y firma una URL de vista previa. Acepta collection, id y secret, además de los valores opcionales expiresIn, baseUrl, pathPattern y locale:

import { getPreviewUrl } from "emdash";

const previewUrl = await getPreviewUrl({
	collection: "posts",
	id: post.id,
	secret: process.env.EMDASH_PREVIEW_SECRET!,
	pathPattern: "/blog/{id}",
});

Sin baseUrl, devuelve una URL relativa al sitio. Use buildPreviewUrl({ path, token, baseUrl? }) cuando ya exista un token.

isPreviewRequest()

Comprueba si una solicitud incluye un token de vista previa y, a continuación, lo lee:

import { isPreviewRequest, getPreviewToken } from "emdash";

if (isPreviewRequest(Astro.url)) {
	const token = getPreviewToken(Astro.url);
	// Verify and show preview content
}

getPreviewToken() devuelve el parámetro de consulta _preview, o null cuando no está presente. El middleware de EmDash verifica las solicitudes de vista previa normales y proporciona el estado de vista previa a getEmDashEntry() automáticamente; estos helpers son para rutas de vista previa personalizadas y herramientas.

Convertidores de contenido

Convierta entre los formatos Portable Text y ProseMirror:

import { prosemirrorToPortableText, portableTextToProsemirror } from "emdash";

// From ProseMirror (editor) to Portable Text (storage)
const portableText = prosemirrorToPortableText(prosemirrorDoc);

// From Portable Text to ProseMirror
const prosemirrorDoc = portableTextToProsemirror(portableText);

El documento de ProseMirror usa nodos propios de EmDash para los bloques integrados, como image, table, iframeBlock y videoBlock. Un editor TipTap que lo cargue necesita esos nodos en su esquema; de lo contrario, no puede cargar los documentos que los usan. Un nodo videoBlock tiene los atributos src, mediaId, provider, caption, width y height.

Configuración del sitio

Lea los ajustes de todo el sitio con getSiteSettings y getSiteSetting:

function getSiteSettings(): Promise<Partial<SiteSettings>>;
function getSiteSetting<K extends SiteSettingKey>(key: K): Promise<SiteSettings[K] | undefined>;
import { getSiteSettings, getSiteSetting } from "emdash";

// Get all settings
const settings = await getSiteSettings();

// Get single setting
const title = await getSiteSetting("title");

Los ajustes son de solo lectura desde la API de tiempo de ejecución. Use la API de administración para actualizarlos.

getSiteSettings() devuelve un objeto parcial porque las claves sin establecer se omiten. Los ajustes de medios, como el logotipo y el favicon del sitio, se resuelven en objetos de referencia de medios antes de que la función devuelva el resultado.

getSiteSettingsWithCacheHint() devuelve { data, cacheHint }. Pase la pista a Astro.cache.set() cuando deba invalidarse una caché de ruta de Astro tras un cambio en los ajustes del sitio.

SEO

Resuelva los valores del panel SEO y los valores de respaldo del contenido de una página con getSeoMeta():

function getSeoMeta<T>(content: SeoContentInput<T>, options?: SeoMetaOptions): SeoMeta;

interface SeoMetaOptions {
	siteTitle?: string;
	siteUrl?: string;
	titleSeparator?: string; // Default: " | "
	path?: string;
	defaultOgImage?: string;
	defaultTitle?: string;
	defaultDescription?: string;
}

interface SeoMeta {
	title: string;
	description: string | null;
	ogTitle: string;
	ogDescription: string | null;
	ogImage: string | null;
	canonical: string | null;
	robots: string | null;
}
import { getSeoMeta } from "emdash";

const meta = getSeoMeta(post, {
	siteTitle: "Example Blog",
	siteUrl: "https://example.com",
	path: `/blog/${post.data.slug}`,
});

Devuelve el título resuelto, la descripción, los valores de Open Graph, la URL canónica y el valor de robots. getContentSeo(content) devuelve el objeto SEO sin procesar, sin aplicar los valores de respaldo de la plantilla.

Para el contenido traducido, getHreflangAlternates(collection, entryId, { siteUrl? }) devuelve las variantes de locale publicadas y enrutables como objetos { hreflang, href } y añade una entrada x-default. Devuelve un array vacío cuando la internacionalización está deshabilitada, la entrada actual está marcada como noindex o no hay ninguna URL absoluta del sitio disponible.

Comentarios

Obtenga los comentarios aprobados de una entrada y su número:

import { getCommentCount, getComments } from "emdash";

const { items: comments, total } = await getComments({
	collection: "posts",
	contentId: post.data.id,
	threaded: true,
	reactions: true,
	sort: "best",
});

const count = await getCommentCount("posts", post.data.id);

threaded anida las respuestas bajo su comentario principal. El valor predeterminado de sort es "oldest"; "best" ordena los comentarios de nivel superior por reacciones y habilita automáticamente los recuentos de reacciones. Las consultas de comentarios renderizadas en el servidor devuelven como máximo 500 comentarios aprobados; use la API REST cuando un cliente necesite paginación.

Traducir los componentes de comentarios

Los componentes Comments y CommentForm de emdash/ui/comments muestran texto en inglés de forma predeterminada. Pase un objeto labels para reemplazar cualquiera de esos textos. Las claves que omita, o que establezca en undefined, conservan su valor predeterminado en inglés:

<Comments
	collection="posts"
	contentId={post.data.id}
	threaded
	labels={{
		heading: (count) => (count === 1 ? "1 Kommentar" : `${count} Kommentare`),
		member: "Mitglied",
		like: "Gefällt mir",
	}}
/>
<CommentForm
	collection="posts"
	contentId={post.data.id}
	labels={{
		name: "Name",
		email: "E-Mail",
		comment: "Kommentar",
		submit: "Kommentar senden",
		submitting: "Wird gesendet …",
		published: "Kommentar veröffentlicht",
		pending: "Kommentar wird vor der Veröffentlichung geprüft",
		error: "Der Kommentar konnte nicht gesendet werden.",
		networkError: "Netzwerkfehler. Bitte versuche es erneut.",
	}}
/>

Comments acepta heading, member y like. heading recibe el número de comentarios aprobados, por lo que puede devolver un texto distinto cuando no hay ningún comentario.

CommentForm acepta name, email, comment, submit, submitting, published, pending, error y networkError. El formulario muestra published cuando el comentario se aprueba de inmediato y pending cuando queda a la espera de moderación. Sin error, el formulario muestra el mensaje de error en inglés del servidor.

Comments da formato a las fechas de los comentarios según la configuración regional de la página (Astro.currentLocale) y recurre a en-US como alternativa. Astro establece Astro.currentLocale solo cuando la configuración de i18n está habilitada. Sin ella, o para usar un formato distinto, pase una etiqueta de configuración regional BCP 47, como locale="de-CH".

Menús

Obtenga menús de navegación y recorra sus elementos, incluidos los hijos anidados:

function getMenu(name: string, options?: { locale?: string }): Promise<Menu | null>;
function getMenus(options?: { locale?: string }): Promise<MenuSummary[]>;
import { getMenu, getMenus } from "emdash";

// Get all menus
const menus = await getMenus();

// Get specific menu with items
const primaryMenu = await getMenu("primary");

if (primaryMenu) {
	primaryMenu.items.forEach(item => {
		console.log(item.label, item.url);
		// Nested items for dropdowns
		item.children.forEach(child => console.log("  -", child.label));
	});
}

getMenu(name, { locale? }) sigue la cadena de respaldo de locales configurada. getMenus({ locale? }) lista los resúmenes de menús para el locale de la solicitud resuelto o el configurado; sin internacionalización, lista todos los locales. getMenuWithCacheHint() devuelve { data, cacheHint } para las rutas que usan la caché de Astro.

Bylines

Obtenga el perfil de un autor por ID o slug, o liste las entradas atribuidas a un byline:

import { getByline, getBylineBySlug, getEntriesByByline } from "emdash";

const profile = await getBylineBySlug("jane-doe", { locale: "en" });
const posts = profile
	? await getEntriesByByline("posts", profile.translationGroup ?? profile.id)
	: [];

getByline(id) devuelve un perfil o null. La búsqueda por slug acepta un locale opcional y sigue la cadena de respaldo de locales. Las consultas de contenido ya hidratan los créditos ordenados de una entrada en entry.data.bylines; use estos helpers independientes para las páginas de autor y los archivos de bylines.

Taxonomías

Obtenga términos de taxonomía, un único término, los términos de una entrada o las entradas por término:

function getTaxonomyTerms(
	taxonomyName: string,
	options?: { locale?: string; includeCounts?: boolean },
): Promise<TaxonomyTerm[]>;

function getTerm(
	taxonomyName: string,
	slug: string,
	options?: { locale?: string; includeCounts?: boolean },
): Promise<TaxonomyTerm | null>;

function getTermsForEntries(
	collection: string,
	entryIds: string[],
	taxonomyName: string,
	options?: { locale?: string },
): Promise<Map<string, TaxonomyTerm[]>>;
import { getTaxonomyTerms, getTerm, getEntryTerms, getEntriesByTerm } from "emdash";

// Get all terms for a taxonomy (tree structure for hierarchical)
const categories = await getTaxonomyTerms("category");

// Get single term
const news = await getTerm("category", "news");

// Get terms assigned to a content entry
const postCategories = await getEntryTerms("posts", "post-123", "category");

// Get entries with a specific term
const newsPosts = await getEntriesByTerm("posts", "category", "news");

getTaxonomyDefs({ locale? }) lista una definición por taxonomía, y getTaxonomyDef(name, { locale? }) devuelve una definición, o null cuando ningún locale define la taxonomía. Ambas resuelven una taxonomía en todos los locales; Traducir taxonomías y términos explica qué etiqueta de locale utilizan. Las búsquedas de términos siguen la cadena de respaldo configurada.

getTaxonomyTerms(name, { locale?, includeCounts? }) devuelve un árbol para las taxonomías jerárquicas e incluye de forma predeterminada el recuento de entradas visibles. Pase includeCounts: false cuando la plantilla no renderice los recuentos. Las consultas de contenido también hidratan los términos asignados en el data.terms de cada entrada; use getEntryTerms() cuando solo tenga el nombre de una colección y el ID de una entrada.

En las páginas de archivo que renderizan términos junto a muchas entradas, agrupe la búsqueda por lotes en lugar de llamar a getEntryTerms() dentro de un bucle:

import { getAllTermsForEntries, getTermsForEntries } from "emdash";

const termsByPost = await getTermsForEntries(
	"posts",
	posts.map(post => post.data.id),
	"category",
);

const allTermsByPost = await getAllTermsForEntries(
	"posts",
	posts.map(post => post.data.id),
);

getTermsForEntries() devuelve un mapa del ID de entrada a los términos de la taxonomía solicitada. getAllTermsForEntries() devuelve un mapa del ID de entrada a los términos agrupados por nombre de taxonomía. getTaxonomyTermsWithCacheHint() devuelve { data, cacheHint } para una ruta con caché de Astro.

Áreas de widgets

Obtenga áreas de widgets y los widgets que contienen:

import { getWidgetArea, getWidgetAreas } from "emdash";

// Get all widget areas
const areas = await getWidgetAreas();

// Get specific widget area with widgets
const sidebar = await getWidgetArea("sidebar");

if (sidebar) {
	sidebar.widgets.forEach(widget => {
		console.log(widget.type, widget.title);
	});
}

getWidgetAreaWithCacheHint(name) devuelve { data, cacheHint } para las rutas que usan la caché de Astro. Las áreas de widgets y sus widgets se ordenan según su orden configurado.

Secciones

Obtenga secciones y fíltrelas:

import { getSection, getSections } from "emdash";

// Get all sections (paginated)
const { items, nextCursor } = await getSections();

// Filter sections
const { items: themeSections } = await getSections({ source: "theme" });
const { items: results } = await getSections({ search: "newsletter" });

// Get a single section by slug
const cta = await getSection("newsletter-cta");

getSections(options?) devuelve { items: Section[]; nextCursor?: string }. Las opciones son source ("theme" | "user" | "import"), search, limit (50 de forma predeterminada, máximo 100) y cursor.

Búsqueda

Ejecute una búsqueda global en todas las colecciones. Los resultados incluyen fragmentos resaltados:

function search(query: string, options?: SearchOptions): Promise<SearchResponse>;

interface SearchOptions {
	collections?: string[]; // Default: every searchable collection
	status?: string; // Default: "published"
	locale?: string; // Default: all locales
	limit?: number; // Default: 20
	cursor?: string;
	scope?: "all" | "title"; // Default: "all"
}

interface SearchResponse {
	items: SearchResult[];
	nextCursor?: string;
}
import { search } from "emdash";

const results = await search("hello world", {
	collections: ["posts", "pages"],
	status: "published",
	limit: 20,
});

// search() resolves to { items, nextCursor? }
results.items.forEach(result => {
	console.log(result.title);
	console.log(result.snippet); // Contains <mark> tags
	console.log(result.score);
});

// Paginate: pass the previous nextCursor back as `cursor` to get the next page.
// nextCursor is undefined once there are no more results.
if (results.nextCursor) {
	const next = await search("hello world", {
		collections: ["posts", "pages"],
		limit: 20,
		cursor: results.nextCursor,
	});
}

Con scope: "title", la consulta solo coincide con el campo de título de cada colección en lugar de con todo el texto indexado; resulta útil en selectores y autocompletado, donde las coincidencias en el cuerpo del texto sorprenderían. Las colecciones cuyo campo de título no está indexado para la búsqueda no devuelven resultados con este ámbito.

Manejo de errores

Las consultas de contenido devuelven los errores operativos en su resultado en lugar de lanzarlos. Una entrada inexistente no es un error operativo: entry es null y error permanece sin definir.

const { entry, error } = await getEmDashEntry("posts", slug);

if (error) {
	return new Response("Content could not be loaded", { status: 500 });
}

if (!entry) {
	return Astro.rewrite("/404");
}

Los helpers sin envoltorio de resultado pueden lanzar excepciones cuando su entrada no es válida o falla una operación de base de datos. Gestione esos errores en el límite de la ruta cuando la página pueda ofrecer una alternativa útil. Las clases de error de repositorios y manejadores que usan las integraciones de servidor de nivel inferior quedan fuera de esta API de plantillas de sitio.