Scribe

Configuration

Toutes les options de scribe.config.ts : paramètres du projet, types de contenu, marqueurs de champs et routage des langues.

View as Markdown

Tout est centralisé dans un seul fichier, scribe.config.ts, qui exporte defineConfig({...}). Le moteur d'exécution (createScribe) et la CLI (qui détecte scribe.config.ts dans le répertoire de travail) exploitent ce même fichier.  

Options du projet

export default defineConfig({
  rootDir: ".",
  contentDir: "content",             // default
  store: ".scribe/store.sqlite",     // default
  assetsDir: "public",               // optional
  locales: ["en", "fr", "de"],
  defaultLocale: "en",               // default
  localeRouting: { strategy: "path-prefix", prefixDefaultLocale: false },
  localeFallbacks: true,             // default
  localePresets: { active: ["fr"] },
  translate: { /* see the translation page */ },
  types: [ /* defineContentType(...) */ ],
});
OptionPar défautDescription
rootDir(requis)Racine du projet. Privilégiez un chemin relatif (généralement ".") : la CLI le résout par rapport au dossier du fichier de configuration, et createScribe par rapport à process.cwd(). Évitez de le construire avec import.meta.url : les bundlers intègrent ce chemin lors de la compilation, ce qui provoque des erreurs sur les hébergements serverless comme Vercel.
contentDir"content"Répertoire contenant un dossier par type de contenu.
store".scribe/store.sqlite"Base de données de traduction SQLite. Versionnez-la (commit) ; n'ajoutez pas .scribe/ à votre fichier gitignore.
assetsDir(aucun)Racine des fichiers statiques (par exemple "public"). Si elle est définie, scribe validate signale les chemins d'images inexistants dans le frontmatter ou le contenu.
locales(requis)Toutes les langues prises en charge, y compris celle par défaut.
defaultLocale"en"Langue source canonique. Doit figurer dans locales.
localeRoutingpath-prefix, sans préfixe par défautComment les marqueurs de langue s'affichent dans les URL générées. path-prefix ajoute la langue en préfixe (en omettant la langue par défaut sauf si prefixDefaultLocale est sur true). search-param ajoute ?param=locale pour les autres langues.
localeFallbackstrueDéduit les chaînes de repli à partir des balises de langue : une variante régionale sans traduction reçoit la traduction la plus proche dans la langue de base (par exemple, pt-BR se rabat sur pt) avant d'utiliser la langue par défaut. Réglez sur false pour désactiver ce comportement. Voir Chaînes de repli des langues.
localePresets(aucun)Groupes de langues nommés pour la commande scribe translate --preset name.
translate(aucun)Paramètres de traduction par défaut pour l'ensemble du projet (traduction).
types(requis)Définitions des types de contenu.

Les configurations sont validées en amont : une valeur defaultLocale inconnue, des identifiants de type en double ou un modèle path mal formulé déclenchent immédiatement une erreur accompagnée d'un message explicite.

Options des types de contenu

defineContentType({
  id: "blog",
  schema: blogSchema,
  path: "/blog/{slug}",
  contentDir: "blog",          // default: the id
  slugStrategy: "localized",   // default: "fixed"
  indexFallback: "en",         // default: "en" if path is set, else "none"
  orderBy: "-publishedAt",     // default: "slug"
  label: "Blog",               // default: capitalized id (studio UI only)
  crossValidate: (data, ctx) => [],
  translate: { /* per-type overrides */ },
})
OptionDescription
idIdentifiant unique. Devient l'accesseur typé (scribe.blog) et le contentDir par défaut.
schemaSchéma d'objet Zod pour le frontmatter, avec ses marqueurs de champs (voir ci-dessous).
pathModèle d'URL contenant exactement un {slug} (par exemple /blog/{slug}). À omettre pour les types de contenu strictement référentiels (auteurs, catégories) qui ne possèdent pas leurs propres pages.
contentDirDossier situé dans le contentDir du projet et contenant les fichiers .mdx de ce type.
slugStrategy"fixed" indique que toutes les langues utilisent le slug en anglais. "localized" indique que le traducteur génère un slug spécifique pour chaque langue (/fr/blog/bonjour-le-monde).
indexFallbackCe que renvoie resolve() lorsqu'une langue ne possède aucune traduction : "en" fournit le document en anglais (avec actualLocale: "en"), et "none" ne renvoie rien.
orderByTri par défaut pour list() : "slug", "publishedAt", "-publishedAt", "updatedAt", "-updatedAt", ou un comparateur (a, b) => number sur des documents entièrement typés.
crossValidateValidation supplémentaire exécutée par scribe validate, qui reçoit le frontmatter analysé et typé. Doit retourner { field, message, level }[].
translateInstructions, règles ou modèle de traduction spécifiques à ce type (traduction).

