Publishing & Deployment Issues May 27, 2026

Construct 3 HTML5 WASM Fetch Blocked by CORS on Custom itch.io Domain - How to Fix

Fix Construct 3 HTML5 wasm and worker fetch blocked by CORS on itch.io custom domains. DevTools proof, subdomain smoke, cors_smoke_receipt_v1.json, split-hosting defer, and comparison to MIME and NW.js lanes.

By GamineAI Team

Construct 3 HTML5 WASM Fetch Blocked by CORS on Custom itch.io Domain - How to Fix

Problem: Your Construct 3 HTML5 export loads on yourgame.itch.io but shows a blank canvas on your custom itch domain (play.yourstudio.com). Browser DevTools reports CORS failures fetching data.wasm, worker scripts, or other runtime assets. Local preview and the itch subdomain URL work.

Who is affected now: July–October 2026 HTML5-first teams enable itch custom domains for fest press kits while running GX.games + Steam parallel lanes (triple-channel BUILD_RECEIPT help). This is origin / hosting topology, not post-upload WASM MIME (application/octet-stream on CDN) and not Construct NW.js Steam save paths (desktop export).

Fastest safe fix: Prove green on *`.itch.iosubdomain** first → file **cors_smoke_receipt_v1.json** withsubdomain_smoke_ok: true` → either keep gameplay on subdomain (marketing custom domain links there) or advance to custom domain CORP/COEP preflight only with a documented header plan.

Direct answer

itch custom domains change the page origin players see. Construct’s HTML5 runtime fetches wasm and workers from URLs that may be treated as cross-origin unless assets and headers align. yourgame.itch.io uses itch’s game hosting model; arbitrary CNAME branded domains often break same-origin assumptions. Fix the hosting decision, not another Construct re-export loop.

Why this issue spikes in July–October 2026

  1. Custom domain press kits — Marketing shares play.brand.com before engineering runs subdomain smoke.
  2. Construct HTML5 fest velocity — Teams ship browser demos before NW.js Steam builds.
  3. MIME vs CORS confusion — Teams pass curl WASM MIME on subdomain then fail on custom domain with CORS only.
  4. Multi-channel receipts — Wrong itch URL invalidates channel_label_match support tickets.
  5. October async playtest volume — Facilitators distribute mixed subdomain + custom links in one Discord thread.

Symptoms and search phrases

  • Console: Access to fetch at '.../data.wasm' from origin 'https://play.brand.com' has been blocked by CORS policy.
  • Network tab: wasm or worker requests red with CORS failure (not 404).
  • Same zip: works on studio.itch.io/demo, fails on custom domain.
  • Local preview works (different origin rules).
  • After enabling custom domain in itch settings only—no Construct project change.
  • COEP / CORP errors appear when experimenting with cross-origin isolation on custom host.

Root causes (check in order)

  1. Custom domain originwasm asset origin (split hosting).
  2. Marketing CNAME live before subdomain proof completed.
  3. Worker script loaded from a host without Access-Control-Allow-Origin for page origin.
  4. Wrong itch upload slot tested (old embed path).
  5. MIME fixed but origin notapplication/wasm on CDN does not fix cross-origin fetch.
  6. Third-party iframe wrapping itch runner with extra origin layer.
  7. Construct export pointed at absolute URLs hard-coded to subdomain while page served on custom domain.

Beginner path (first 30 minutes)

Prerequisites: Published Construct HTML5 build on itch, browser DevTools, optional curl.

  1. Open https://yourgame.itch.io/your-demo → confirm game runs.
  2. Open custom domain URL → F12 → Console → note CORS error URL.
  3. Compare origins in error (page origin vs blocked asset URL).
  4. If subdomain fails too → fix itch CDN MIME or export layout first.
  5. If subdomain passes → run subdomain smoke preflight (S1–S6).
  6. Decide: defer custom domain for fest week or plan CORP/COEP chapter.

Common mistake: Re-uploading the Construct zip five times without changing which URL you share.

Fastest safe fix path

Step 1 — Subdomain proof (required gate)

Follow Construct 3 itch subdomain WASM and CORS smoke (guide):

Gate Pass
S1 — Game loads on *.itch.io Canvas interactive
S2 — DevTools no CORS on wasm/worker Console clean
S3 — curl -I wasm MIME application/wasm where applicable
S4 — cors_smoke_receipt_v1.json subdomain_smoke_ok: true

Policy: Do not debug custom domain until S4 is green.

Evening tutorial: Your First Construct 3 itch Subdomain WASM Smoke.

