Scribe

Configurazione

Tutte le opzioni di scribe.config.ts: impostazioni del progetto, tipi di contenuto, marcatori di campo e routing delle lingue.

View as Markdown

Tutto è gestito da un unico file, scribe.config.ts, che esporta defineConfig({...}). Sia il runtime (createScribe) che la CLI (che cerca scribe.config.ts nella directory di lavoro) leggono questo stesso file.

Opzioni di progetto

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: { /* vedi la pagina sulla traduzione */ },
  types: [ /* defineContentType(...) */ ],
});
OpzionePredefinitoDescrizione
rootDir— (obbligatorio)Radice del progetto. Mantienila relativa (solitamente "."): la CLI la risolve rispetto alla directory del file di configurazione, mentre createScribe rispetto a process.cwd(). Non costruirla usando import.meta.url: i bundler incorporano quel percorso durante la build, il che causa errori su host serverless come Vercel.
contentDir"content"Directory che contiene una cartella per ogni tipo di contenuto.
store".scribe/store.sqlite"Store delle traduzioni in SQLite. Includilo nei commit; non aggiungere .scribe/ al gitignore.
assetsDirRadice degli asset statici (es. "public"). Se impostata, scribe validate avvisa se nei frontmatter o nel corpo del testo ci sono percorsi a immagini inesistenti sul disco.
locales— (obbligatorio)Tutte le lingue supportate, inclusa quella predefinita.
defaultLocale"en"Lingua di origine canonica. Deve essere presente in locales.
localeRoutingpath-prefix, predefinito senza prefissoCome appaiono i marcatori di lingua negli URL generati. path-prefix antepone la lingua (omettendo quella predefinita, a meno che prefixDefaultLocale non sia true). search-param aggiunge ?param=locale per le lingue diverse da quella predefinita.
localeFallbackstrueDeriva le catene di fallback dai tag della lingua: a una variante regionale senza traduzione di un documento viene servita la traduzione nella lingua base più vicina (es. pt-BR fa fallback su pt) prima di passare al fallback della lingua predefinita. Imposta a false per disabilitare. Vedi Catene di fallback delle lingue.
localePresetsGruppi di lingue nominati per scribe translate --preset name.
translateImpostazioni predefinite di traduzione per tutto il progetto (traduzione).
types— (obbligatorio)Definizioni dei tipi di contenuto.

Le configurazioni vengono convalidate in anticipo: un defaultLocale sconosciuto, id di tipo duplicati o un template di path malformato generano subito un errore con un messaggio esplicativo.

Opzioni dei tipi di contenuto

defineContentType({
  id: "blog",
  schema: blogSchema,
  path: "/blog/{slug}",
  contentDir: "blog",          // default: l'id
  slugStrategy: "localized",   // default: "fixed"
  indexFallback: "en",         // default: "en" se path è impostato, altrimenti "none"
  orderBy: "-publishedAt",     // default: "slug"
  label: "Blog",               // default: id con l'iniziale maiuscola (solo per la UI dello studio)
  crossValidate: (data, ctx) => [],
  translate: { /* override specifici per tipo */ },
})
OpzioneDescrizione
idIdentificatore univoco. Diventa l'accessor tipizzato (scribe.blog) e la contentDir predefinita.
schemaSchema Zod per il frontmatter, con i relativi marcatori di campo (vedi sotto).
pathTemplate dell'URL con esattamente un {slug} (es. /blog/{slug}). Omettilo per i tipi di solo riferimento (autori, categorie) che non hanno pagine proprie.
contentDirCartella all'interno della contentDir del progetto che ospita i file .mdx di questo tipo.
slugStrategy"fixed": tutte le lingue usano lo slug inglese. "localized": il traduttore produce uno slug per ogni lingua (/fr/blog/bonjour-le-monde).
indexFallbackCosa restituisce resolve() quando una lingua non ha traduzione: "en" serve il documento in inglese (con actualLocale: "en"), "none" non restituisce nulla.
orderByOrdinamento predefinito per list(): "slug", "publishedAt", "-publishedAt", "updatedAt", "-updatedAt", oppure un comparatore (a, b) => number su documenti completamente tipizzati.
crossValidateConvalida aggiuntiva eseguita da scribe validate, che riceve il frontmatter parsato (tipizzato). Restituisce { field, message, level }[].
translatePrompt/regole/modelli di traduzione specifici per tipo (traduzione).

Marcatori di campo

Ogni campo dello schema appartiene a una di tre categorie. I campi non contrassegnati sono strutturali per impostazione predefinita.

import { field } from "scribe-cms";

const schema = z.object({
  // Inviato al traduttore, memorizzato per ogni lingua:
  title: field.translatable(z.string().min(1)),

  // Solo in inglese; copiato dal documento EN in ogni lingua:
  heroImage: field.structural(z.string().optional()),

  // Riferimento o riferimenti tramite slug in inglese a un altro tipo di contenuto:
  author: field.relation("author"),
  relatedPosts: field.relation("blog", { multiple: true, max: 4, optional: true }),
});

I marcatori traducibili funzionano anche sui campi nidificati all'interno di array o oggetti semplici (es. sections.*.title); assicurati solo di non racchiudere l'array contenitore in field.structural, altrimenti l'intero sottoalbero diventerà unicamente in inglese.

field.relation(typeId, options?)

OpzionePredefinitoDescrizione
multiplefalseIl campo è un array di slug.
optionalfalseIl campo può essere omesso. In tal caso related() restituisce null (singolo) o salta gli elementi mancanti (multiplo).
min / maxLimiti di conteggio degli elementi (solo per multiple: true).

I vincoli vanno inseriti nell'oggetto delle opzioni: non concatenati tramite i metodi Zod. Il concatenamento (es. .max(8), .optional()) clona lo schema e rimuoverebbe i metadati della relazione.

Le relazioni memorizzano sempre gli slug in inglese, vengono verificate da scribe validate (una relazione obbligatoria sospesa è un errore che blocca la build; una opzionale è un avviso) e vengono dereferenziate a runtime con related(); consulta le API di runtime.

Catene di fallback delle lingue

Per impostazione predefinita, a una lingua regionale sprovvista di traduzione per un documento viene servita la sua lingua base prima di passare alla lingua predefinita: ogni lingua prova i prefissi via via più corti del proprio tag che sono presenti in locales, quindi fr-CA fa fallback su fr, e zh-Hant-TW prova prima zh-Hant, poi zh. Imposta localeFallbacks: false per disabilitare questo comportamento. La lingua predefinita non fa mai parte di una catena; rimane il fallback finale, regolato da indexFallback del tipo.

I fallback si applicano a resolve() (la lingua servita viene riportata in actualLocale e i redirect degli slug usano lo slug della lingua di fallback) e a staticParams() (gli slug pre-renderizzati corrispondono a ciò che viene servito da resolve()). Volutamente, non si applicano a get(), list(), translation(), alternates() o alla sitemap: questi richiedono sempre una corrispondenza esatta.

Tipi client tipizzati

Per gli alias di tipo lato app, deriva tutto dalla configurazione:

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

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