Scribe

Медиафайлы

Объявляйте валидируемые поля файлов с помощью field.asset(), задавайте ограничения путей и форматов и преобразуйте их в публичные URL при чтении.

View as Markdown

Scribe работает со статическими файлами (сейчас это изображения) как с полноправными ссылками, объявленными в схеме. Они больше не являются просто свободными строками. Главный принцип гласит, что компоненты никогда не формируют URL файлов через конкатенацию строк. В секции frontmatter хранится каноничная ссылка на источник. Во время выполнения она преобразуется в итоговый URL при загрузке. Этот единственный уровень косвенности позволяет легко подключать publicPath, CDN и хеширование контента через конфигурацию. Никаких масштабных изменений в кодовой базе не требуется.

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

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

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()

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. Использование цепочки клонирует схему и теряет метаданные. Поля файлов всегда являются структурными. Пути к файлам никогда не отправляются переводчику.

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

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

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

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

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

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

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 к необработанной ссылке:

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

Вы также можете ссылаться на файлы напрямую внутри MDX-контента с помощью встроенного токена asset. Во время чтения он преобразуется аналогичным образом.

Валидация

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

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

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

Студия

В студии файлы представлены в режиме только для чтения:

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