EmDash memorizza i media caricati (immagini, documenti, video) in un backend di archiviazione configurabile. Scegli in base alla tua piattaforma di distribuzione e ai requisiti.
Panoramica
| Archiviazione | Ideale Per | Funzionalità |
|---|---|---|
| R2 Binding | Cloudflare Workers | Zero configurazione, veloce |
| S3 | Qualsiasi piattaforma | Upload firmati, supporto CDN |
| Local | Sviluppo | Archiviazione file semplice |
Cloudflare R2 (Binding)
Usa i binding R2 quando distribuisci su Cloudflare Workers per l’integrazione più veloce.
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 da wrangler.jsonc |
publicUrl | string | URL pubblico opzionale per il bucket |
Installazione
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 di media pubblici, abilita l’accesso pubblico sul tuo bucket R2:
- Vai al Dashboard Cloudflare > R2 > il tuo bucket
- Abilita l’accesso pubblico nelle Impostazioni
- Aggiungi l’URL pubblico alla tua configurazione:
storage: r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev",
});
Archiviazione Compatibile S3
L’adattatore S3 funziona con Cloudflare R2 (tramite API S3), MinIO e altri servizi compatibili S3.
La seguente configurazione punta EmDash a un bucket compatibile 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 | Richiesto | 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 (predefinito: "auto") |
publicUrl | string | no | CDN opzionale o URL pubblico |
* Sia accessKeyId che secretAccessKey devono essere forniti insieme, oppure entrambi omessi.
Risoluzione della configurazione S3 dalle variabili d’ambiente
Qualsiasi campo omesso da s3({...}) viene letto dalla corrispondente variabile d’ambiente S3_* all’avvio del processo. Questo ti consente 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 | Predefinito: "auto" |
S3_PUBLIC_URL | publicUrl | Prefisso CDN opzionale |
Le variabili d’ambiente vengono lette da process.env all’avvio del processo. Questa è una funzionalità solo Node.
Chiamare s3() senza argomenti legge ogni campo dalle variabili d’ambiente S3_*:
import emdash, { s3 } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
// s3() senza argomenti: tutti i campi dalle variabili d'ambiente S3_*
storage: s3(),
// Oppure misto: sovrascrivi un campo, resto dall'ambiente
// storage: s3({ publicUrl: "https://cdn.example.com" }),
}),
],
});
R2 tramite API S3
Usa le credenziali S3 con R2 per funzionalità come URL di upload firmati:
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 le credenziali API R2 nel dashboard Cloudflare sotto R2 > Manage R2 API Tokens.
MinIO
Punta l’adattatore S3 a un endpoint MinIO con le sue credenziali di accesso:
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 memorizzati 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 per l’archiviazione dei file |
baseUrl | string | URL base per servire i file |
La baseUrl dovrebbe corrispondere all’endpoint dei file media di EmDash (/_emdash/api/media/file) a meno che non configuri un server di file statici personalizzato.
Configurazione Basata sull’Ambiente
Cambia i 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 firmati, consentendo ai client di caricare direttamente nell’archiviazione senza passare attraverso il tuo server. Questo migliora le prestazioni per file grandi.
Gli upload firmati sono automatici quando si usa l’adattatore S3. L’interfaccia admin li usa quando disponibili.
Adattatori che supportano upload firmati:
- S3 (incluso R2 tramite API S3)
Adattatori che non supportano upload firmati:
- R2 binding (usa invece l’adattatore S3 con credenziali R2)
- Local
Interfaccia Storage
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.