Custom file storage
Content & assetsCustom file storage
Keep uploads on your own infrastructure, no cloud secret ever reaches the browser.
- Private S3 connector,
{ mode: "private", listEndpoint }on your backend lists + presigns. - Upload handler,
onImageUpload(file)stores the file on your CDN and returns a URL. - Public bucket, a region/bucket config for a simple public store.
See also Amazon S3 and image uploads.
Private bucket: the endpoint contract
With { mode: "private", listEndpoint } the editor sends a GET to listEndpoint and shows what comes back. Return { items: [...] } or a bare array. Each item needs a url; key, name or label, thumbnailUrl, kind, alt and size are optional.
{ "items": [ { "key": "campaigns/hero.png", "url": "https://assets.example.com/campaigns/hero.png?X-Amz-Signature=…", "kind": "image" } ] }The request carries the user's cookies (credentials: "include") and any headers you set, so your backend can limit the list to the signed-in organization. On a non-2xx response the editor shows the message field of the JSON body as the error.
Presigned URLs expire
Presigned S3 URLs last at most 7 days. Re-resolve them at send time, or serve the objects from a public or CDN address (see asset domain), so an email sent later does not show broken images.
Upload handler
onImageUpload(file, { kind }) must resolve to { url, alt? }. Without it, uploads are stored in the design as base64 data: URLs, which make the email much larger and which many email clients strip. The File block will not upload at all without a handler.