Modèle de contenu
Fichiers, frontmatter, champs intégrés, redirections et ce que vérifie scribe validate.
View as MarkdownFichiers
Un document correspond à un fichier .mdx (ou .md) dans le dossier du type :
content/
blog/
hello-world.mdx → slug "hello-world"
_redirects.json → règles de redirection pour ce type (optionnel)
authors/
jane.mdx → slug "jane"
- Le nom du fichier correspond au slug anglais. Les slugs sont en minuscules et séparés par des tirets (kebab-case).
- Seuls les fichiers anglais existent sur le disque. Les versions localisées sont stockées dans la base SQLite.
- Les fichiers dont le nom commence par
_ou une majuscule (commePUBLISHING.md) sont ignorés. Vous pouvez ainsi conserver des notes à côté de votre contenu.
Frontmatter
Le frontmatter est en YAML. Il est validé par le schéma Zod du type :
---
title: "Hello, world"
description: "Une description suffisamment longue pour le schéma."
author: jane
publishedAt: "2026-01-15"
updatedAt: "2026-02-01"
---
Le corps est en MDX.
La validation suit votre schéma Zod. Avec un simple z.object, les clés inconnues sont ignorées en silence. Utilisez .strict() si vous souhaitez que les fautes de frappe dans les noms de champs fassent échouer la validation.
Champs frontmatter intégrés
Ces champs sont disponibles sur chaque type de contenu sans les déclarer dans le schéma. Ils sont extraits du frontmatter avant l'exécution de votre schéma. Leur déclaration dans votre schéma Zod n'a donc aucun effet :
| Champ | Type | Description |
|---|---|---|
publishedAt | Date ISO | Date de publication. |
updatedAt | Date ISO | Dernière mise à jour majeure. Par défaut, correspond à publishedAt. Alimente la balise lastModified du sitemap. |
noindex | booléen | Exclu du sitemap. Vous pouvez l'exposer sous forme de balise meta robots dans vos pages. |
canonicalPath | chaîne | Remplacer manuellement le chemin de l'URL canonique. |
Les documents localisés héritent de publishedAt, updatedAt, noindex et canonicalPath de leur parent anglais. Les traducteurs ne peuvent pas les modifier.
Chaque document chargé contient également slug, enSlug (le slug parent anglais, identique à slug pour les documents anglais), locale, frontmatter et content.
Types sans corps
Les collections uniquement destinées à servir de référence (comme un type model ou category dont le schéma est purement structurel) n'ont souvent aucun corps MDX. Déclarez body: false sur le type pour l'indiquer explicitement :
defineContentType({
id: "model",
contentDir: "models",
schema: modelSchema,
body: false, // les entrées se limitent au frontmatter
});
La valeur par défaut est body: true, ce qui garantit une compatibilité totale avec les versions précédentes. Sur un type body: false, tout contenu autre que des espaces constitue une erreur de validation, le chargeur ignore l'analyse MDX et les exports statiques ne produisent aucun corps. Un type sans corps possédant zéro champ traduisible est également exclu de tout processus de traduction (pas de bruit inutile). Un type sans corps qui possède encore un champ traduisible reste dans la liste des tâches à accomplir avec une charge utile uniquement composée du frontmatter. Consultez la section traduction pour connaître les règles de traduisibilité.
Au-delà du frontmatter
Les corps MDX offrent bien plus que du simple texte :
- Les jetons en ligne intègrent des liens, des URL de ressources et des littéraux non traduisibles directement dans le corps. Ils sont résolus par langue au moment de la lecture.
- Les ressources déclarées avec
field.asset()sont validées sur le disque et résolues sous forme d'URL publiques au moment du chargement.
Redirections : _redirects.json
Pour chaque dossier de type de contenu, ajoutez un fichier _redirects.json optionnel pour déclarer les migrations de slugs et les documents retirés. Les redirections persistent même après la suppression du fichier MDX source. Les slugs sources traduits sont automatiquement récupérés depuis SQLite.
{
"redirects": [
{ "from": "hello-world", "toSlug": "hello-scribe" },
{ "from": ["old-a", "old-b"], "toSlug": "hello-scribe" },
{ "from": "moved-post", "toType": "glossary", "toSlug": "virtual-try-on" },
{ "from": "retired-page", "toUrl": "/pricing" },
{ "from": "retired-ext", "toUrl": "https://example.com/app" }
]
}
Il existe trois types de redirections (une seule cible par entrée) :
| Type | Champs | Description |
|---|---|---|
| Même type | toSlug | Slug EN cible dans le même type de contenu. L'URL est construite à partir du path de ce type et localisée pour chaque langue. |
| Type croisé | toType + toSlug | Slug EN cible dans un autre type de contenu routable (doit comporter un path). |
| N'importe où | toUrl | Chemin sur le même site relatif à la racine ou URL externe absolue, identique pour chaque langue. |
from: Slug(s) EN uniquement. Les slugs sources traduits sont résolus depuis SQLite.- Paramètre
permanentoptionnel (par défauttrue).
Pour retirer ou renommer un document : ajoutez une entrée à _redirects.json, supprimez (ou renommez) le fichier MDX source, puis exécutez scribe validate et relancez la compilation. Les règles de redirection sont générées par buildAllContentRedirects() pour la configuration de votre proxy ou de votre framework.
Validation
scribe validate
Vérifie, pour chaque fichier anglais : l'analyse du schéma, la structure des champs intégrés, votre hook crossValidate et la compilation MDX du corps. Un corps qui ne peut pas être analysé en tant que MDX constitue une erreur bloquante pour la compilation, aussi bien pour les sources anglaises que pour les traductions enregistrées.
À l'échelle du projet, l'outil vérifie également : l'intégrité des relations (une relation requise non valide génère une erreur, une relation optionnelle non valide génère un avertissement), les règles de _redirects.json (cibles valides, pas de sources dupliquées, pas de chaînes de redirection), les règles de suffixe des slugs localisés, les champs de ressources déclarés (existence du fichier, formats, maxKB), les jetons de corps en ligne (balises mal formées, relations invalides, attribut :href vers des types non routables, clés vars manquantes, fichiers de ressources manquants), les types body: false contenant encore du contenu dans le corps, les ressources d'images manquantes lorsque le dossier des ressources est défini, ainsi que l'existence de la base de traduction.
Le code de sortie est non nul dès qu'une erreur est détectée. Exécutez-le avant votre compilation :
{
"scripts": {
"build": "scribe validate && <votre compilation de framework>"
}
}