---
order: 2
section: guides
title: Configurazione
description: >-
  Tutte le opzioni di scribe.config.ts: impostazioni del progetto, tipi di
  contenuto, marcatori di campo e routing delle lingue.
noindex: false
canonicalPath: /it/docs/configuration
---
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

```ts
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](#locale-fallback-chains). |
| `localePresets` | — | Gruppi di lingue nominati per `scribe translate --preset name`. |
| `translate` | — | Impostazioni predefinite di traduzione per tutto il progetto ([traduzione](/docs/translation)). |
| `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

```ts
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](/docs/translation)). |

## Marcatori di campo

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

```ts
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](/docs/runtime-api).

## 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:

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

type MyScribe = ScribeClient<typeof config>;
type BlogDoc = ScribeDocs<typeof config>["blog"];
```
