Betterflow uses two complementary storage layers that work independently of each other. Cloudflare R2 is a remote object store for assets that need to be served publicly — background images and videos recorded by the Chrome extension. Browser storage (IndexedDB and LocalStorage) handles all user-uploaded images, export history, export preferences, and canvas state, so the editor stays fully functional even without an R2 bucket configured.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/betterspacx/app/llms.txt
Use this file to discover all available pages before exploring further.
Cloudflare R2
R2 is Cloudflare’s S3-compatible object storage. Betterflow uses it for two specific workloads:- Hosting the built-in background image gallery assets served to the editor UI.
- Receiving Chrome extension video uploads via presigned URLs generated by the
/api/upload-urlroute.
Setup
Create a Cloudflare account and R2 bucket
Sign up at cloudflare.com if you don’t have an account. In the
Cloudflare dashboard navigate to R2 Object Storage → Create bucket. Give your bucket a
name (e.g.
betterflow-storage) and choose the storage region closest to your users.Note your Cloudflare Account ID — it appears in the right-hand sidebar on any dashboard
page and is required for the S3-compatible endpoint.Generate R2 API credentials
In the Cloudflare dashboard go to R2 → Manage API Tokens and create a new token with
Object Read & Write permissions scoped to your bucket. Copy both values immediately — the
secret is only shown once.
| Credential | Environment variable |
|---|---|
| Access Key ID | R2_ACCESS_KEY_ID |
| Secret Access Key | R2_SECRET_ACCESS_KEY |
| API Token | R2_API_TOKEN |
| Account ID | CLOUDFLARE_ACCOUNT_ID |
| Bucket name | R2_BUCKET_NAME |
Configure CORS on the R2 bucket
The browser needs to fetch assets cross-origin. In the Cloudflare dashboard open your bucket,
go to Settings → CORS Policy, and add a rule that allows
GET requests from your site’s
origin:Set the public URL environment variables
Betterflow’s After updating
next.config.ts reads NEXT_PUBLIC_R2_PUBLIC_URL and
NEXT_PUBLIC_R2_CUSTOM_DOMAIN to allowlist hostnames for Next.js Image Optimization. Set
both to the correct public endpoint for your bucket:.env, restart the development server (pnpm run dev) so the new values are
picked up by next.config.ts at startup.(Optional) Map a custom domain to your bucket
For cleaner public URLs and improved cache-hit ratios, map a custom subdomain to your R2
bucket. In the Cloudflare dashboard open your bucket → Settings → Custom Domains and add
a domain you control (e.g.
assets.yourdomain.com). Cloudflare automatically provisions a
TLS certificate.Update NEXT_PUBLIC_R2_CUSTOM_DOMAIN and NEXT_PUBLIC_CDN_URL to use the new domain and
redeploy.Browser Storage
Betterflow uses two browser-native storage mechanisms — IndexedDB for binary blobs and structured records, and LocalStorage for lightweight key/value state. Both require no configuration and work automatically across sessions.IndexedDB Stores
IndexedDB is used for all data that is too large or too structured for LocalStorage: uploaded image blobs, exported image files, and export preferences.| Store | Key | Contents |
|---|---|---|
image-blobs | Unique image ID | Uploaded image blob, MIME type, and timestamp. A blob URL is created from this record for immediate canvas rendering and persisted here so images survive page refreshes. |
exports | Unique export ID | Exported image blob together with format, quality, scale, timestamp, and file name metadata. |
export-preferences | 'preferences' | Last-used export settings: format (PNG / MP4 / WebM / GIF), quality preset, and output scale. Restored when the export panel opens. |
LocalStorage Keys
LocalStorage holds lightweight editor state that is fast to read synchronously on startup.| Key | Contents |
|---|---|
canvas-objects | Serialized canvas object state (image transforms, overlays, borders, shadows, 3D perspective settings). Restored automatically when the editor loads. |
canvas-background-prefs | Background preferences (gradient colors, solid color, background image selection, blur and noise settings). |
Browser storage is scoped to the origin, so data stored at
localhost:3000 is separate from
data at your production domain. Users who clear their browser storage or switch to a different
device will start with a blank canvas.