Biblioteca multimedia

En esta página

EmDash incluye una biblioteca multimedia para gestionar imágenes, documentos y otros archivos. Esta guía cubre la subida, la organización y el uso de medios en tu contenido.

Acceder a la biblioteca multimedia

Abre la biblioteca desde la barra lateral del panel haciendo clic en Media. Verás todos los archivos subidos con vista previa, nombres y fechas de subida.

Biblioteca multimedia de EmDash con cuadrícula de imágenes y botón de subida

Subir archivos

Desde la biblioteca multimedia

  1. Haz clic en Media en la barra lateral del panel

  2. Haz clic en Upload o arrastra archivos a la zona de subida

  3. Selecciona uno o más archivos en tu equipo

  4. Espera a que terminen las subidas

Desde el editor de contenido

  1. En el editor de texto enriquecido, haz clic en el botón de imagen

  2. Haz clic en Upload en el selector de medios

  3. Selecciona un archivo en tu equipo

  4. Añade texto alternativo y haz clic en Insert

Tipos de archivo admitidos

EmDash admite tipos de archivo web habituales:

CategoríaExtensiones
Imágenes.jpg, .jpeg, .png, .gif, .webp, .avif, .svg
Documentos.pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx
Vídeo.mp4, .webm, .mov
Audio.mp3, .wav, .ogg

Backends de almacenamiento

EmDash admite varios backends de almacenamiento. Configúralo en tu Astro config:

Local Storage

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 guardan en el directorio ./uploads. Adecuado para desarrollo y despliegues con un solo servidor.

Cloudflare R2

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

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",
		},
	],
}

S3-Compatible

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 (mediante API S3), MinIO y otros servicios compatibles con S3.

Cómo funcionan las subidas

EmDash usa URL firmadas para subidas seguras:

  1. El cliente solicita una URL de subida a la API

  2. El servidor genera una URL firmada con caducidad

  3. El cliente sube directamente al almacenamiento usando esa URL

  4. El servidor registra los metadatos del archivo en la base de datos

Así los archivos grandes no pasan por tu servidor de aplicación y puedes subir directamente al almacenamiento en la nube.

Organizar medios

Carpetas

Crea carpetas para organizar tus medios:

  1. Haz clic en New Folder en la biblioteca multimedia

  2. Introduce un nombre de carpeta

  3. Haz clic en Create

  4. Arrastra archivos a las carpetas para organizarlos

Búsqueda

Usa el cuadro de búsqueda para encontrar archivos por nombre. Coincide con partes del nombre de archivo.

Filtros

Filtra medios por:

  • Type — Imágenes, documentos, vídeo, audio
  • Date — Rango de fechas de subida
  • Folder — Carpeta concreta

Usar medios en el contenido

En el editor de texto enriquecido

  1. Coloca el cursor donde quieras la imagen

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

  3. Selecciona una imagen de la biblioteca o sube una nueva

  4. Introduce texto alternativo

  5. Haz clic en Insert

Como imagen destacada

  1. Abre una entrada de contenido en el editor

  2. Localiza el campo Featured Image en la barra lateral

  3. Haz clic en Select Image

  4. Elige en la biblioteca multimedia o sube un archivo

  5. Haz clic en Save

En campos personalizados

Para campos configurados como imagen o archivo, haz clic en el campo para abrir el selector de medios.

Mostrar medios en plantillas

Accede a las URL de los medios desde los datos del 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 adaptables

Para imágenes adaptables, usa el componente Image de Astro con URL externas:

Imágenes adaptables

Para imágenes adaptables, usa el componente Image de Astro con URL externas:

---
import { Image } from "astro:assets";
import { getEmDashEntry } from "emdash";

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

{post?.data.featured_image && (
  <Image
    src={post.data.featured_image}
    alt={post.data.featured_image_alt ?? ""}
    width={800}
    height={450}
  />
)}

Eliminar medios

  1. Selecciona el archivo o archivos que quieras eliminar

  2. Haz clic en Delete

  3. Confirma la eliminación

API de medios

Accede a los medios por programación con la API de administración.

Subir un archivo

Sube medios como datos multipart:

POST /_emdash/api/media
Content-Type: multipart/form-data
Authorization: Bearer YOUR_API_TOKEN

file=<binary file data>

Respuesta:

{
	"success": true,
	"data": {
		"item": {
			"id": "01ABC123",
			"filename": "hero-image.jpg",
			"mime_type": "image/jpeg",
			"storage_key": "media/abc123/hero-image.jpg",
			"width": 1200,
			"height": 800
		}
	}
}

Listar medios

GET /_emdash/api/media?prefix=images/&limit=20
Authorization: Bearer YOUR_API_TOKEN

Eliminar medios

DELETE /_emdash/api/media/images/hero.jpg
Authorization: Bearer YOUR_API_TOKEN

Proveedores de medios

Además del almacenamiento local, EmDash admite proveedores externos para alojamiento especializado de imagen y vídeo. Aparecen como pestañas en el selector de medios para elegir entre varias fuentes.

Proveedores disponibles

Cloudflare Images

Cloudflare Images ofrece alojamiento de imágenes con optimización, redimensionado y conversión de formato automáticos.

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

export default defineConfig({
  integrations: [
    emdash({
      // ... database, storage config
      mediaProviders: [
        cloudflareImages({
          accountId: import.meta.env.CF_ACCOUNT_ID,
          apiToken: import.meta.env.CF_IMAGES_TOKEN,
          // Optional: custom delivery domain
          deliveryDomain: "images.example.com",
        }),
      ],
    }),
  ],
});

Características:

  • Explorar y subir imágenes desde el panel
  • Optimización y conversión de formato automáticas
  • Transformaciones por URL (redimensionar, recortar, formato)
  • Variantes flexibles para imágenes adaptables

Cloudflare Stream

Cloudflare Stream ofrece alojamiento de vídeo con streaming adaptable HLS/DASH.

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

export default defineConfig({
  integrations: [
    emdash({
      // ... database, storage config
      mediaProviders: [
        cloudflareStream({
          accountId: import.meta.env.CF_ACCOUNT_ID,
          apiToken: import.meta.env.CF_STREAM_TOKEN,
          // Optional: player settings
          controls: true,
          autoplay: false,
          loop: false,
        }),
      ],
    }),
  ],
});

Características:

  • Explorar, buscar y subir vídeos desde el panel
  • Streaming adaptable HLS y DASH
  • Generación automática de miniaturas
  • Subida directa para archivos grandes

Usar varios proveedores

Puedes configurar varios proveedores. Cada uno aparece como 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 multimedia local (pestaña «Library») sigue disponible junto a cualquier proveedor configurado.

Renderizar medios del proveedor

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 a partir del valor almacenado
  • Renderiza un elemento <img> optimizado
  • Aplica optimizaciones específicas del proveedor (p. ej. transformaciones de Cloudflare Images)

Tipo MediaValue

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

interface MediaValue {
  provider?: string;    // Provider ID, defaults to "local"
  id: string;           // Provider-specific ID
  src?: string;         // Direct URL (for local media or legacy data)
  previewUrl?: string;  // Preview URL for admin display (external providers)
  filename?: string;    // Original filename
  mimeType?: string;    // MIME type
  width?: number;       // Image/video width
  height?: number;      // Image/video height
  alt?: string;         // Alt text
  meta?: Record<string, unknown>; // Provider-specific metadata
}

Así EmDash puede renderizar los medios correctamente independientemente de dónde estén alojados.

Siguientes pasos