Biblioteca de medios

En esta página

EmDash incluye una biblioteca de medios para gestionar imágenes, documentos y otros archivos. Esta guía cubre la subida, búsqueda y uso de medios en tu contenido.

Acceder a la biblioteca de medios

Abre la biblioteca de medios desde la barra lateral del admin haciendo clic en Medios. La biblioteca principal muestra carpetas y archivos que no están asignados a una carpeta. Abre una carpeta para ver sus archivos.

Biblioteca de medios de EmDash mostrando cuadrícula de imágenes con botón de subida

Usado en

Abre un archivo en la biblioteca de medios de EmDash para ver las entradas de contenido que lo referencian. Mientras EmDash escanea el contenido existente, la lista incluye las referencias encontradas hasta el momento y puede estar incompleta.

Activar el seguimiento de uso de medios

Si el seguimiento de uso de medios está desactivado, un administrador puede activarlo:

  1. Finaliza cualquier edición de contenido. Si otra aplicación escribe directamente en la base de datos de contenido, páusala y espera a que termine cualquier escritura en progreso.
  2. Abre Configuración → Seguimiento de uso de medios, selecciona Habilitar seguimiento y confirma.
  3. Cuando la página muestre Indexando contenido existente, las ediciones y otras escrituras de base de datos pueden reanudarse.
  4. Mantén la página abierta hasta que muestre Listo. Si la abandonas, regresa para continuar desde el progreso guardado.

Una vez activado el seguimiento de uso de medios, no se puede desactivar.

Subir archivos

Desde la biblioteca de medios

  1. Abre Medios en la barra lateral del admin.

  2. Selecciona Subir archivos, luego Examinar archivos para elegir uno o más archivos. También puedes arrastrar archivos a cualquier parte de la biblioteca de medios.

  3. Las subidas comienzan automáticamente. El diálogo muestra el estado de cada archivo y permite cancelar o reintentar archivos individuales.

Desde el editor de contenido

  1. Abre un campo de imagen, archivo o galería en el editor de contenido.

  2. Busca, filtra por tipo, navega por una carpeta o cambia entre las fuentes de medios disponibles.

  3. Selecciona medios existentes, o selecciona Subir archivos y elige archivos desde tu computadora. También puedes soltar archivos en el selector. Cada subida aparece en los resultados con su estado actual.

  4. Si una subida falla, selecciona Reintentar o Eliminar en ese elemento. Una subida exitosa se convierte en una tarjeta de medio seleccionada.

  5. Para una galería, usa los controles de flechas bajo Medios seleccionados para establecer el orden.

  6. Selecciona la acción del selector, como Seleccionar, Insertar imagen o Agregar 3 imágenes.

Tipos de archivo soportados

EmDash acepta estos tipos de archivo por defecto:

CategoríaExtensiones
Imágenes.jpg, .jpeg, .png, .gif, .webp, .avif
Documentos.pdf
Video.mp4, .webm, .mov
Audio.mp3, .wav, .ogg

Los campos de imagen y archivo pueden permitir otros tipos MIME, incluyendo image/svg+xml para archivos SVG.

Backends de almacenamiento

EmDash soporta múltiples backends de almacenamiento. Configura el almacenamiento en tu configuración de Astro:

Almacenamiento local

import { defineConfig } from "astro/config";
import emdash, { local } from "emdash/astro";

export default defineConfig({
  integrations: [
    emdash({
      storage: local({
        directory: "./uploads",
        baseUrl: "/_emdash/api/media/file",
      }),
    }),
  ],
});

Los archivos se almacenan en el directorio ./uploads. Adecuado para desarrollo y despliegues de servidor único.

Cloudflare R2

import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";

export default defineConfig({
  integrations: [
    emdash({
      storage: r2({
        binding: "MEDIA_BUCKET",
        publicUrl: "https://media.example.com",
      }),
    }),
  ],
});

Requiere un bucket R2 configurado en wrangler.jsonc:

{
	"r2_buckets": [
		{
			"binding": "MEDIA_BUCKET",
			"bucket_name": "my-media-bucket",
		},
	],
}