Marqueurs de champs

Chaque champ du schéma appartient à l'une des trois catégories suivantes. Les champs sans marqueur sont structurels par défaut.

import { field } from "scribe-cms";

const schema = z.object({
  // Envoyé au traducteur, stocké par langue :
  title: field.translatable(z.string().min(1)),

  // Uniquement en anglais ; copié du document EN vers chaque langue :
  heroImage: field.structural(z.string().optional()),

  // Référence(s) de slug en anglais vers un autre type de contenu :
  author: field.relation("author"),
  relatedPosts: field.relation("blog", { multiple: true, max: 4, optional: true }),
});

Les marqueurs traduisibles fonctionnent également sur les champs imbriqués dans des tableaux simples ou des objets (par exemple sections.*.title). Il suffit de ne pas envelopper le tableau conteneur avec field.structural, sinon l'intégralité de la sous-arborescence sera limitée à l'anglais.

field.relation(typeId, options?)

OptionPar défautDescription
multiplefalseLe champ est un tableau de slugs.
optionalfalseLe champ peut être omis. La fonction related() renvoie alors null (pour un élément unique) ou ignore les éléments manquants (pour les éléments multiples).
min / max(aucun)Limites de la quantité d'éléments (uniquement si multiple: true).

Les contraintes s'insèrent dans l'objet d'options, et non via des méthodes Zod chaînées. Un chaînage (comme .max(8) ou .optional()) clone le schéma et supprimerait les métadonnées de la relation.

Les relations stockent systématiquement les slugs en anglais. Elles sont vérifiées par scribe validate (une relation obligatoire pointant dans le vide bloque la compilation, tandis qu'une relation facultative orpheline génère un avertissement), et elles sont déréférencées à l'exécution avec related(). Consultez l'API d'exécution.

Chaînes de repli des langues

Par défaut, une langue régionale dépourvue de traduction pour un document se voit proposer sa langue de base avant la langue par défaut. Chaque langue teste successivement les préfixes plus courts de sa propre balise qui figurent également dans locales. Ainsi, fr-CA se rabat sur fr, et zh-Hant-TW essaie zh-Hant, puis zh. Réglez localeFallbacks: false pour désactiver cette fonction. La langue par défaut n'appartient jamais à une chaîne de repli. Elle demeure le recours ultime, régi par la propriété indexFallback du type de contenu.

Ces replis s'appliquent à resolve() (la langue servie est indiquée dans actualLocale et les redirections de slugs utilisent le slug de la langue de repli) ainsi qu'à staticParams() (les slugs pré-rendus correspondent à ce que sert resolve()). Ils ne s'appliquent volontairement pas à get(), list(), translation(), alternates() ni au sitemap : ceux-ci conservent une correspondance exacte.

Types clients typés

Pour les alias de types côté application, déduisez tout depuis la configuration :

import type { ScribeClient, ScribeDocs } from "scribe-cms/runtime";
import config from "./scribe.config";

type MyScribe = ScribeClient<typeof config>;
type BlogDoc = ScribeDocs<typeof config>["blog"];
Configuration · Scribe