Riferimento API JavaScript

In questa pagina

Questa pagina descrive l’API pubblica usata da pagine, layout e componenti Astro per leggere e presentare un sito EmDash. Non elenca ogni export dalla radice del pacchetto emdash: repository del database, handlers de API, utilità di migrazione, APIs para autores de plugins e outros internals do servidor têm referências separadas ou destinam-se a codice di integrazione del framework.

Il contratto API dei modelli di sito in questo riferimento elenca ogni funzione importata da emdash dai modelli di sito mantenuti da EmDash. Import solo di tipi come MediaValue appartengono alla documentazione del modello dati pertinente. Funzioni correlate sono documentate nelle stesse sezioni quando aiutano l’autore del sito, ma la pagina non copre export root non correlati.

Contratto API dei modelli di sito

I modelli mantenuti invocano questi helper runtime:

FonctionUso
decodeSlugDecodificare un parametro di route dinamica prima della ricerca
getEmDashCollectionLeggere e filtrare voci in una collection
getEmDashEntryLeggere una voce per ID o slug
getMenuWithCacheHintRenderizzare un menu di navigazione con invalidazione cache
getSeoMetaRisolvere i valori del pannello SEO di una voce e i fallback del modello
getSiteSettingsLeggere identità pubblica del sito e altre impostazioni globali
getSiteSettingsWithCacheHintLeggere impostazioni globali con invalidazione cache
getTaxonomyTermsWithCacheHintRenderizzare filtri tassonomia con invalidazione cache
getTermsForEntriesCaricare in batch una tassonomia per un elenco di voci
sanitizeHrefRifiutare schemi URL non sicuri prima di renderizzare link memorizzati
searchCercare contenuto pubblicato in tutte le collection

Query sui contenuti

Le funzioni di query di EmDash seguono il pattern live content collections d’Astro et restituiscono { entries, error } ou { entry, error } para gestione errori controllata.

getEmDashCollection()

Recupera tutte le voci di una collection. L’esempio seguente carica tutti i post e verifica eventuali errori:

import { getEmDashCollection } from "emdash";

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

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

Parameters

ParameterTypeDescription
collectionstringCollection slug
optionsCollectionFilterOptional filter options

Options

Il parametro options accetta il seguente 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 e offset si escludono a vicenda. As chaves where podem nomear campi contenuto, taxonomias ou byline; oggetti range consentono confronti ordinati.

Returns

La funzione si risolve in 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)
}

Examples

I seguenti esempi filtrano per stato e tassonomia, limitano i risultati e gestiscono gli errori:

// 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()

Recupera una singola voce per slug o ID. O exemplo seguinte carrega um post e reindirizza se manca:

import { getEmDashEntry } from "emdash";

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

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

Parameters

ParameterTypeDescription
collectionstringCollection slug
slugOrIdstringEntry slug or ID
options{ locale?: string; references?: ReferenceSelection }Optional. Locale for slug resolution, and the reference fields to load

La modalità preview è gestita automaticamente: quando o richiesta ha un token _preview válido, a query serve contenuto in bozza. Nessun parametro è richiesto per lo stato preview.

references nomina i campi reference da caricare, indexados por slug do campo. true pede a prima pagina con il limite predefinito di 50 voci; a forma objeto aceita limit (al massimo 100) e o cursor de uma pagina precedente. Campi omessi non vengono letti, e uma chamada sem a opção non esegue query reference.

Returns

La funzione si risolve in 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
}

Examples

I seguenti esempi recuperano per slug e ID, leggono lo stato preview e distinguono errori da assenza:

// 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.redirect("/404");
}

getTranslations()

Recupera le traduzioni disponibili di una voce por slug de collection e ID de base de dados:

import { getTranslations } from "emdash";

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

Il risultato contiene a translationGroup condivisa, um array translations e um error opcional. Ogni riepilogo traduzione include id, locale, slug e status.

resolveEmDashPath()

Risolve un pathname pubblico face aos padrões URL configurados para collection routabili:

import { resolveEmDashPath } from "emdash";

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

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

Il risultato contiene a collection corrispondente, a entry e os params de rota. La funzione restituisce null quando nessun pattern URL configurato corrisponde.

getEditMeta()

Legge i metadati di editing visuale não enumeráveis anexados a um valor Portable Text:

import { getEditMeta } from "emdash";

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

Restituisce { collection, id, field } per un valore annotato, ou undefined quando o valor não tem anotação.

Tipi di contenuto

ContentEntry