Compatible con S3

import { defineConfig } from "astro/config";
import emdash, { s3 } from "emdash/astro";

export default defineConfig({
  integrations: [
    emdash({
      storage: s3({
        endpoint: "https://s3.amazonaws.com",
        bucket: "my-media-bucket",
        accessKeyId: process.env.S3_ACCESS_KEY_ID,
        secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
        region: "us-east-1",
        publicUrl: "https://media.example.com",
      }),
    }),
  ],
});

Funciona con Cloudflare R2 (vía API S3), MinIO y otros servicios compatibles con S3.

Cómo funcionan las subidas

El admin usa el flujo de destino de subida:

  1. El cliente solicita un destino de subida, y EmDash crea un elemento multimedia pendiente.

  2. El cliente sube el archivo al destino devuelto.

  3. El cliente confirma la subida.

  4. EmDash valida el archivo almacenado y marca el elemento multimedia como listo.

El almacenamiento compatible con S3 devuelve una URL firmada para que el archivo pueda evitar el runtime de la aplicación. El almacenamiento local y R2 nativo devuelven un endpoint de streaming del mismo origen.

Encontrar medios

Búsqueda

Usa el cuadro de búsqueda para encontrar archivos por nombre. La búsqueda coincide con nombres de archivo parciales.

Filtrar por tipo

Usa el filtro de tipo para mostrar imágenes, documentos, archivos de video o audio.

Organizar medios en carpetas

Los editores pueden seleccionar Agregar nueva carpeta desde la biblioteca principal. Abre una carpeta seleccionando su nombre. Sin un término de búsqueda, las páginas de carpetas muestran solo los medios asignados a esa carpeta. Las búsquedas por nombre de archivo cubren toda la biblioteca, incluyendo otras carpetas y la biblioteca principal.

Para mover un archivo local a una carpeta visible, arrastra su tarjeta de cuadrícula o fila de lista sobre la carpeta. También puedes abrir Detalles del medio, elegir una Ubicación y seleccionar Guardar. Usa Ubicación para devolver un archivo a la biblioteca principal o moverlo sin arrastrar.

Los autores pueden mover archivos locales que subieron. Los editores pueden mover cualquier archivo local. Los archivos de proveedores externos no pueden asignarse a carpetas.

Las subidas entran en la biblioteca principal. Muévelos a una carpeta después de la subida usando cualquiera de los métodos anteriores.

Eliminar una carpeta devuelve sus medios a la biblioteca principal. Los archivos multimedia, URLs y referencias de contenido permanecen sin cambios.

Usar medios en contenido

En el editor de texto enriquecido

  1. Coloca el cursor donde quieres la imagen

  2. Haz clic en el botón de imagen en la barra de herramientas

  3. Encuentra una imagen en el selector o sube una nueva.

  4. Selecciona Insertar imagen.

  5. Agrega texto alternativo en la configuración de imagen.

Como imagen destacada

  1. Abre una entrada de contenido en el editor

  2. Encuentra el campo Imagen destacada en la barra lateral

  3. Haz clic en Seleccionar imagen

  4. Elige una imagen del selector o sube una.

  5. Selecciona Seleccionar, luego Guardar.

En campos personalizados

Para campos configurados como tipos de imagen o archivo, selecciona la acción del campo para abrir el mismo selector de medios. Las reglas de tipo MIME del campo limitan las fuentes y archivos que puedes elegir.

Editar un recurso de imagen seleccionado

Los campos de imagen locales, imágenes de texto enriquecido e imágenes de galería proporcionan tres acciones:

  • Reemplazar cambia la imagen usada en el campo, bloque o posición de galería actual.
  • Editar recurso abre los Detalles del medio para el elemento seleccionado de la Biblioteca de medios. Puedes actualizar su texto alternativo, pie de foto, punto focal o recorte mientras permaneces en el editor de contenido.
  • Eliminar limpia la referencia de contenido actual. El elemento de la Biblioteca de medios permanece disponible.

