A reliable path from R2 bucket to asset preview.
Connect a workspace to Cloudflare R2, deliver files through the right URL, and reuse assets from media fields without exposing storage credentials.
Two URLs, two jobs
Jade keeps object storage credentials and browser delivery separate. This is the most important part of the setup.
Private endpoint
endpoint_url is the S3-compatible endpoint used by the backend for signed uploads and deletes. For a default R2 bucket it is https://<ACCOUNT_ID>.r2.cloudflarestorage.com.Public delivery URL
asset_base_url is the browser-facing base URL returned with assets and used by previews. Use an R2 custom domain in production, not the S3 endpoint.Credentials stay server-side
Set up Cloudflare R2
Create a bucket, create a scoped token, then choose the correct public delivery option.
Create a bucket
Create an R2 bucket in the Cloudflare dashboard or with Wrangler. Buckets are private by default.
Wrangler
npx wrangler login
npx wrangler r2 bucket create jade-assets-productionCreate an Object Read & Write token
In R2 → Overview → Account Details → API Tokens, create an account or user token with Object Read & Write permission scoped to this bucket. Copy the access key ID and secret access key when they are shown.
Choose public delivery
Connect a custom domain under the bucket Settings → Custom Domains for production. Enable Public Development URL only when testing with the rate-limited managed r2.dev URL.
Do not use r2.dev for production traffic
r2.dev endpoint is rate-limited and does not provide the production controls available behind a custom domain, including WAF rules, Cloudflare Access, Bot Management, and custom caching. Do not create a CNAME pointing at an r2.devhostname.Configure Jade
Workspace owners and admins enter the storage connection once; all projects in the workspace can then use the asset library.
Settings → Storage
Storage provider: Cloudflare R2
Bucket name: jade-assets-production
Endpoint URL: https://<ACCOUNT_ID>.r2.cloudflarestorage.com
Public asset base URL: https://cdn.example.com
Region: auto
Cloudflare account ID: <ACCOUNT_ID>
Access key ID: <R2_ACCESS_KEY_ID>
Secret access key: <R2_SECRET_ACCESS_KEY>Use the right values
Region should be auto for a default R2 bucket. If the bucket uses a jurisdiction, use its jurisdiction- specific S3 endpoint. Set the Public asset base URL to the active custom domain or temporary r2.dev URL without confusing it with the private endpoint.Use the asset library
The asset page and document editor use the same project-scoped library.
Dedicated page
/app/assets to upload, search, preview, open, copy the public link, or delete files. Image previews use contained rendering and can be opened in a larger modal.Media fields
Authenticated asset routes
GET /api/projects/{projectId}/assets?search=hero
POST /api/projects/{projectId}/assets?filename=hero.png
DELETE /api/assets/{assetId}API-key management routes
GET /api/management/v1/projects/{projectId}/assets?search=hero
POST /api/management/v1/projects/{projectId}/assets?filename=hero.png
DELETE /api/management/v1/assets/{assetId}Role requirements
assets:reador assets:write API-key scopes.Production checklist
Use separate environments and rotate credentials when they are exposed.
Current limitations