As funções de consulta restituiscono entradas com a seguinte 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
}

Il proxy edit fornisce annotazioni di editing visuale. Estendilo sugli elementi per abilitare l’editing inline: {...entry.edit.title}. Fuori dalla modalità editing, non produce output.

O objeto data contém todos os campi contenuto mais campos de sistema:

  • id - Unique identifier
  • slug - URL-friendly identifier
  • status - “draft” | “published” | “archived”
  • createdAt - Creation time as a Date
  • updatedAt - Last update time as a Date
  • publishedAt - Publication time as a Date, or null; retained when content is unpublished
  • Plus all custom fields defined in your collection schema

ReferencePage

entry.references contém uma página por campo reference pedido a getEmDashEntry, indexada por slug do campo:

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

Ogni voce è mappata como uma entrada carregada diretamente, exceto uma exceção: bylines e termini tassonomia non sono idratati, logo data.bylines e data.terms sono assenti.

getEmDashReferences()

Recupera una pagina di un singolo campo reference sem reler a entrada a que pertence. Usalo per andare oltre la prima pagina com o nextCursor restituito da quella pagina.

ParameterTypeDescription
collectionstringCollection slug of the entry that holds the field
slugOrIdstringEntry slug or ID
fieldstringReference field slug
options{ limit?: number; cursor?: string; locale?: string }Optional. Defaults to 50 entries, at most 100

L’esempio seguente carica le successive 20 voci collegate:

import { getEmDashReferences } from "emdash";

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

error è impostato solo per errori reali. Campo desconhecido, voce mancante ou entrada invisível ao pedido producono un array entries vuoto.

Il risultato include anche un cacheHint que nomeia as righe lette dalla pagina. Uma rota que mette in cache il rendering deve fondere nel proprio hint, como getEmDashEntry({ references }) incorpora quello della prima pagina, para que scrivere su una di queste voci invalida la pagina.

Helper URL

decodeSlug() and slugify()

Usa decodeSlug() su un parametro di route dinamica antes de o passar a uma query di contenuto. Restituisce undefined per parametro mancante; caso contrário aplica decodeURIComponent(), que lança com encoding percentuale malformato:

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) converte testo in slug minuscolo separato da trattini. Use-o quando um modelo precisa construir um slug a partir de uma etichetta; slug voce memorizzati provengono già da EmDash.

sanitizeHref() and isSafeHref()

Questi helper rifiutano schemi di link pericolosi come javascript:. isSafeHref(value) restituisce un booleano. sanitizeHref(value) restituisce l’URL sicuro originale o "#" quando il valore è vuoto o pericoloso.

import { sanitizeHref } from "emdash";

const href = sanitizeHref(menuItem.url);

Sistema preview

generatePreviewToken()

Genera un token preview per contenuto in bozza. O exemplo seguinte cria um token que scade in un’ora:

import { generatePreviewToken } from "emdash";

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

contentId deve usare il formato collection:id. expiresIn accetta secondi o durata terminante in s, m, h, d ou w e o predefinito è "1h". Conserva il secret di firma sul server.

verifyPreviewToken()

Verifica un token preview e legge il payload:

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"
}

Passa token o url con il secret di firma. Token non valido restituisce { valid: false, error }, onde error é "none", "malformed", "invalid" ou "expired".

parseContentId()

Divide il valore collection:id del payload preview nelle sue due parti:

import { parseContentId } from "emdash";

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

Restituisce { collection, id } e lancia se il valore non ha separatore due punti.

getPreviewUrl() and buildPreviewUrl()

getPreviewUrl() crea e firma un URL preview. Accetta collection, id e secret, mais valores opcionais expiresIn, baseUrl, pathPattern e locale:

import { getPreviewUrl } from "emdash";

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

Senza baseUrl, restituisce un URL relativo al sito. Use buildPreviewUrl({ path, token, baseUrl? }) quando esiste già un token.

isPreviewRequest()

Verifica se una richiesta include un token preview e poi leggilo:

import { isPreviewRequest, getPreviewToken } from "emdash";

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

getPreviewToken() restituisce il parametro query _preview ou null quando manca. O middleware EmDash verifica richieste preview normali e fornisce stato preview a getEmDashEntry() automaticamente; questi helper servono route preview personalizzate e tooling.

Convertitori di contenuto

Converte tra i formati Portable Text e 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);

Impostazioni del sito

Leggi le impostazioni globali del sito con getSiteSettings e 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");

Le impostazioni sono in sola lettura via API runtime. Usa l’API admin per aggiornarle.

