Référence de l'API JavaScript

Sur cette page

EmDash exporte des fonctions pour interroger le contenu et travailler avec l’aperçu, les paramètres, les menus, les taxonomies, les zones de widgets, les sections et la recherche.

Requêtes de contenu

Les fonctions de requête d’EmDash suivent le modèle de collections de contenu en direct d’Astro, retournant { entries, error } ou { entry, error } pour une gestion élégante des erreurs.

getEmDashCollection()

Récupérer toutes les entrées d’une collection. L’exemple suivant charge tous les articles et vérifie les erreurs :

import { getEmDashCollection } from "emdash";

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

if (error) {
	console.error("Échec du chargement des articles :", error);
}

Paramètres

ParamètreTypeDescription
collectionstringSlug de la collection
optionsCollectionFilterOptions de filtre optionnelles

Options

Le paramètre options accepte le filtre suivant :

interface CollectionFilter {
	status?: "draft" | "published" | "archived";
	limit?: number;
	cursor?: string; // Pagination par keyset — passez un `nextCursor` précédent
	offset?: number; // Pagination par offset — sauter N entrées (utiliser avec `limit`)
	where?: Record<string, string | string[]>; // Filtrer par champ ou taxonomie
}

Retour

La fonction résout en un CollectionResult :

interface CollectionResult<T> {
	entries: ContentEntry<T>[]; // Tableau vide en cas d'erreur ou si aucun trouvé
	error?: Error; // Défini si la requête a échoué
	nextCursor?: string; // Curseur pour la prochaine page keyset, le cas échéant
	hasMore?: boolean; // S'il existe plus d'entrées au-delà de cette page (quand `limit` est défini)
}

Exemples

Les exemples suivants filtrent par statut et taxonomie, limitent les résultats et gèrent les erreurs :

// Obtenir tous les articles publiés
const { entries: posts } = await getEmDashCollection("posts", {
	status: "published",
});

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

// Filtrer par taxonomie
const { entries: newsPosts } = await getEmDashCollection("posts", {
	status: "published",
	where: { category: "news" },
});

// Page d'archive numérotée (ex. /page/3) avec pagination par offset
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" },
});

// Gérer les erreurs
const { entries, error } = await getEmDashCollection("posts");
if (error) {
	return new Response("Erreur serveur", { status: 500 });
}

getEmDashEntry()

Récupérer une entrée unique par slug ou ID. L’exemple suivant charge un article et redirige quand il est manquant :

import { getEmDashEntry } from "emdash";

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

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

Paramètres

ParamètreTypeDescription
collectionstringSlug de la collection
slugOrIdstringSlug ou ID de l’entrée
options{ locale?: string }Optionnel. Locale pour la résolution du slug

Le mode aperçu est géré automatiquement — le middleware détecte les tokens _preview et sert le contenu brouillon via AsyncLocalStorage. Le paramètre optionnel options n’accepte qu’un locale pour la résolution du slug ; l’état d’aperçu ne nécessite aucun paramètre.

Retour

La fonction résout en un EntryResult :

interface EntryResult<T> {
	entry: ContentEntry<T> | null; // null si non trouvé
	error?: Error; // Défini uniquement pour les erreurs réelles, pas pour "non trouvé"
	isPreview: boolean; // true si le contenu brouillon est servi
}

Exemples

Les exemples suivants récupèrent par slug et ID, lisent l’état d’aperçu et distinguent les erreurs des non-trouvés :

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

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

// L'aperçu est automatique — isPreview est true quand un token _preview valide est présent
const { entry, isPreview, error } = await getEmDashEntry("posts", slug);

// Gérer erreurs vs non-trouvé
if (error) {
	return new Response("Erreur serveur", { status: 500 });
}
if (!entry) {
	return Astro.redirect("/404");
}

Types de contenu

ContentEntry

Les fonctions de requête retournent des entrées sous la forme suivante :

interface ContentEntry<T = Record<string, unknown>> {
	id: string;
	data: T;
	edit: EditProxy; // Annotations d'édition visuelle
}

Le proxy edit fournit des annotations d’édition visuelle. Répartissez-le sur les éléments pour activer l’édition en ligne : {...entry.edit.title}. En production, cela ne produit aucune sortie.

L’objet data contient tous les champs de contenu plus les champs système :

  • id - Identifiant unique
  • slug - Identifiant convivial pour les URL
  • status - “draft” | “published” | “archived”
  • createdAt - Horodatage ISO
  • updatedAt - Horodatage ISO
  • publishedAt - Horodatage ISO ou null
  • Plus tous les champs personnalisés définis dans votre schéma de collection

