EmDash archivia i media caricati (immagini, documenti, video) in un backend di archiviazione configurabile. Scegli in base alla tua piattaforma di deploy e ai tuoi requisiti.
Panoramica
| Archiviazione | Ideale per | Caratteristiche |
|---|---|---|
| R2 Binding | Cloudflare Workers | Zero configurazione, veloce |
| S3 | Qualsiasi piattaforma | Upload firmati, supporto CDN |
| Locale | Sviluppo | Archiviazione su filesystem semplice |
Cloudflare R2 (Binding)
Usa i binding R2 per l’integrazione più rapida durante il deploy su Cloudflare Workers.
import emdash from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
storage: r2({ binding: "MEDIA" }),
}),
],
});
Configurazione
| Opzione | Tipo | Descrizione |
|---|---|---|
binding | string | Nome del binding R2 in wrangler.jsonc |
publicUrl | string | URL pubblica del bucket (opzionale) |
Setup
Aggiungi il binding R2 alla tua configurazione Wrangler:
wrangler.jsonc
{
"r2_buckets": [
{
"binding": "MEDIA",
"bucket_name": "emdash-media"
}
]
} wrangler.toml
[[r2_buckets]]
binding = "MEDIA"
bucket_name = "emdash-media" Accesso pubblico
Per URL media pubbliche, abilita l’accesso pubblico sul tuo bucket R2:
- Dashboard Cloudflare > R2 > il tuo bucket
- Abilita l’accesso pubblico nelle Impostazioni
- Aggiungi l’URL pubblica alla configurazione:
storage: r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev",
});
Archiviazione compatibile S3
L’adattatore S3 funziona con Cloudflare R2 (via API S3), MinIO e altri servizi compatibili con S3.
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", // Optional, defaults to "auto"
publicUrl: process.env.S3_PUBLIC_URL, // Optional CDN URL
}),
}),
],
});
Configurazione
| Opzione | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
endpoint | string | sì | URL dell’endpoint S3 |
bucket | string | sì | Nome del bucket |
accessKeyId | string | no* | Chiave di accesso |
secretAccessKey | string | no* | Chiave segreta |
region | string | no | Regione (default: "auto") |
publicUrl | string | no | URL CDN o pubblica (opzionale) |
* accessKeyId e secretAccessKey devono essere forniti insieme, oppure entrambi omessi.
Risoluzione della configurazione S3 dalle variabili d’ambiente
Qualsiasi campo omesso in s3({...}) viene letto dalla variabile d’ambiente S3_*
corrispondente all’avvio del processo. Questo ti permette di costruire un’immagine container
una volta e iniettare le credenziali all’avvio senza ricostruire. I valori espliciti in
s3({...}) hanno sempre la precedenza sulle variabili d’ambiente.
| Variabile d’ambiente | Campo | Note |
|---|---|---|
S3_ENDPOINT | endpoint | Deve essere un URL http/https valido |
S3_BUCKET | bucket | |
S3_ACCESS_KEY_ID | accessKeyId | |
S3_SECRET_ACCESS_KEY | secretAccessKey | |
S3_REGION | region | Default "auto" |
S3_PUBLIC_URL | publicUrl | Prefisso CDN opzionale |
Le variabili d’ambiente vengono lette da process.env all’avvio del processo. Questa è una funzionalità esclusiva di Node.
import emdash, { s3 } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
// s3() with no args: all fields from S3_* environment variables
storage: s3(),
// Or mix: override one field, rest from environment
// storage: s3({ publicUrl: "https://cdn.example.com" }),
}),
],
});
R2 via API S3
Usa credenziali S3 con R2 per funzionalità come URL di upload firmate:
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 credenziali API R2 nella dashboard Cloudflare sotto R2 > Manage R2 API Tokens.
MinIO
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",
});
Filesystem locale
Usa l’archiviazione locale per lo sviluppo. I file vengono salvati in una directory su disco.
import emdash, { local } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
}),
],
});
Configurazione
| Opzione | Tipo | Descrizione |
|---|---|---|
directory | string | Percorso della directory di archiviazione |
baseUrl | string | URL base per servire i file |
Il baseUrl deve corrispondere all’endpoint dei file media di EmDash (/_emdash/api/media/file) a meno che non si configuri un server di file statici personalizzato.
Configurazione basata sull’ambiente
Cambia backend di archiviazione in base all’ambiente:
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 })],
});
Upload firmati
L’adattatore S3 supporta URL di upload firmate, consentendo ai client di caricare direttamente nell’archiviazione senza passare dal tuo server. Questo migliora le prestazioni per file di grandi dimensioni.
Gli upload firmati sono automatici quando si usa l’adattatore S3. L’interfaccia di amministrazione li usa quando disponibili.
Adattatori che supportano gli upload firmati:
- S3 (incluso R2 via API S3)
Adattatori che non supportano gli upload firmati:
- R2 binding (usa invece l’adattatore S3 con credenziali R2)
- Locale
Interfaccia di archiviazione
Tutti gli adattatori di archiviazione implementano la stessa interfaccia:
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;
}
Questa coerenza consente di cambiare backend di archiviazione senza modificare il codice dell’applicazione.