---
order: 1
section: start
title: Démarrage rapide
description: >-
  Installez scribe-cms, définissez un schéma, rédigez du contenu et récupérez-le
  typé en cinq étapes.
noindex: false
canonicalPath: /fr/docs/getting-started
---
## Installation

```bash
pnpm add scribe-cms zod better-sqlite3
```

Prérequis : Node 20+, Zod v4. Scribe est agnostique en termes de framework, il fonctionne avec n'importe quelle stack basée sur Node. `better-sqlite3` est un module natif, veillez donc à le conserver en dehors de votre bundler (consultez la page [API d'exécution](/docs/runtime-api)).

## 1. Créer `scribe.config.ts`

Placez-le à la racine de votre projet :

```ts
import { z } from "zod";
import { defineConfig, defineContentType, field } from "scribe-cms";

const blogSchema = z.object({
  title: field.translatable(z.string().min(1)),
  description: field.translatable(z.string().min(50).max(250)),
  author: field.relation("author"),
  tags: field.structural(z.array(z.string()).default([])),
});

const authorSchema = z.object({
  name: field.structural(z.string().min(1)),
});

export default defineConfig({
  rootDir: ".", // relative to this file (CLI) / process.cwd() (runtime)
  locales: ["en", "fr", "de"],
  types: [
    defineContentType({
      id: "blog",
      path: "/blog/{slug}",
      schema: blogSchema,
      slugStrategy: "localized",
      orderBy: "-publishedAt",
    }),
    defineContentType({
      id: "author",
      contentDir: "authors",
      schema: authorSchema,
    }),
  ],
});
```

`defineConfig` et `defineContentType` sont des fonctions d'identité qui préservent les types littéraux. C'est grâce à elles que `scribe.blog` et `related(doc, "author")` sont entièrement typés par la suite.

## 2. Rédiger le contenu

```text
content/
  blog/
    hello-world.mdx
  authors/
    jane.mdx
```

```mdx
---
title: "Bonjour tout le monde"
description: "Un premier article qui dit bonjour au monde, en détail, parce que le schéma exige cinquante caractères."
author: jane
publishedAt: "2026-01-15"
---

Le corps du texte est en MDX. Le **Markdown** et les composants fonctionnent parfaitement.
```

Le nom du fichier (`hello-world`) correspond au slug en anglais. `publishedAt` fait partie des champs intégrés disponibles pour chaque type. Consultez la page [modèle de contenu](/docs/content-model) pour en savoir plus.

## 3. Valider

Après un `pnpm install`, la CLI `scribe` est disponible dans votre PATH (tout comme `next`) :

```bash
pnpm scribe validate
pnpm scribe status
```

Ajoutez-le avant votre build :

```json
{
  "scripts": {
    "build": "scribe validate && <your framework build>"
  }
}
```

## 4. Lire le contenu

```ts
import { createScribe } from "scribe-cms/runtime";
import config from "./scribe.config";

const scribe = createScribe(config);

const posts = scribe.blog.list(); // BlogDoc[], newest first
const { document } = scribe.blog.resolve("hello-world", "fr");
const author = scribe.blog.related(document!, "author"); // AuthorDoc, non-null
```

`document.frontmatter` est typé à partir de votre schéma Zod. Consultez l'[API d'exécution](/docs/runtime-api) pour découvrir l'ensemble des possibilités.

## 5. Traduire

```bash
export GEMINI_API_KEY=...   # or put it in .env
npx scribe translate --locale fr
```

Scribe repère chaque page manquante ou obsolète en français, traduit les champs marqués avec `field.translatable()` puis stocke le résultat dans `.scribe/store.sqlite`. **Pensez à commiter ce répertoire**, n'ajoutez jamais `.scribe/` à votre fichier `.gitignore`. Plus de détails sur la page [traduction](/docs/translation).
