Storage Setup
Configure object storage for uploads, direct browser PUTs, and CORS for Cloudflare R2 or AWS S3.
Why Storage Setup Matters
Crikket uploads bug report artifacts directly from the browser to object storage.
That includes:
- screenshots
- video recordings
- raw debugger payload artifacts
This keeps Crikket API requests small, but it means your storage bucket must be configured correctly for browser uploads.
If storage CORS is missing or wrong, bug report uploads fail before finalize completes.
Required Server Environment Variables
Set these in apps/server/.env:
STORAGE_BUCKET
STORAGE_ACCESS_KEY_ID
STORAGE_SECRET_ACCESS_KEY
STORAGE_REGION
STORAGE_ENDPOINT
STORAGE_PUBLIC_URLRules:
STORAGE_BUCKETis always required.STORAGE_ACCESS_KEY_IDandSTORAGE_SECRET_ACCESS_KEYare always required.STORAGE_REGIONis required for standard AWS S3.STORAGE_ENDPOINTis recommended for R2 and custom S3-compatible providers.STORAGE_PUBLIC_URLis optional.
Use one of these patterns:
AWS S3
STORAGE_BUCKET=crikket-production
STORAGE_ACCESS_KEY_ID=your-access-key-id
STORAGE_SECRET_ACCESS_KEY=your-secret-access-key
STORAGE_REGION=us-east-1Cloudflare R2
STORAGE_BUCKET=crikket-production
STORAGE_ACCESS_KEY_ID=your-r2-access-key-id
STORAGE_SECRET_ACCESS_KEY=your-r2-secret-access-key
STORAGE_REGION=auto
STORAGE_ENDPOINT=https://<account-id>.r2.cloudflarestorage.comOptional Public URL
If you serve files from a CDN or public bucket hostname and want stable public URLs instead of signed URLs:
STORAGE_PUBLIC_URL=https://cdn.example.com/bug-reportsBrowser Upload Model
Crikket uses this flow for bug report artifacts:
- Crikket API creates an upload session.
- The browser uploads capture and debugger artifacts directly to storage using presigned
PUTURLs. - Crikket API finalizes the report only after storage uploads succeed.
Because the browser talks directly to storage, CORS is mandatory.
CORS Requirements
Your storage bucket must allow browser requests from every frontend origin that can submit bug reports.
At minimum, allow:
PUTfor direct uploadsGETandHEADfor direct object access and previewsOrigin,Content-Type, and other request headers used by the browser
Recommended production policy:
- allow only your real frontend origins, not
* - include every app domain that can submit bug reports
- expose
ETag
If you are testing locally, include your local frontend origin too, for example:
http://localhost:3001
https://local.crikket.ioCloudflare R2 CORS
In Cloudflare Dashboard:
- Open
R2. - Select your bucket.
- Open
Settings. - Add a
CORS policy.
Recommended policy:
[
{
"AllowedOrigins": [
"https://app.example.com",
"https://admin.example.com",
"https://local.crikket.io"
],
"AllowedMethods": ["GET", "HEAD", "PUT"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]Notes:
PUTis the critical method for bug report uploads.GETandHEADare recommended for media access and preview behavior.DELETEis not required for browser uploads.
AWS S3 CORS
In AWS Console:
- Open
S3. - Select your bucket.
- Open
Permissions. - Edit
Cross-origin resource sharing (CORS).
Recommended policy:
[
{
"AllowedOrigins": [
"https://app.example.com",
"https://admin.example.com",
"https://local.crikket.io"
],
"AllowedMethods": ["GET", "HEAD", "PUT"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]Verify Storage Before Go-Live
Before shipping, verify all of these:
STORAGE_BUCKETpoints to the correct bucketSTORAGE_REGIONorSTORAGE_ENDPOINTmatches the provider- access key and secret key belong to that bucket/account
- bucket CORS includes every frontend origin that can submit reports
- screenshot upload works
- video upload works
- uploaded report media is readable after finalize
Common Failure Mode
If bug report upload fails with a message similar to:
- direct upload to storage failed
- upload failed before the server responded
the most common cause is missing or incorrect bucket CORS.
Check:
- bucket CORS policy
- frontend origin matches exactly
STORAGE_ENDPOINTpoints to the right provider endpoint- browser
PUTrequest response in DevTools