Ir al contenido

Opciones de almacenamiento

EmDash almacena los archivos subidos, como imágenes, documentos y vídeos, en un backend de almacenamiento configurable. Elige la opción que mejor encaje con tu plataforma de despliegue y tus requisitos.

AlmacenamientoMejor paraCaracterísticas
Enlace R2Cloudflare WorkersIntegración rápida y casi sin configuración
S3Cualquier plataformaSubidas firmadas, soporte para CDN
LocalDesarrolloAlmacenamiento simple en el sistema de archivos

Usa enlaces R2 al desplegar en Cloudflare Workers para la integración más rápida.

astro.config.mjs
import emdash from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
storage: r2({ binding: "MEDIA" }),
}),
],
});
OpciónTipoDescripción
bindingstringNombre del enlace R2 desde wrangler.jsonc
publicUrlstringURL pública opcional para el bucket

Añade el enlace R2 a tu configuración de Wrangler:

{
"r2_buckets": [
{
"binding": "MEDIA",
"bucket_name": "emdash-media"
}
]
}

Para URLs públicas de medios, habilita el acceso público en tu bucket R2:

  1. Ve al Panel de Cloudflare > R2 > tu bucket
  2. Habilita el acceso público en Configuración
  3. Añade la URL pública a tu configuración:
storage: r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev",
});

El adaptador S3 funciona con Cloudflare R2 (a través de la API S3), MinIO y otros servicios compatibles con S3.

astro.config.mjs
import emdash, { s3 } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
storage: s3({
endpoint: process.env.S3_ENDPOINT,
bucket: process.env.S3_BUCKET,
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
region: "auto", // Opcional; por defecto es "auto"
publicUrl: process.env.S3_PUBLIC_URL, // URL pública o CDN opcional
}),
}),
],
});
OpciónTipoDescripción
endpointstringURL del endpoint S3
bucketstringNombre del bucket
accessKeyIdstringClave de acceso
secretAccessKeystringClave secreta
regionstringRegión (por defecto: "auto")
publicUrlstringURL pública o de CDN opcional

Usa credenciales S3 con R2 para funciones como URLs de subida firmadas:

storage: s3({
endpoint: "https://<account-id>.r2.cloudflarestorage.com",
bucket: "emdash-media",
accessKeyId: process.env.R2_ACCESS_KEY_ID,
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
publicUrl: "https://pub-xxxx.r2.dev",
});

Genera credenciales de la API R2 en el panel de Cloudflare en R2 > Gestionar Tokens de la API R2.

storage: s3({
endpoint: "https://minio.example.com",
bucket: "emdash-media",
accessKeyId: process.env.MINIO_ACCESS_KEY,
secretAccessKey: process.env.MINIO_SECRET_KEY,
publicUrl: "https://minio.example.com/emdash-media",
});

Usa almacenamiento local para desarrollo. Los archivos se almacenan en un directorio en disco.

astro.config.mjs
import emdash, { local } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
}),
],
});
OpciónTipoDescripción
directorystringRuta del directorio para almacenar archivos
baseUrlstringURL base para servir archivos

La baseUrl debe coincidir con el endpoint de archivos de medios de EmDash (/_emdash/api/media/file) a menos que configures un servidor de archivos estáticos personalizado.

Cambia los backends de almacenamiento según el entorno:

astro.config.mjs
import emdash, { s3, local } from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";
const storage = import.meta.env.PROD
? r2({ binding: "MEDIA" })
: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
});
export default defineConfig({
integrations: [emdash({ storage })],
});

El adaptador S3 admite URLs de subida firmadas, permitiendo que los clientes suban directamente al almacenamiento sin pasar por tu servidor. Esto mejora el rendimiento para archivos grandes.

Las subidas firmadas son automáticas al usar el adaptador S3. La interfaz de administración las usa cuando están disponibles.

Adaptadores que admiten subidas firmadas:

  • S3 (incluyendo R2 a través de la API S3)

Adaptadores que no admiten subidas firmadas:

  • Enlace R2 (usa el adaptador S3 con credenciales R2 en su lugar)
  • Local

Todos los adaptadores de almacenamiento implementan la misma interfaz:

interface Storage {
upload(options: {
key: string;
body: Buffer | Uint8Array | ReadableStream;
contentType: string;
}): Promise<UploadResult>;
download(key: string): Promise<DownloadResult>;
delete(key: string): Promise<void>;
exists(key: string): Promise<boolean>;
list(options?: ListOptions): Promise<ListResult>;
getSignedUploadUrl(options: SignedUploadOptions): Promise<SignedUploadUrl>;
getPublicUrl(key: string): string;
}

Esta interfaz uniforme permite cambiar de backend de almacenamiento sin tocar el código de la aplicación.