---
order: 2
section: guides
title: Настройки
description: >-
  Все параметры scribe.config.ts: настройки проекта, типы контента, маркеры
  полей и маршрутизация локалей.
noindex: false
canonicalPath: /ru/docs/configuration
---
Все хранится в одном файле `scribe.config.ts`, который экспортирует `defineConfig({...})`. И среда выполнения (`createScribe`), и CLI (которая ищет `scribe.config.ts` в рабочей директории) читают один и тот же файл.

## Project options

```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: { /* see the translation page */ },
  types: [ /* defineContentType(...) */ ],
});
```

| Option | Default | Description |
| --- | --- | --- |
| `rootDir` | (required) | Корень проекта. Указывайте относительный путь (обычно `"."`): CLI разрешает его относительно папки с конфигом, а `createScribe` относительно `process.cwd()`. Не используйте `import.meta.url`: сборщики встраивают этот путь при сборке, что приводит к ошибкам на бессерверных платформах вроде Vercel. |
| `contentDir` | `"content"` | Папка, где каждому типу контента соответствует своя подпапка. |
| `store` | `".scribe/store.sqlite"` | SQLite база переводов. **Сделайте коммит этого файла, не добавляйте `.scribe/` в gitignore.** |
| `assetsDir` | | Корень для статики (например, `"public"`). Если параметр задан, команда `scribe validate` будет предупреждать о путях к картинкам в frontmatter или теле документа, которых нет на диске. |
| `locales` | (required) | Все локали, включая локаль по умолчанию. |
| `defaultLocale` | `"en"` | Каноничная исходная локаль. Должна быть указана в `locales`. |
| `localeRouting` | path-prefix, unprefixed default | Как маркеры локалей отображаются в сгенерированных URL. `path-prefix` добавляет локаль в начало (пропуская локаль по умолчанию, если `prefixDefaultLocale` не равно `true`). `search-param` добавляет `?param=locale` для всех локалей, кроме основной. |
| `localeFallbacks` | `true` | Строит цепочки запасных локалей (фолбэков) на основе их тегов. Если для региональной локали нет перевода, используется ближайший перевод на базовый язык (например, для `pt-BR` фолбэком станет `pt`), и только потом локаль по умолчанию. Установите `false` для отключения. См. [Цепочки запасных локалей](#locale-fallback-chains). |
| `localePresets` | | Именованные группы локалей для `scribe translate --preset name`. |
| `translate` | | Глобальные настройки перевода ([перевод](/docs/translation)). |
| `types` | (required) | Определения типов контента. |

Конфигурации проверяются заранее. Неизвестная `defaultLocale`, дублирующиеся ID типов или неверный формат `path` сразу вызывают ошибку с понятным описанием.

## Content type options

```ts
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 */ },
})
```

| Option | Description |
| --- | --- |
| `id` | Уникальный идентификатор. Становится типизированным аксессором (`scribe.blog`) и значением по умолчанию для `contentDir`. |
| `schema` | Zod-схема для frontmatter с маркерами полей (см. ниже). |
| `path` | URL-шаблон ровно с одним `{slug}` (например, `/blog/{slug}`). Не указывайте для типов, которые служат **только для связи** (авторы, категории) и не имеют собственных страниц. |
| `contentDir` | Папка внутри проектного `contentDir`, в которой лежат `.mdx` файлы этого типа. |
| `slugStrategy` | `"fixed"` означает, что все локали используют английский слаг. `"localized"` позволяет переводчику создавать слаги для каждой локали (`/ru/blog/privet-mir`). |
| `indexFallback` | Что возвращает `resolve()`, если для локали нет перевода. `"en"` отдает английский документ (с `actualLocale: "en"`), `"none"` не возвращает ничего. |
| `orderBy` | Сортировка по умолчанию для `list()`. Варианты: `"slug"`, `"publishedAt"`, `"-publishedAt"`, `"updatedAt"`, `"-updatedAt"` или функция-компаратор `(a, b) => number` для строго типизированных документов. |
| `crossValidate` | Дополнительная проверка при вызове `scribe validate`, которая получает разобранный (типизированный) frontmatter. Возвращает массив `{ field, message, level }[]`. |
| `translate` | Настройки промптов, правил и модели для конкретного типа контента ([перевод](/docs/translation)). |

## Field markers

Каждое поле схемы относится к одному из трех типов. Поля без маркеров по умолчанию считаются **структурными**.

```ts
import { field } from "scribe-cms";

const schema = z.object({
  // Sent to the translator, stored per locale:
  title: field.translatable(z.string().min(1)),

  // English-only; copied from the EN document into every locale:
  heroImage: field.structural(z.string().optional()),

  // English slug reference(s) to another content type:
  author: field.relation("author"),
  relatedPosts: field.relation("blog", { multiple: true, max: 4, optional: true }),
});
```

Маркеры перевода работают и для полей внутри обычных массивов или объектов (например, `sections.*.title`). Главное не оборачивать родительский массив в `field.structural`, иначе все вложенные элементы станут исключительно английскими.

### `field.relation(typeId, options?)`

| Option | Default | Description |
| --- | --- | --- |
| `multiple` | `false` | Поле является массивом слагов. |
| `optional` | `false` | Поле можно не указывать. В этом случае `related()` возвращает `null` (если поле одно) или пропускает отсутствующие элементы (если это массив). |
| `min` / `max` | | Ограничения на количество элементов (только при `multiple: true`). |

Ограничения указываются в объекте параметров, а **не** через цепочки методов Zod. Цепочки (например, `.max(8)`, `.optional()`) клонируют схему и стирают метаданные связей.

Связи всегда хранят **английские слаги**. Они проверяются командой `scribe validate` (отсутствующая обязательная связь это ошибка, блокирующая сборку, а отсутствующая необязательная вызывает предупреждение). Связи разрешаются во время выполнения через `related()`. Смотрите [API среды выполнения](/docs/runtime-api).

## Locale fallback chains

По умолчанию, если для региональной локали нет перевода документа, перед локалью по умолчанию отдается версия на базовом языке. Для этого перебираются все более короткие префиксы собственного тега локали, которые также есть в `locales`. Так, `fr-CA` откатывается к `fr`, а `zh-Hant-TW` сначала проверяет `zh-Hant`, затем `zh`. Чтобы отключить это поведение, установите `localeFallbacks: false`. Локаль по умолчанию никогда не участвует в цепочке. Она остается последним запасным вариантом, который зависит от параметра `indexFallback` конкретного типа контента.

Фолбэки применяются в `resolve()` (отданная локаль указывается в `actualLocale`, а редиректы слагов используют слаг запасной локали) и `staticParams()` (пререндерятся те же слаги, которые отдает `resolve()`). Они намеренно **не** применяются к `get()`, `list()`, `translation()`, `alternates()` или карте сайта. Для них всегда требуется точное совпадение.

## Typed client types

Для псевдонимов типов на стороне приложения выводите все прямо из конфига:

```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"];
```
