Configurazione
Tutte le opzioni di scribe.config.ts: impostazioni del progetto, tipi di contenuto, marcatori di campo e routing delle lingue.
View as MarkdownTutto è 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(...) */ ],
});
| Opzione | Predefinito | Descrizione |
|---|---|---|
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. |
assetsDir | — | Radice 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. |
localeRouting | path-prefix, predefinito senza prefisso | Come 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. |
localeFallbacks | true | Deriva 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. |
localePresets | — | Gruppi di lingue nominati per scribe translate --preset name. |
translate | — | Impostazioni 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 */ },
})
| Opzione | Descrizione |
|---|---|
id | Identificatore univoco. Diventa l'accessor tipizzato (scribe.blog) e la contentDir predefinita. |
schema | Schema Zod per il frontmatter, con i relativi marcatori di campo (vedi sotto). |
path | Template dell'URL con esattamente un {slug} (es. /blog/{slug}). Omettilo per i tipi di solo riferimento (autori, categorie) che non hanno pagine proprie. |
contentDir | Cartella 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). |
indexFallback | Cosa restituisce resolve() quando una lingua non ha traduzione: "en" serve il documento in inglese (con actualLocale: "en"), "none" non restituisce nulla. |
orderBy | Ordinamento predefinito per list(): "slug", "publishedAt", "-publishedAt", "updatedAt", "-updatedAt", oppure un comparatore (a, b) => number su documenti completamente tipizzati. |
crossValidate | Convalida aggiuntiva eseguita da scribe validate, che riceve il frontmatter parsato (tipizzato). Restituisce { field, message, level }[]. |
translate | Prompt/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?)
| Opzione | Predefinito | Descrizione |
|---|---|---|
multiple | false | Il campo è un array di slug. |
optional | false | Il campo può essere omesso. In tal caso related() restituisce null (singolo) o salta gli elementi mancanti (multiplo). |
min / max | — | Limiti 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"];