JavaScript-API-Referenz

Auf dieser Seite

EmDash exportiert Funktionen zum Abfragen von Inhalten und für die Arbeit mit Vorschau, Einstellungen, Menüs, Taxonomien, Widget-Bereichen, Abschnitten und Suche.

Inhaltsabfragen

Die Abfragefunktionen von EmDash folgen dem Live Content Collections-Muster von Astro und geben { entries, error } oder { entry, error } für eine elegante Fehlerbehandlung zurück.

getEmDashCollection()

Alle Einträge einer Sammlung abrufen. Das folgende Beispiel lädt alle Posts und prüft auf Fehler:

import { getEmDashCollection } from "emdash";

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

if (error) {
	console.error("Posts konnten nicht geladen werden:", error);
}

Parameter

ParameterTypBeschreibung
collectionstringSammlungs-Slug
optionsCollectionFilterOptionale Filteroptionen

Optionen

Der options-Parameter akzeptiert folgenden Filter:

interface CollectionFilter {
	status?: "draft" | "published" | "archived";
	limit?: number;
	cursor?: string; // Keyset-Paginierung — übergib einen vorherigen `nextCursor`
	offset?: number; // Offset-Paginierung — überspringe N Einträge (mit `limit` verwenden)
	where?: Record<string, string | string[]>; // Nach Feld oder Taxonomie filtern
}

Rückgabe

Die Funktion löst zu einem CollectionResult auf:

interface CollectionResult<T> {
	entries: ContentEntry<T>[]; // Leeres Array bei Fehler oder wenn keine gefunden
	error?: Error; // Gesetzt, wenn Abfrage fehlgeschlagen
	nextCursor?: string; // Cursor für die nächste Keyset-Seite, falls vorhanden
	hasMore?: boolean; // Ob weitere Einträge über diese Seite hinaus existieren (wenn `limit` gesetzt)
}

Beispiele

Die folgenden Beispiele filtern nach Status und Taxonomie, begrenzen Ergebnisse und behandeln Fehler:

// Alle veröffentlichten Posts abrufen
const { entries: posts } = await getEmDashCollection("posts", {
	status: "published",
});

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

// Nach Taxonomie filtern
const { entries: newsPosts } = await getEmDashCollection("posts", {
	status: "published",
	where: { category: "news" },
});

// Nummerierte Archivseite (z.B. /page/3) mit Offset-Paginierung
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" },
});

// Fehler behandeln
const { entries, error } = await getEmDashCollection("posts");
if (error) {
	return new Response("Serverfehler", { status: 500 });
}

getEmDashEntry()

Einen einzelnen Eintrag nach Slug oder ID abrufen. Das folgende Beispiel lädt einen Post und leitet weiter, wenn er fehlt:

import { getEmDashEntry } from "emdash";

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

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

Parameter

ParameterTypBeschreibung
collectionstringSammlungs-Slug
slugOrIdstringEintrags-Slug oder ID
options{ locale?: string }Optional. Locale für Slug-Auflösung

Der Vorschaumodus wird automatisch gehandhabt — die Middleware erkennt _preview-Token und liefert Entwurfsinhalte über AsyncLocalStorage. Der optionale options-Parameter akzeptiert nur eine locale für die Slug-Auflösung; der Vorschaustatus erfordert keinen Parameter.

Rückgabe

Die Funktion löst zu einem EntryResult auf:

interface EntryResult<T> {
	entry: ContentEntry<T> | null; // null wenn nicht gefunden
	error?: Error; // Nur bei tatsächlichen Fehlern gesetzt, nicht bei "nicht gefunden"
	isPreview: boolean; // true wenn Entwurfsinhalt ausgeliefert wird
}

Beispiele

Die folgenden Beispiele rufen nach Slug und ID ab, lesen den Vorschaustatus und unterscheiden Fehler von Nicht-Gefunden:

// Nach Slug abrufen
const { entry: post } = await getEmDashEntry("posts", "hello-world");

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

// Vorschau ist automatisch — isPreview ist true wenn ein gültiger _preview-Token vorhanden ist
const { entry, isPreview, error } = await getEmDashEntry("posts", slug);

// Fehler vs. Nicht-Gefunden behandeln
if (error) {
	return new Response("Serverfehler", { status: 500 });
}
if (!entry) {
	return Astro.redirect("/404");
}

Inhaltstypen

ContentEntry

Abfragefunktionen geben Einträge in folgender Form zurück:

interface ContentEntry<T = Record<string, unknown>> {
	id: string;
	data: T;
	edit: EditProxy; // Visuelle Bearbeitungsannotationen
}

Der edit-Proxy bietet visuelle Bearbeitungsannotationen. Verteile ihn auf Elemente, um Inline-Bearbeitung zu aktivieren: {...entry.edit.title}. In der Produktion erzeugt dies keine Ausgabe.

Das data-Objekt enthält alle Inhaltsfelder plus Systemfelder:

  • id - Eindeutiger Bezeichner
  • slug - URL-freundlicher Bezeichner
  • status - “draft” | “published” | “archived”
  • createdAt - ISO-Zeitstempel
  • updatedAt - ISO-Zeitstempel
  • publishedAt - ISO-Zeitstempel oder null
  • Plus alle benutzerdefinierten Felder, die in deinem Sammlungsschema definiert sind

