---
order: 7
section: features
title: Activos
description: >-
  Define campos de activos validados mediante field.asset(), limita sus rutas y
  formatos, y resuélvelos a URL públicas en tiempo de lectura.
noindex: false
canonicalPath: /es/docs/assets
---
Scribe trata los activos estáticos (actualmente imágenes) como referencias de primera clase declaradas en el esquema, en lugar de simples cadenas de texto. El principio fundamental es que **los componentes nunca construyen URL de activos concatenando cadenas**. El frontmatter almacena una referencia de origen canónica, y el motor de ejecución la resuelve en la URL final al momento de cargarla. Esta única indirección es lo que permite integrar `publicPath`, redes CDN y el hash de contenido como parte de la configuración, sin tener que hacer migraciones en la base de código.

## Configuración

El grupo de configuración `assets` declara dónde se alojan los archivos de origen y cómo se sirven. El uso aislado de `assetsDir` sigue funcionando como un alias obsoleto de `{ dir: assetsDir }`.

```ts
export default defineConfig({
  // ...
  assets: {
    dir: "public",            // where source files live on disk, relative to rootDir. Default "public".
    publicPath: "/",          // URL prefix they are served under. A path ("/static/") or a CDN origin. Default "/".
    managedDirs: ["/blog-images"], // extra Scribe-owned web-path roots not covered by any field.asset()
  },
});
```

`publicPath` sigue la convención de webpack y Vite para este concepto. Las entradas de `managedDirs` son **directorios raíz de origen**: carpetas que se referencian desde el cuerpo de los archivos MDX y que no están vinculadas a un campo de activo específico.

## `field.asset()`

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

const garmentSchema = z.object({
  title: field.translatable(z.string()),
  productImage: field.asset({
    dir: "/try-on/garments",   // value must live under this web path
    formats: ["webp"],          // extension allowlist
    maxKB: 150,                 // size budget (warning)
    optional: false,            // default
  }),
});
```

Al igual que con `field.relation()`, **las restricciones se definen en el objeto de opciones y no encadenando métodos de Zod**; encadenar métodos clona el esquema y elimina los metadatos. Los campos de activos siempre son estructurales: las rutas de los activos nunca se envían al traductor.

| Opción | Tipo | Significado |
| --- | --- | --- |
| `dir` | `string` | Prefijo de la ruta web bajo el cual debe residir el valor. También declara una raíz administrada. |
| `template` | `string` | Plantilla para derivar rutas, por ejemplo, `"/try-on/garments/{slug}/product.webp"`. `{slug}` representa el slug en inglés de la entrada. Cuando se configura, el campo del frontmatter puede omitirse por completo para que el cargador lo complete; un valor explícito sobrescribe la plantilla (ideal para compartir activos entre entradas). |
| `formats` | `string[]` | Extensiones permitidas (en minúsculas y sin punto). Incumplir esto genera una advertencia de validación. |
| `maxKB` | `number` | Presupuesto de tamaño del archivo. Incumplir esto genera una advertencia de validación. |
| `optional` | `boolean` | Indica si el campo puede estar ausente (solo tiene sentido si no se usa `template`). Si el valor está presente pero el archivo no existe, se considera un error. |

El valor del frontmatter es una **ruta web relativa a la raíz** que apunta a `assets.dir` (por ejemplo, `/try-on/garments/denim-flare/product.webp`). Esto sigue la misma convención que una cadena de imagen normal, sin introducir esquemas de URI nuevos. En el disco, el frontmatter guarda la referencia de origen o se omite si se usa una plantilla. Las URL resueltas solo existen en la salida durante la ejecución; las exportaciones estáticas o sin procesar y el traductor siempre ven los valores de origen.

## Resolución del cargador

Cuando el motor de ejecución carga un documento, recorre el esquema en busca de campos de activos y, por cada uno:

1. Si el valor del frontmatter no existe y el campo tiene un atributo `template`, materializa la ruta a partir de la plantilla (`{slug}` se reemplaza por el slug en inglés).
2. Añade el prefijo `assets.publicPath` (uniéndolo sin barras dobles; se admite un `publicPath` de origen absoluto).

De este modo, los consumidores obtienen las URL definitivas sin realizar llamadas adicionales:

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

La resolución ocurre después de fusionar los campos estructurales en los documentos locales, por lo que cada idioma recibe los valores resueltos a partir del origen en inglés.

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

Esta es una vía de escape para las imágenes en el cuerpo del MDX y para casos especiales, la cual aplica el `publicPath` a una referencia sin procesar:

```ts
scribe.assets.url("/blog-images/hero.webp"); // publicPath applied
```

También puedes referenciar los activos directamente en el cuerpo de los archivos MDX mediante el [token en línea `asset`](/docs/inline-tokens), que se resuelve de la misma forma en el momento de lectura.

## Validación

El comando `scribe validate` comprueba los campos de activos declarados:

- **Archivo faltante en un campo de activo obligatorio**: error (bloquea la compilación, igual que una relación obligatoria huérfana).
- **Archivo faltante en un campo `optional` con un valor presente**: también es un error; que el campo sea `optional` significa que puede omitirse, no que la ruta indicada pueda ser falsa.
- **Valor fuera del directorio `dir` del campo**: error.
- **Extensión no incluida en `formats`**: advertencia.
- **Archivo que supera el tamaño de `maxKB`**: advertencia.
- Los campos con plantillas validan la ruta ya materializada: el archivo debe existir aunque el frontmatter omita el valor.

Los mensajes incluyen la atribución del campo, por ejemplo: `garment/denim-flare: productImage → /try-on/garments/denim-flare/product.webp not found`. Por otro lado, las cadenas que parecen imágenes (recopiladas heurísticamente del frontmatter y del cuerpo del MDX) siguen generando advertencias si no se encuentran, lo que cubre las imágenes del cuerpo sin requerir ninguna migración.

## Studio

El [studio](/docs/studio) muestra los activos en modo de solo lectura:

- **Inspector de entradas** presenta los campos de activos como vistas previas de imágenes con la URL resuelta, el tamaño del archivo y sus dimensiones. Si falta el archivo, aparece una etiqueta roja.
- **Navegador de activos** (`/assets`) muestra una cuadrícula de miniaturas por cada raíz administrada. Cada activo detalla su ruta, tamaño, dimensiones y una lista que indica qué entradas y campos lo están referenciando. Las etiquetas resaltan los activos que no tienen referencias (posibles elementos huérfanos), los que faltan pero están referenciados, los que superan el límite de tamaño y los que sufren desajustes de formato.
- **Vista de galería** permite que cualquier tipo de contenido con un campo de activo muestre su lista de entradas como una cuadrícula de tarjetas, ideal para funcionar como un panel de revisión visual (QA) de las imágenes generadas.