Crear copia recortada selecciona la nueva copia para el uso actual. Las imágenes de texto enriquecido y galería mantienen su texto alternativo, pie de foto, diseño y posición por uso. Reemplazar original mantiene la misma referencia multimedia y cambia la imagen en todas partes donde se usa ese recurso.

Las imágenes de proveedores externos y campos de archivo proporcionan Reemplazar y Eliminar, pero no Editar recurso.

Reemplazar una imagen

Usa Reemplazar imagen para actualizar el archivo detrás de un elemento multimedia local existente. Los autores pueden reemplazar imágenes que subieron, y los editores pueden reemplazar cualquier imagen local. La acción está disponible para imágenes JPEG, PNG y WebP almacenadas en disco local, Cloudflare R2 o almacenamiento compatible con S3.

  1. Abre Medios, luego selecciona una imagen de la biblioteca local.
  2. Permanece en Detalles, luego selecciona Reemplazar imagen.
  3. Elige una imagen no vacía en el mismo formato que el archivo existente.
  4. Revisa la advertencia, luego selecciona Reemplazar imagen para confirmar.

El reemplazo puede usar dimensiones diferentes o una relación de aspecto diferente a la imagen existente. EmDash mantiene el ID del medio, nombre de archivo, URL, texto alternativo, pie de foto y ubicación, por lo que cada referencia existente usa el reemplazo. Reemplazar el archivo borra su punto focal.

Reemplazar imagen sube otro archivo desde tu computadora. Para recortar la imagen actual, selecciona Reemplazar original desde el editor de Recorte.

Establecer un punto focal

Un punto focal mantiene visible la parte importante de una imagen local cuando una tarjeta, galería u otro diseño la recorta para llenar una forma fija.

  1. Abre Medios y selecciona una imagen de la biblioteca local, o selecciona Editar recurso para una imagen local en el editor de contenido.
  2. Selecciona Editar imagen, luego Punto focal.
  3. Haz clic o arrastra el marcador a la parte importante de la imagen. También puedes usar las teclas de flecha.
  4. Verifica las vistas previas cuadrada, horizontal y vertical, luego selecciona Guardar.

Selecciona Restablecer para eliminar un punto focal personalizado. El punto guardado se copia cuando seleccionas la imagen para un campo de contenido o galería. Otro contenido que ya usa la imagen mantiene su punto almacenado hasta que selecciones la imagen nuevamente. Cuando editas un recurso desde un campo de contenido o galería, ese uso actual se actualiza con el punto focal guardado.

Recortar una imagen

El recorte está disponible para imágenes JPEG, PNG y WebP subidas a EmDash. Funciona con almacenamiento local, Cloudflare R2 y almacenamiento compatible con S3. Las imágenes de proveedores de medios externos no pueden recortarse en la Biblioteca de medios.

  1. Abre Medios, luego selecciona una imagen de la biblioteca local.
  2. Selecciona Editar imagen, luego Recortar.
  3. Selecciona Original, Forma libre o una relación de aspecto común. Las relaciones fijas permanecen bloqueadas mientras cambias el tamaño. Forma libre te permite cambiar el ancho y alto independientemente.
  4. Mueve el marco de recorte sobre la imagen. Para una relación fija, arrastra una esquina para cambiar el tamaño. Forma libre también proporciona cuatro controles de borde. La cuadrícula de regla de tercios permanece visible. Puedes enfocar el marco o un control y usar las teclas de flecha. Mantén Shift para pasos más grandes.
  5. Selecciona una de las acciones de recorte:
    • Crear copia recortada crea un elemento multimedia separado y deja el original sin cambios. Selecciona la copia recortada en cada entrada de contenido donde quieras usarla.
    • Reemplazar original reemplaza la imagen en todas partes donde se usa el elemento multimedia. Las entradas de contenido existentes mantienen la misma referencia multimedia y no se reescriben ni republican.

Recortar un archivo WebP produce una imagen WebP estática. Si la fuente es animada, el resultado recortado no retiene la animación.

Mostrar medios en plantillas

Accede a las URLs de medios desde tus datos de contenido:

---
import { getEmDashEntry } from "emdash";