Vorschausystem

generatePreviewToken()

Einen Vorschau-Token für Entwurfsinhalte generieren. Das folgende Beispiel erstellt einen Token, der in einer Stunde abläuft:

import { generatePreviewToken } from "emdash";

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

verifyPreviewToken()

Einen Vorschau-Token verifizieren und seinen Inhalt lesen:

import { verifyPreviewToken } from "emdash";

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

if (result.valid) {
	const { cid, exp, iat } = result.payload;
	// cid ist im "collection:id"-Format, z.B. "posts:my-draft-post"
}

isPreviewRequest()

Prüfen, ob eine Anfrage einen Vorschau-Token enthält, dann auslesen:

import { isPreviewRequest, getPreviewToken } from "emdash";

if (isPreviewRequest(Astro.url)) {
	const token = getPreviewToken(Astro.url);
	// Verifizieren und Vorschauinhalt anzeigen
}

Inhaltskonverter

Zwischen Portable Text und ProseMirror-Formaten konvertieren:

import { prosemirrorToPortableText, portableTextToProsemirror } from "emdash";

// Von ProseMirror (Editor) zu Portable Text (Speicher)
const portableText = prosemirrorToPortableText(prosemirrorDoc);

// Von Portable Text zu ProseMirror
const prosemirrorDoc = portableTextToProsemirror(portableText);

Site-Einstellungen

Site-weite Einstellungen mit getSiteSettings und getSiteSetting lesen:

import { getSiteSettings, getSiteSetting } from "emdash";

// Alle Einstellungen abrufen
const settings = await getSiteSettings();

// Einzelne Einstellung abrufen
const title = await getSiteSetting("title");

Einstellungen sind über die Laufzeit-API nur lesbar. Verwende die Admin-API, um sie zu aktualisieren.

Menüs

Navigationsmenüs abrufen und ihre Elemente durchlaufen, einschließlich verschachtelter Kinder:

import { getMenu, getMenus } from "emdash";

// Alle Menüs abrufen
const menus = await getMenus();

// Bestimmtes Menü mit Elementen abrufen
const primaryMenu = await getMenu("primary");

if (primaryMenu) {
	primaryMenu.items.forEach(item => {
		console.log(item.label, item.url);
		// Verschachtelte Elemente für Dropdowns
		item.children.forEach(child => console.log("  -", child.label));
	});
}

Taxonomien

Taxonomie-Begriffe, einen einzelnen Begriff, die Begriffe eines Eintrags oder Einträge nach Begriff abrufen:

import { getTaxonomyTerms, getTerm, getEntryTerms, getEntriesByTerm } from "emdash";

// Alle Begriffe einer Taxonomie abrufen (Baumstruktur für hierarchische)
const categories = await getTaxonomyTerms("category");

// Einzelnen Begriff abrufen
const news = await getTerm("category", "news");

// Einem Inhaltseintrag zugewiesene Begriffe abrufen
const postCategories = await getEntryTerms("posts", "post-123", "category");

// Einträge mit einem bestimmten Begriff abrufen
const newsPosts = await getEntriesByTerm("posts", "category", "news");

Widget-Bereiche

Widget-Bereiche und die darin enthaltenen Widgets abrufen:

import { getWidgetArea, getWidgetAreas } from "emdash";

// Alle Widget-Bereiche abrufen
const areas = await getWidgetAreas();

// Bestimmten Widget-Bereich mit Widgets abrufen
const sidebar = await getWidgetArea("sidebar");

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

Abschnitte

Abschnitte abrufen und filtern:

import { getSection, getSections } from "emdash";

// Alle Abschnitte abrufen (paginiert)
const { items, nextCursor } = await getSections();

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

// Einen einzelnen Abschnitt nach Slug abrufen
const cta = await getSection("newsletter-cta");

getSections(options?) gibt { items: Section[]; nextCursor?: string } zurück. Optionen sind source ("theme" | "user" | "import"), search, limit (Standard 50, max 100) und cursor.

Suche

Eine globale Suche über Sammlungen ausführen. Ergebnisse enthalten hervorgehobene Ausschnitte:

import { search } from "emdash";

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

// search() löst zu { items, nextCursor? } auf
results.items.forEach(result => {
	console.log(result.title);
	console.log(result.snippet); // Enthält <mark>-Tags
	console.log(result.score);
});

// Paginieren: übergib den vorherigen nextCursor als `cursor`, um die nächste Seite zu erhalten.
// nextCursor ist undefined wenn keine weiteren Ergebnisse vorhanden sind.
if (results.nextCursor) {
	const next = await search("hello world", {
		collections: ["posts", "pages"],
		limit: 20,
		cursor: results.nextCursor,
	});
}

Fehlerbehandlung

EmDash exportiert Fehlerklassen für die Behandlung spezifischer Fehler. Das folgende Beispiel fängt Validierungs- und Schemafehler:

import {
  EmDashDatabaseError,
  EmDashValidationError,
  EmDashStorageError,
  SchemaError,
} from "emdash";

try {
  await repo.create({ ... });
} catch (error) {
  if (error instanceof EmDashValidationError) {
    console.error("Validierung fehlgeschlagen:", error.message);
  }
  if (error instanceof SchemaError) {
    console.error("Schemafehler:", error.code, error.details);
  }
}