---
order: 7
section: features
title: Медиафайлы
description: >-
  Объявляйте валидируемые поля файлов с помощью field.asset(), задавайте
  ограничения путей и форматов и преобразуйте их в публичные URL при чтении.
noindex: false
canonicalPath: /ru/docs/assets
---
Scribe работает со статическими файлами (сейчас это изображения) как с полноправными ссылками, объявленными в схеме. Они больше не являются просто свободными строками. Главный принцип гласит, что **компоненты никогда не формируют URL файлов через конкатенацию строк.** В секции frontmatter хранится каноничная *ссылка на источник*. Во время выполнения она преобразуется в *итоговый URL* при загрузке. Этот единственный уровень косвенности позволяет легко подключать `publicPath`, CDN и хеширование контента через конфигурацию. Никаких масштабных изменений в кодовой базе не требуется.

## Конфигурация

Блок конфигурации `assets` описывает расположение исходных файлов и способ их отдачи. Одиночный параметр `assetsDir` все еще работает как устаревший псевдоним для `{ dir: assetsDir }`.

```ts
export default defineConfig({
  // ...
  assets: {
    dir: "public",            // где исходные файлы лежат на диске, относительно rootDir. По умолчанию "public".
    publicPath: "/",          // префикс URL, по которому они отдаются. Путь ("/static/") или источник CDN. По умолчанию "/".
    managedDirs: ["/blog-images"], // дополнительные корневые каталоги веб-путей, управляемые Scribe, которые не покрыты никаким field.asset()
  },
});
```

Параметр `publicPath` следует правилам webpack/Vite для этого понятия. Записи `managedDirs` служат **корневыми каталогами источников**. Это папки, на которые ссылаются из MDX-контента и которые не привязаны к конкретному полю файла.

## `field.asset()`

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

const garmentSchema = z.object({
  title: field.translatable(z.string()),
  productImage: field.asset({
    dir: "/try-on/garments",   // значение должно находиться внутри этого веб-пути
    formats: ["webp"],          // список разрешенных расширений
    maxKB: 150,                 // лимит размера (предупреждение)
    optional: false,            // по умолчанию
  }),
});
```

Как и в случае с `field.relation()`, **ограничения задаются в объекте параметров, а не через цепочку методов Zod**. Использование цепочки клонирует схему и теряет метаданные. Поля файлов всегда являются структурными. Пути к файлам никогда не отправляются переводчику.

| Параметр | Тип | Значение |
| --- | --- | --- |
| `dir` | `string` | Префикс веб-пути, внутри которого должно находиться значение. Также объявляет управляемый корневой каталог. |
| `template` | `string` | Шаблон производного пути, например `"/try-on/garments/{slug}/product.webp"`. Здесь `{slug}` обозначает английский slug записи. Если шаблон задан, поле во frontmatter можно пропустить, и загрузчик заполнит его сам. Явно указанное значение переопределит шаблон (полезно для намеренного использования общих файлов у разных записей). |
| `formats` | `string[]` | Разрешенные расширения (в нижнем регистре, без точки). При нарушении выдается предупреждение валидации. |
| `maxKB` | `number` | Лимит размера файла. При превышении появится предупреждение валидации. |
| `optional` | `boolean` | Поле может отсутствовать (имеет смысл только без параметра `template`). Если значение указано, но сам файл отсутствует, это все равно вызовет ошибку. |

Значение во frontmatter представляет собой **веб-путь относительно корня** в `assets.dir` (например, `/try-on/garments/denim-flare/product.webp`). Это тот же формат, что и у обычной строки с изображением. Никаких новых схем URI не требуется. На диске frontmatter хранит ссылку на источник (или ничего, если используется шаблон). Итоговые URL существуют только в выводе среды выполнения. Статический экспорт и переводчик всегда видят исходные значения.

## Разрешение путей загрузчиком

При загрузке документа среда выполнения обходит схему в поисках полей файлов и для каждого выполняет следующие шаги:

1. Если значение во frontmatter отсутствует и поле имеет `template`, формирует путь на основе шаблона (при этом `{slug}` заменяется на английский slug).
2. Добавляет префикс `assets.publicPath` (соединение происходит без двойных слешей, также поддерживается `publicPath` с абсолютным источником).

В результате потребители получают готовые URL без дополнительных вызовов:

```ts
const garment = scribe.garment.get("denim-flare");
garment.frontmatter.productImage;
// "/try-on/garments/denim-flare/product.webp"                       (publicPath "/")
// "https://cdn.example.com/try-on/garments/denim-flare/product.webp" (CDN publicPath)
```

Разрешение путей происходит после объединения структурных полей с локализованными документами. Поэтому каждая локаль получает готовые значения из английского источника.

### `scribe.assets.url(ref)`

Это запасной вариант для изображений в теле MDX и нестандартных ситуаций. Он применяет `publicPath` к необработанной ссылке:

```ts
scribe.assets.url("/blog-images/hero.webp"); // применяется publicPath
```

Вы также можете ссылаться на файлы напрямую внутри MDX-контента с помощью [встроенного токена `asset`](/docs/inline-tokens). Во время чтения он преобразуется аналогичным образом.

## Валидация

Команда `scribe validate` проверяет объявленные поля файлов:

* **Отсутствует файл для обязательного поля файла**: ошибка (блокирует сборку аналогично повисшей обязательной связи).
* **Отсутствует файл для поля `optional` при наличии значения**: тоже ошибка. Параметр `optional` означает, что может отсутствовать само *поле*, а не физический файл по указанному пути.
* **Значение выходит за рамки каталога `dir` поля**: ошибка.
* **Расширение не входит в список `formats`**: предупреждение.
* **Размер файла превышает `maxKB`**: предупреждение.
* Шаблонные поля проверяют *сгенерированный* путь. Файл должен существовать, даже если значение во frontmatter пропущено.

Сообщения содержат привязку к полю, например `garment/denim-flare: productImage → /try-on/garments/denim-flare/product.webp not found`. Кроме того, строки, похожие на изображения и собранные эвристически из frontmatter и тела MDX, по-прежнему вызывают предупреждения при отсутствии файла. Это защищает изображения в тексте без необходимости выполнять миграцию.

## Студия

В [студии](/docs/studio) файлы представлены в режиме только для чтения:

* **Инспектор записей** отображает поля файлов в виде превью изображений с итоговым URL, размером файла и его габаритами. При отсутствии файла появляется красный значок.
* **Браузер файлов** (`/assets`) выводит сетку миниатюр для каждого управляемого корневого каталога. Для каждого файла указан путь, вес, размеры и список ссылающихся элементов (каждая запись и поле, указывающие на него). Специальные значки отмечают неиспользуемые файлы (потенциальный мусор), отсутствующие, но упомянутые в ссылках, превышающие лимит размера и файлы с отклонениями по формату.
* **Режим галереи** позволяет любому типу с полем файла отображать список записей в виде сетки карточек. Это удобная доска для контроля качества сгенерированных изображений.