const { entry: post } = await getEmDashEntry("posts", Astro.params.slug);
---

{post?.data.featured_image && (
  <img
    src={post.data.featured_image}
    alt={post.data.featured_image_alt ?? ""}
  />
)}

Imágenes responsivas

Para campos de medios de EmDash, usa el componente Image de emdash/ui:

---
import { Image } from "emdash/ui";
import { getEmDashEntry } from "emdash";

const { entry: post } = await getEmDashEntry("posts", Astro.params.slug);
---

{post?.data.featured_image && (
  <Image
    image={post.data.featured_image}
    width={800}
    height={450}
    priority
  />
)}

priority es para la imagen principal above-the-fold. Establece loading="eager" y fetchpriority="high": loading controla si la carga se difiere, y fetchpriority da al navegador una pista de prioridad para la solicitud.

Cuando el valor del campo lleva una contraparte oscura, Image renderiza ambas y muestra la que coincide con el esquema de color del visitante. Modo oscuro cubre la habilitación del slot en un campo y la convención de clase <html> en la que se basa el componente.

EmDash instala un endpoint de imagen que produce las variantes redimensionadas bajo demanda. En Cloudflare Workers ese endpoint usa el binding IMAGES. Transformación de imágenes cubre de dónde viene el binding y qué sucede cuando está ausente.

Eliminar medios

  1. Selecciona el/los archivo(s) que deseas eliminar

  2. Haz clic en Eliminar

  3. Confirma la eliminación

API de medios

Usa la API REST para subir, listar, actualizar, eliminar y organizar medios locales. La referencia de endpoints de medios documenta la subida directa multipart y los flujos de destino de subida, parámetros de solicitud, formas de respuesta, permisos y operaciones de carpetas.

Proveedores de medios

Además del almacenamiento local, EmDash soporta proveedores de medios externos para alojamiento especializado de imágenes y video. Los proveedores de medios aparecen como pestañas en el selector de medios, permitiendo a los editores elegir de múltiples fuentes.

Proveedores disponibles

Cloudflare Images

Cloudflare Images proporciona alojamiento de imágenes con optimización automática, redimensionamiento y conversión de formato.

import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { cloudflareImages } from "@emdash-cms/cloudflare";

export default defineConfig({
  integrations: [
    emdash({
      // ... configuración de base de datos, almacenamiento
      mediaProviders: [
        cloudflareImages({
          accountId: import.meta.env.CF_ACCOUNT_ID,
          apiToken: import.meta.env.CF_IMAGES_TOKEN,
          // Opcional: dominio de entrega personalizado
          deliveryDomain: "images.example.com",
        }),
      ],
    }),
  ],
});

Características:

  • Navegar y subir imágenes directamente desde el admin
  • Optimización automática de imágenes y conversión de formato
  • Transformaciones basadas en URL (redimensionar, recortar, formato)
  • Variantes flexibles para imágenes responsivas

Cloudflare Stream

Cloudflare Stream proporciona alojamiento de video con streaming adaptativo HLS/DASH.

import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { cloudflareStream } from "@emdash-cms/cloudflare";

export default defineConfig({
  integrations: [
    emdash({
      // ... configuración de base de datos, almacenamiento
      mediaProviders: [
        cloudflareStream({
          accountId: import.meta.env.CF_ACCOUNT_ID,
          apiToken: import.meta.env.CF_STREAM_TOKEN,
          // Opcional: configuración del reproductor
          controls: true,
          autoplay: false,
          loop: false,
        }),
      ],
    }),
  ],
});

Características:

  • Navegar, buscar y subir videos desde el admin
  • Streaming adaptativo HLS y DASH
  • Generación automática de miniaturas
  • Subida directa para archivos grandes

Usar múltiples proveedores

Puedes configurar múltiples proveedores. Cada uno aparece como una pestaña en el selector de medios:

import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { cloudflareImages, cloudflareStream } from "@emdash-cms/cloudflare";