Système d’aperçu

generatePreviewToken()

Générer un token d’aperçu pour le contenu brouillon. L’exemple suivant crée un token qui expire dans une heure :

import { generatePreviewToken } from "emdash";

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

verifyPreviewToken()

Vérifier un token d’aperçu et lire son contenu :

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 est au format "collection:id", ex. "posts:my-draft-post"
}

isPreviewRequest()

Vérifier si une requête inclut un token d’aperçu, puis le lire :

import { isPreviewRequest, getPreviewToken } from "emdash";

if (isPreviewRequest(Astro.url)) {
	const token = getPreviewToken(Astro.url);
	// Vérifier et afficher le contenu d'aperçu
}

Convertisseurs de contenu

Convertir entre les formats Portable Text et ProseMirror :

import { prosemirrorToPortableText, portableTextToProsemirror } from "emdash";

// De ProseMirror (éditeur) vers Portable Text (stockage)
const portableText = prosemirrorToPortableText(prosemirrorDoc);

// De Portable Text vers ProseMirror
const prosemirrorDoc = portableTextToProsemirror(portableText);

Paramètres du site

Lire les paramètres globaux du site avec getSiteSettings et getSiteSetting :

import { getSiteSettings, getSiteSetting } from "emdash";

// Obtenir tous les paramètres
const settings = await getSiteSettings();

// Obtenir un paramètre individuel
const title = await getSiteSetting("title");

Les paramètres sont en lecture seule depuis l’API d’exécution. Utilisez l’API d’administration pour les mettre à jour.

Récupérer les menus de navigation et parcourir leurs éléments, y compris les enfants imbriqués :

import { getMenu, getMenus } from "emdash";

// Obtenir tous les menus
const menus = await getMenus();

// Obtenir un menu spécifique avec ses éléments
const primaryMenu = await getMenu("primary");

if (primaryMenu) {
	primaryMenu.items.forEach(item => {
		console.log(item.label, item.url);
		// Éléments imbriqués pour les menus déroulants
		item.children.forEach(child => console.log("  -", child.label));
	});
}

Taxonomies

Récupérer les termes de taxonomie, un terme unique, les termes d’une entrée ou les entrées par terme :

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

// Obtenir tous les termes d'une taxonomie (structure arborescente pour les hiérarchiques)
const categories = await getTaxonomyTerms("category");

// Obtenir un terme unique
const news = await getTerm("category", "news");

// Obtenir les termes assignés à une entrée de contenu
const postCategories = await getEntryTerms("posts", "post-123", "category");

// Obtenir les entrées avec un terme spécifique
const newsPosts = await getEntriesByTerm("posts", "category", "news");

Zones de widgets

Récupérer les zones de widgets et les widgets qu’elles contiennent :

import { getWidgetArea, getWidgetAreas } from "emdash";

// Obtenir toutes les zones de widgets
const areas = await getWidgetAreas();

// Obtenir une zone de widgets spécifique avec ses widgets
const sidebar = await getWidgetArea("sidebar");

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

Sections

Récupérer les sections et les filtrer :

import { getSection, getSections } from "emdash";

// Obtenir toutes les sections (paginées)
const { items, nextCursor } = await getSections();

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

// Obtenir une section unique par slug
const cta = await getSection("newsletter-cta");

getSections(options?) retourne { items: Section[]; nextCursor?: string }. Les options sont source ("theme" | "user" | "import"), search, limit (défaut 50, max 100) et cursor.

Recherche

Exécuter une recherche globale à travers les collections. Les résultats incluent des extraits mis en évidence :

import { search } from "emdash";

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

// search() résout en { items, nextCursor? }
results.items.forEach(result => {
	console.log(result.title);
	console.log(result.snippet); // Contient des balises <mark>
	console.log(result.score);
});

// Paginer : passez le nextCursor précédent comme `cursor` pour obtenir la page suivante.
// nextCursor est undefined quand il n'y a plus de résultats.
if (results.nextCursor) {
	const next = await search("hello world", {
		collections: ["posts", "pages"],
		limit: 20,
		cursor: results.nextCursor,
	});
}

Gestion des erreurs

EmDash exporte des classes d’erreur pour gérer des échecs spécifiques. L’exemple suivant capture les erreurs de validation et de schéma :

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

try {
  await repo.create({ ... });
} catch (error) {
  if (error instanceof EmDashValidationError) {
    console.error("Validation échouée :", error.message);
  }
  if (error instanceof SchemaError) {
    console.error("Erreur de schéma :", error.code, error.details);
  }
}