Medios
Imágenes y archivos viven en la biblioteca de medios del workspace. Cómo los referencian los bloques, por qué cada subida tiene su propia URL y qué implica al reemplazar.
Los medios son de nivel workspace, no de página. Una biblioteca, organizada en carpetas, compartida por cada página y cada bloque.
El campo de medios
Un bloque alcanza un recurso mediante fields.media:
export const imageProps = {
src: fields.media({ label: "Image", required: true }),
alt: fields.text({ label: "Alt text" }),
};El valor guardado es una cadena con la URL, no un id ni un objeto. Tu componente lo recibe listo para usar:
function ImageBlock({ content }) {
if (!content.src) return null;
return <img src={content.src} alt={content.alt ?? ""} />;
}Como el valor es una URL simple, un campo de medios no cuesta nada al renderizar: no hay búsqueda, ni paso de resolución, ni un estado en el que la imagen aún carga.
Cada subida obtiene su propia URL
Los recursos subidos se sirven desde un host CDN, con un hash en la ruta:
https://assets.cmssy.io/{workspaceId}/78aa0167-cmssy-og-default.pngEse hash es por subida. Es lo que hace los recursos inmutables y cacheables para siempre, pero tiene una consecuencia que se suele aprender por las malas:
Subir un reemplazo no actualiza los bloques que apuntan al archivo antiguo. Una subida nueva es una URL nueva; los bloques existentes conservan la vieja y siguen mostrando la imagen vieja. Si cambiaste un logo y el sitio sigue mostrando el anterior, no hay nada mal cacheado: los bloques simplemente apuntan donde siempre apuntaron.
No hay sustitución en el sitio: las herramientas de medios son listar, subir y mover, así que un archivo nuevo siempre significa una URL nueva. El remedio es reapuntar los bloques: un buscar y reemplazar sobre el contenido de bloques, algo en lo que el servidor MCP es bueno.
Conviene planear la consecuencia práctica. Un recurso al que apuntan muchas páginas -un logo, una imagen OG por defecto- sale más barato de cambiar si pasa por la configuración del sitio o por un solo bloque, en vez de estar pegado en veinte lugares.
Carpetas
Las carpetas son un árbol plano con parentId. Organizan la biblioteca para las personas; no forman parte de la URL, así que mover un recurso entre carpetas no rompe nada.
Por MCP puedes listar, crear, renombrar, borrar y mover, lo que convierte una reorganización masiva en un script en vez de una tarde arrastrando.
Imágenes en Next.js
Los recursos vienen de un origen distinto al de tu app, así que next/image los rechazará hasta que permitas el host:
// next.config.mjs
const nextConfig = {
images: {
remotePatterns: [
{ protocol: "https", hostname: "assets.cmssy.io" },
],
},
};Un comodín hostname: "**" funciona y es lo que usa la app de referencia, pero deja pasar cualquier host HTTPS por tu optimizador de imágenes. Nombrar el host de recursos es la opción más estricta y cuesta una línea.
El texto alternativo es contenido
Empareja cada fields.media con un campo de texto para el alt y deja que lo rellenen los editores. El alt describe qué significa la imagen en este contexto: la misma foto necesita alt distinto en un caso de éxito y en un muro de logos. No puede ser una propiedad del archivo, y por eso pertenece al bloque y no a la biblioteca.
Siguientes pasos
- Esquema de bloque y tipos de campo:
fields.mediaentre los demás. - Servidor MCP: automatizar subidas y movimientos.
- Branding: logo e imagen OG en la configuración del sitio.