Step 2 — Origin map (write before changing DNS)

Create cors_origin_map_v1.json in release-evidence/html5/:

{
  "schema": "cors_origin_map_v1",
  "page_origin_subdomain": "https://yourgame.itch.io",
  "page_origin_custom": "https://play.yourstudio.com",
  "wasm_url_observed": "https://...",
  "worker_url_observed": "https://...",
  "same_origin_on_subdomain": true,
  "same_origin_on_custom": false,
  "hosting_decision": "defer_custom_use_subdomain_for_fest"
}

Strategy playbook: Construct custom domain CORS vs subdomain hosting.

Step 3 — Fest-week defer (recommended for most indies)

Action Why
Press kit links to yourgame.itch.io/demo Proven origin
Custom domain → marketing landing only No wasm on custom origin
File hosting_decision: defer_custom on receipt Diligence traceability

Course milestone: Lesson 208 — CORS hosting decision receipt.

Step 4 — Custom domain header path (advanced only)

If you must serve gameplay on custom domain:

  1. Complete custom domain worker CORP/COEP preflight.
  2. Document three-origin map (page, wasm, worker).
  3. Verify COOP/COEP requirements for Construct features you use.
  4. Pair with fest CORP/COEP worker smoke.

Honest limit: itch-hosted custom domains may not expose header knobs you need. If CORP/COEP cannot pass, defer custom—do not ship a broken branded URL.

Step 5 — Receipt cors_smoke_receipt_v1.json

{
  "schema": "cors_smoke_receipt_v1",
  "checked_at": "2026-05-27T18:00:00Z",
  "engine": "construct-3-html5",
  "subdomain_smoke_ok": true,
  "custom_domain_smoke_ok": false,
  "hosting_decision": "defer_custom_use_subdomain_for_fest",
  "build_label": "2026-05-27-fest-html5-03",
  "facilitator": "initials"
}

Wire optional BUILD_RECEIPT column html5_cors_smoke_ok when HTML5 is in scope for Wednesday smoke.

Working dev path — DevTools proof table

Check Where Pass
Page URL origin Address bar Note scheme + host
Failed request URL Network → wasm/worker Compare host to page
Access-Control-Allow-Origin Response headers (if visible) Matches page or *
Subdomain run *.itch.io No CORS errors
Custom run branded domain Document fail reason
Receipt cors_smoke_receipt_v1.json subdomain_smoke_ok: true

Godot comparison: Godot WASM memory ceiling — OOM vs CORS are different triage paths.

Verification checklist

  • [ ] Game runs on itch subdomain with clean console
  • [ ] CORS error URLs captured for custom domain attempt
  • [ ] cors_smoke_receipt_v1.json filed with explicit hosting_decision
  • [ ] Press / Discord links use proven subdomain URL for fest week
  • [ ] MIME proof on live wasm URL if loader hangs without CORS (itch MIME help)
  • [ ] build_label matches GX multi-channel receipts when dual-publishing
  • [ ] Facilitator README states approved hosting pattern

Prevention

  1. Run subdomain smoke preflight before enabling custom domain in itch.
  2. Add hosting decision row to 12-free itch WASM cross-check resource facilitator checklist.
  3. Never share custom domain in fest kit until custom_domain_smoke_ok: true or decision is defer_custom.
  4. Pair marketing with CORS vs subdomain playbook decision tree.
  5. Separate HTML5 itch from NW.js Steam save-path testing (Construct NW.js save help).

Troubleshooting

Symptom Fix
CORS on custom only Defer custom; use subdomain gameplay URL
CORS on subdomain too MIME / layout / 404 — not this article
404 on wasm, no CORS Zip root layout; re-upload
Works in editor, fails hosted Test hosted URL only
COEP/CORP errors on custom CORP/COEP chapter or defer custom
GX works, itch custom fails Independent channels—prove itch separately

FAQ

Can I fix CORS by re-exporting Construct?
Usually no if subdomain already works. Fix which URL you publish.

Does itch support custom domains for HTML5 wasm?
Custom domains are a marketing/hosting feature with origin constraints. Prove with receipts; defer if headers cannot pass.

Is this the same as Godot wasm MIME errors?
No—Godot MIME is Content-Type on fetch. Construct custom domain is cross-origin blocking.

Should playtests use custom domain links?
Use subdomain until custom_domain_smoke_ok: true is filed.

Related links

Prove subdomain first, document hosting_decision, then touch custom domains—CORS on branded itch URLs is a hosting choice, not a broken export.