getSiteSettings() restituisce un oggetto parziale perché le chiavi non impostate sono omesse. Impostazioni media come logo e favicon del sito si risolvono in oggetti media-reference prima del ritorno della funzione.

getSiteSettingsWithCacheHint() restituisce { data, cacheHint }. Passa l’hint a Astro.cache.set() quando la cache route Astro deve invalidarsi dopo la modifica delle impostazioni del sito.

SEO

Risolvi i valori del pannello SEO e fallback contenuto di una pagina 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}`,
});

Restituisce titolo, description, valori Open Graph, URL canonica e valore robots risolti. getContentSeo(content) restituisce oggetto SEO grezzo senza fallback del modello.

Per contenuto tradotto, getHreflangAlternates(collection, entryId, { siteUrl? }) restituisce varianti locale pubblicate e routabili como objetos { hreflang, href } e aggiunge voce x-default. Restituisce array vuoto quando internazionalizzazione è disabilitata, voce corrente contrassegnata noindex o non c’è URL assoluto del sito.

Commenti

Recupera commenti approvati e relativo conteggio per una voce:

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 annida risposte sotto il commento padre. sort predefinito è "oldest"; "best" ordina commenti di primo livello per reazioni e ativa contagens automaticamente. Consultas de comentários renderizadas no servidor restituiscono no máximo 500 comentários aprovados; use REST API quando cliente necessita paginazione.

Recupera menu di navigazione e scorre i relativi elementi, inclusi figli annidati:

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? }) segue la catena fallback locale configurata. getMenus({ locale? }) elenca riepiloghi menu per la locale della richiesta risolta o configurata; senza internazionalizzazione elenca ogni locale. getMenuWithCacheHint() restituisce { data, cacheHint } per route con cache Astro.

Bylines

Recupera profilo autore per ID o slug, o elenca voci accreditate 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) restituisce profilo o null. Ricerca per slug accetta locale opzionale e segue catena fallback. Query contenuto idratano già crediti ordinati in una voce in entry.data.bylines; usa questi helper autonomi per pagine autore e archivi byline.

Taxonomies

Recupera termini tassonomia, un termine, termini di una voce o voci per termine:

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? }) elenca una definizione per tassonomia, e getTaxonomyDef(name, { locale? }) restituisce definizione o null quando nessuna locale definisce tassonomia. Ambos resolvem taxonomia em cada locale; Tradurre tassonomie e termini explica que etichetta de locale usam. Ricerche termini seguono catena fallback configurata.

getTaxonomyTerms(name, { locale?, includeCounts? }) restituisce albero per tassonomie gerarchiche e inclui conteggi voci visibili per impostazione predefinita. Passe includeCounts: false quando modello non mostra conteggi. Query contenuto idratano termini assegnati in data.terms di ogni voce; use getEntryTerms() quando hai solo nome collection e ID voce.

Per pagine archivio che mostrano termini accanto a molte voci, raggruppa la ricerca invece di chiamare getEntryTerms() in loop:

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() restituisce una mappa da ID voce ai termini della tassonomia richiesta. getAllTermsForEntries() restituisce una mappa da ID voce a termini raggruppati per nome tassonomia. getTaxonomyTermsWithCacheHint() restituisce { data, cacheHint } per route con cache Astro.

Aree widget

Recupera aree widget e widget che contengono:

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) restituisce { data, cacheHint } per route con cache Astro. Aree e widget sono ordinati secondo l’ordine configurato.

Sections

Recupera sezioni e le filtra:

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?) restituisce { items: Section[]; nextCursor?: string }. Opzioni: source ("theme" | "user" | "import"), search, limit (predefinito 50, max. 100) e cursor.

Ricerca

Esegue ricerca globale nelle collection. I risultati includono snippet evidenziati:

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

Com scope: "title", query corrisponde solo al campo title de cada collection em vez do texto indexado completo — útil para selettori e autocompletamento dove corrispondenze nel corpo sorprenderebbero. Collections cujo title não está indexado para pesquisa não restituiscono resultados neste scope.

Gestione errori

Consultas de conteúdo restituiscono erros operacionais no resultado em vez de lançar. Voce mancante non è errore operacional: entry é null e error resta undefined.

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

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

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

Helper senza envelope risultato possono lanciare quando input non valido o operazione database fallisce. Gestisci errori al confine della route quando la pagina può fornire fallback utile. Classi errore repository e handler di integrazioni server di basso livello restano fuori da questa API modelli di sito.