Cloudflare R2 CORS Configuration
Hyperscape serves game assets (3D models, textures, audio) from Cloudflare R2 atassets.hyperscape.club. Cross-origin asset loading requires proper CORS configuration.
Problem
Without CORS configuration, browsers block asset loading from R2 with errors like:Solution
Configure R2 bucket CORS to allow cross-origin requests from all Hyperscape domains.Automatic Configuration (CI/CD)
The.github/workflows/deploy-cloudflare.yml workflow automatically configures CORS during deployment:
Manual Configuration
If you need to configure CORS manually:Using Wrangler CLI
CORS Configuration File
Thescripts/r2-cors-config.json file contains:
| Field | Value | Description |
|---|---|---|
allowed.origins | ["*"] | Allow requests from any origin |
allowed.methods | ["GET", "HEAD"] | Allow GET and HEAD requests (read-only) |
allowed.headers | ["*"] | Allow all request headers |
exposed | ["ETag", "Content-Length", "Content-Type"] | Headers exposed to JavaScript |
maxAge | 3600 | Cache preflight responses for 1 hour |
Using Cloudflare Dashboard
- Log in to Cloudflare Dashboard
- Navigate to R2 → hyperscape-assets bucket
- Go to Settings → CORS Policy
- Add CORS rule:
- Allowed Origins:
* - Allowed Methods:
GET,HEAD - Allowed Headers:
* - Exposed Headers:
ETag,Content-Length,Content-Type - Max Age:
3600
- Allowed Origins:
- Click Save
Verification
Test CORS configuration:Allowed Domains
The CORS configuration allows requests from:hyperscape.gg(production frontend)*.hyperscape.gg(subdomains)hyperbet.win(betting frontend)*.hyperbet.win(subdomains)hyperscape.bet(alternative domain)*.hyperscape.bet(subdomains)localhost:*(local development)- Any other origin (wildcard
*)
Security Considerations
Why Wildcard Origin?
R2 assets are public read-only resources (3D models, textures, audio). There’s no security risk in allowing cross-origin access from any domain because:- No authentication required - Assets are publicly accessible
- Read-only access - Only GET/HEAD methods allowed (no PUT/POST/DELETE)
- No sensitive data - Assets are game content, not user data
Alternative: Restricted Origins
If you want to restrict origins to specific domains:- ✅ More restrictive (only listed domains can load assets)
- ❌ Requires updating config when adding new domains
- ❌ Breaks local development on non-standard ports
Troubleshooting
CORS Errors Persist After Configuration
Cause: Browser cached old CORS preflight responses Solution: Hard refresh (Ctrl+Shift+R) or clear browser cacheWrangler CORS Command Fails
Symptoms:wrangler r2 bucket cors set returns error
Common Issues:
-
Invalid JSON format:
-
Missing authentication:
-
Bucket doesn’t exist:
Assets Still Not Loading
Symptoms: 404 errors or CORS errors persist Checklist:-
Verify CORS is configured:
-
Check asset exists in R2:
-
Verify CDN URL is correct:
- Client
.env:PUBLIC_CDN_URL=https://assets.hyperscape.club - Server
.env:PUBLIC_CDN_URL=https://assets.hyperscape.club
- Client
-
Check R2 custom domain:
- R2 bucket → Settings → Custom Domains
- Verify
assets.hyperscape.clubis connected
Related Documentation
- Cloudflare Deployment - Full Cloudflare Pages deployment guide
- Vast.ai Deployment - GPU streaming deployment
- README.md - Quick start guide
Implementation Details
CORS Configuration Script
Thescripts/configure-r2-cors.sh script:
- Reads CORS config from
scripts/r2-cors-config.json - Uses Wrangler CLI to apply configuration
- Verifies configuration was applied successfully
scripts/configure-r2-cors.sh
CORS Config: scripts/r2-cors-config.json
Wrangler API Format
The correct Wrangler R2 CORS API format (as of February 2026):- Nested
allowed.origins/methods/headersstructure exposedarray (notExposeHeaders)maxAgeinteger (notMaxAgeSeconds)
055779a (February 26, 2026)