export default defineConfig({
  integrations: [
    emdash({
      database: d1({ binding: "DB" }),
      storage: r2({ binding: "MEDIA" }),
      mediaProviders: [
        cloudflareImages({
          accountId: import.meta.env.CF_ACCOUNT_ID,
          apiToken: import.meta.env.CF_IMAGES_TOKEN,
        }),
        cloudflareStream({
          accountId: import.meta.env.CF_ACCOUNT_ID,
          apiToken: import.meta.env.CF_STREAM_TOKEN,
        }),
      ],
    }),
  ],
});

La biblioteca de medios local (pestaña “Biblioteca”) siempre está disponible junto con cualquier proveedor configurado.

Renderizar medios de proveedores

Usa el componente Image para renderizar medios:

---
import { Image } from "emdash/ui";
import { getEmDashEntry } from "emdash";

const { entry: post } = await getEmDashEntry("posts", Astro.params.slug);
---

{post?.data.featured_image && (
  <Image
    image={post.data.featured_image}
    width={800}
    height={450}
  />
)}

El componente automáticamente:

  • Detecta el proveedor del valor almacenado
  • Renderiza un elemento <img> optimizado
  • Aplica optimizaciones específicas del proveedor (ej: transformaciones de Cloudflare Images)

Valores de archivo y metadatos actuales

Un campo de archivo almacena una referencia y una instantánea de metadatos. Los campos en caché como url, filename, mimeType y size son opcionales porque los valores persistidos pueden omitirlos:

interface FileValue {
  id: string;
  url?: string;        // URL en caché legacy
  src?: string;        // URL directa de un proveedor externo
  filename?: string;  // Nombre de archivo original en caché
  mimeType?: string;  // Tipo MIME en caché
  size?: number;       // Tamaño en caché, cuando está disponible
  provider?: string;   // Por defecto "local"
  meta?: Record<string, unknown>;
}

getEmDashEntry() y getEmDashCollection() devuelven este valor almacenado sin una consulta de medios adicional. Para metadatos actuales, usa el método get() del proveedor configurado explícitamente. Usa getEmbed() para la URL de renderizado específica del proveedor:

---
const file = post.data.attachment;
const provider = file
  ? Astro.locals.emdash?.getMediaProvider(file.provider ?? "local")
  : undefined;
const current = file ? await provider?.get?.(file.id) : null;
const embed = file && provider ? await provider.getEmbed(file) : null;
---

Los clientes HTTP autenticados pueden hacer la misma consulta explícita a través de GET /_emdash/api/media/:id para medios locales o GET /_emdash/api/media/providers/:providerId/:itemId para otro proveedor.

Para una URL de archivo local, usa el meta.storageKey almacenado con el helper de URL pública. Esto respeta un dominio público R2 o S3 configurado sin consultar la tabla de medios:

---
const storageKey =
  typeof file?.meta?.storageKey === "string" ? file.meta.storageKey : undefined;
const url = storageKey
  ? Astro.locals.emdash?.getPublicMediaUrl?.(storageKey)
  : file?.src ?? file?.url;
---

Las consultas de proveedores pueden realizar trabajo de red o base de datos. Evita una consulta por archivo en páginas de colección sin sesión; usa la instantánea almacenada y componentes de renderizado a menos que la solicitud necesite metadatos frescos.

Tipo MediaValue

Los campos de medios almacenan un objeto MediaValue que contiene información del proveedor:

interface MediaValue {
  provider?: string;    // ID del proveedor, por defecto "local"
  id: string;           // ID específica del proveedor
  src?: string;         // URL directa (para medios locales o valores de cadena simple)
  previewUrl?: string;  // URL de vista previa para visualización admin (proveedores externos)
  filename?: string;    // Nombre de archivo original
  mimeType?: string;    // Tipo MIME
  width?: number;       // Ancho de imagen/video
  height?: number;      // Alto de imagen/video
  focalX?: number;      // Posición focal horizontal de 0 a 1
  focalY?: number;      // Posición focal vertical de 0 a 1
  alt?: string;         // Texto alternativo
  meta?: Record<string, unknown>; // Metadatos específicos del proveedor
}

Esto permite a EmDash renderizar medios correctamente independientemente de dónde estén alojados.

Próximos pasos