Scribe

Assets (Recursos)

Declare campos de recursos validados com field.asset(), restrinja caminhos e formatos, e resolva-os para URLs públicas no momento da leitura.

View as Markdown

O Scribe trata os recursos estáticos (atualmente imagens) como referências de primeira classe declaradas em um esquema, e não como simples strings soltas. O princípio básico é que os componentes nunca montam URLs de recursos concatenando strings. O frontmatter armazena uma referência de origem canônica e o tempo de execução a transforma na URL final na hora do carregamento. Essa pequena camada de separação permite que você adicione configurações como publicPath, CDNs e hash de conteúdo sem precisar reescrever o código do projeto.

Configuração

O grupo de configuração assets define onde os arquivos de origem ficam guardados e como devem ser servidos. O antigo assetsDir ainda funciona como um atalho (agora descontinuado) para { dir: assetsDir }.

export default defineConfig({
  // ...
  assets: {
    dir: "public",            // onde os arquivos de origem ficam no disco, em relação ao rootDir. O padrão é "public".
    publicPath: "/",          // o prefixo da URL sob o qual são servidos. Um caminho ("/static/") ou uma origem de CDN. O padrão é "/".
    managedDirs: ["/blog-images"], // raízes extras de caminho da web gerenciadas pelo Scribe que não são cobertas por nenhum field.asset()
  },
});

O publicPath segue a convenção do webpack/Vite para esse conceito. As entradas em managedDirs são raízes de origem: diretórios que você menciona no meio dos textos em MDX e que não estão atrelados a um campo de recurso específico.

field.asset()

import { field } from "scribe-cms";

const garmentSchema = z.object({
  title: field.translatable(z.string()),
  productImage: field.asset({
    dir: "/try-on/garments",   // o valor deve estar dentro deste caminho da web
    formats: ["webp"],          // lista de extensões permitidas
    maxKB: 150,                 // limite de tamanho (gera um aviso)
    optional: false,            // padrão
  }),
});

Assim como no field.relation(), as restrições ficam no objeto de opções, não em métodos Zod encadeados. Se você encadear, o esquema é clonado e os metadados são perdidos. Os campos de recursos são sempre estruturais, ou seja, os caminhos dos recursos nunca são enviados para a equipe de tradução.

OpçãoTipoSignificado
dirstringPrefixo do caminho da web sob o qual o valor deve estar. Também declara uma raiz gerenciada.
templatestringModelo de caminho derivado. Por exemplo: "/try-on/garments/{slug}/product.webp". {slug} é o slug em inglês da entrada. Se você configurar isso, dá para omitir o campo no frontmatter e o carregador preenche para você. Se você passar um valor explícito, ele substitui o modelo (útil para compartilhar imagens entre entradas).
formatsstring[]Extensões permitidas (letras minúsculas, sem o ponto). Se sair disso, gera um aviso de validação.
maxKBnumberLimite de tamanho do arquivo. Se passar, gera um aviso de validação.
optionalbooleanO campo pode estar ausente (só faz sentido se não usar template). Se o valor estiver lá e o arquivo não existir, vai dar erro do mesmo jeito.

O valor no frontmatter é um caminho da web relativo à raiz dentro de assets.dir. Por exemplo, /try-on/garments/denim-flare/product.webp (a mesma regra de uma string de imagem normal, sem precisar inventar um esquema de URI novo). No disco, o frontmatter guarda a referência de origem (ou nada, se estiver usando um modelo). As URLs resolvidas só aparecem na saída do tempo de execução. As exportações estáticas/brutas e os tradutores sempre enxergam os valores de origem.

Resolução no carregamento

Quando o tempo de execução carrega um documento, ele varre o esquema procurando campos de recursos e, para cada um:

  1. Se não tiver um valor no frontmatter e o campo tiver um template, ele monta o caminho usando o modelo (o {slug} vira o slug em inglês).
  2. Adiciona o prefixo de assets.publicPath (juntando sem barras duplas; se for um publicPath de origem absoluta, também funciona).

Assim, quem consome os dados recebe a URL final de bandeja, sem precisar fazer mais nenhuma chamada:

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)

A resolução acontece depois que os campos estruturais são mesclados nos documentos localizados. Ou seja, todos os idiomas recebem os valores resolvidos direto da origem em inglês.

scribe.assets.url(ref)

Uma válvula de escape para imagens no corpo do MDX ou para casos avulsos. Aplica o publicPath direto em uma referência bruta:

scribe.assets.url("/blog-images/hero.webp"); // publicPath aplicado

Você também pode puxar recursos direto no corpo do MDX usando o token inline asset, que é resolvido do mesmo jeito na hora da leitura.

Validação

O comando scribe validate confere todos os campos de recursos que você declarou:

  • Arquivo faltando em um campo de recurso obrigatório: erro (para a build, igual quando falta uma relação obrigatória).
  • Arquivo faltando em um campo optional que tem valor: erro também. O optional significa que o campo pode ficar em branco, não que você pode inventar um caminho falso.
  • Valor fora do dir do campo: erro.
  • Extensão fora do formats: aviso.
  • Arquivo maior que o maxKB: aviso.
  • Campos que usam modelo validam o caminho materializado. O arquivo tem que existir, mesmo que o frontmatter não tenha o valor.

As mensagens dizem certinho de onde vem o problema. Por exemplo: garment/denim-flare: productImage → /try-on/garments/denim-flare/product.webp not found. Além disso, strings que parecem imagens e que a gente cata por heurística no frontmatter e no corpo do MDX ainda geram aviso quando não existem. Isso ajuda a cobrir as imagens do texto sem precisar migrar nada.

Studio

O studio mostra os recursos em modo somente leitura:

  • O inspetor de entrada mostra os campos de recursos como prévias de imagem com a URL resolvida, tamanho do arquivo e as dimensões. Se o arquivo estiver faltando, aparece um selo vermelho.
  • O navegador de recursos (/assets) exibe uma grade de miniaturas para cada raiz gerenciada. Cada recurso mostra seu caminho, tamanho, dimensões e uma lista com todos os campos e entradas que o referenciam. Selos ajudam a destacar recursos sem referência (candidatos a virar órfãos), referenciados mas que estão faltando, que passaram do tamanho ou que estão fora do formato.
  • A visualização em galeria permite que qualquer tipo com um campo de recurso mostre sua lista de entradas como uma grade de cartões. É ótimo para bater o olho e fazer o controle de qualidade das imagens geradas.
Assets (Recursos) · Scribe