Amazon S3

Content & assets

Amazon S3

Add an “Amazon S3” tab backed by your own bucket. Two modes: public (list in the browser) or private (your backend lists + presigns).

Public bucket#

tsx
<EmailEditor
  s3={{
    region: "us-east-1", bucket: "my-assets", prefix: "email/", // optional
    publicBaseUrl: "https://cdn.example.com" // optional (CloudFront)
  }}
/>

The browser lists the bucket via ListObjectsV2 and references each object's public URL. Objects must be public-read to render in a sent email. If listing needs credentials, you may pass accessKeyId/secretAccessKey, but…

Never put a broad AWS key in the browser, it's visible to end-users. If you must sign the list request, use a read-only, list-only IAM key scoped to that one bucket (s3:ListBucket + s3:GetObject). For anything sensitive, use private mode below.

Private bucket#

Your backend holds the AWS secret, lists the bucket, and returns presigned URLs. The connector just fetches your endpoint.

tsx
<EmailEditor
  s3={{
    mode: "private", listEndpoint: "https://app.example.com/api/s3-assets", headers: { Authorization: "Bearer …" }   // optional
  }}
/>

Backend contract#

Return JSON in this shape (or a bare array of items):

json
{
  "items": [
    { "key": "photos/a.png", "url": "https://…presigned…", "name": "a.png", "kind": "image" }
  ]
}

Only url is required per item; key, name, kind, thumbnailUrl, alt are optional (kind is inferred from the path when omitted).

Presigned URLs expire (max 7 days). For reliable email, re-resolve at send time or make the objects public.