Web Game Deployment Issues - Complete Solution Guide

You built a web game (Unity WebGL, Godot HTML5, Phaser, or a static build) but deployment fails: the build does not run in the browser, assets return 404, or you see CORS or routing errors. This guide walks you through the most common web game deployment issues and how to fix them.

The Problem

Typical symptoms when deploying a web game:

  • Build fails during export (missing files, path errors, or tool-specific errors)
  • Blank or black screen in the browser after upload
  • 404 Not Found for .data, .wasm, .js, or other asset files
  • CORS errors in the console when loading resources
  • Game runs locally but not on the host (e.g. Netlify, Vercel, itch.io, GitHub Pages)
  • Infinite loading or "Downloading..." that never finishes
  • Wrong base path so the game looks for files at the wrong URL

These usually come from build output, server configuration, or how the host serves files.

Why This Happens

Wrong or missing base path:
Web builds often assume files are served from the site root (/). If you deploy to a subpath (e.g. yoursite.com/games/my-game/), the game still requests /Build/mygame.data instead of /games/my-game/Build/mygame.data, so the server returns 404.

Host does not serve the right MIME types or headers:
Some hosts do not set correct MIME types for .wasm, .data, or .mem. Browsers may block or mishandle them. Others block cross-origin or range requests that WebGL loaders need.

SPA / client-side routing overwrites game routes:
If the site uses a single-page app router, requests to /Build/... can be rewritten to index.html, so the game never gets its asset files.

Build output not uploaded or in wrong folder:
The deployed folder may be missing the Build/ or StreamingAssets/ folder, or you uploaded only index.html and not the rest of the output.

CORS:
If the game or assets are on a different origin (e.g. CDN, different subdomain) and the server does not send proper CORS headers, the browser blocks loading.

Solution 1: Fix Base Path / Subpath Deployment

If your game is not at the site root (e.g. you deploy to /game/ or /games/my-game/), the engine must know the base path.

Unity WebGL

  1. Open Player Settings (Edit → Project Settings → Player).
  2. Under WebGL → Publishing Settings, set Deployment WebGL Template to a template that supports base path, or use the default and set WebGL Template if needed.
  3. Set Compression Format (e.g. Gzip or Brotli) to match what your server supports.
  4. In a custom template or in the loader, set the base path before the engine starts. For the default template, you can pass it in the URL, e.g. ?basePath=/games/my-game/ and ensure your index uses it when resolving paths to Build/ and StreamingAssets/.

If using a custom index:

  • In the script that creates the Unity loader, set unityInstance or the config so that all asset URLs are prefixed with your base path (e.g. "/games/my-game/Build/").
  • Ensure every request (e.g. mygame.data, mygame.wasm, mygame.framework.js) uses that prefix.

Godot HTML5

  1. Export the game (Project → Export → HTML5).
  2. If you deploy to a subpath, open the exported index.html (and any loader JS).
  3. Set the export Custom HTML or edit the generated script so that the path to the .pck and .wasm is correct. For example, if the game is at https://site.com/game/, the script should load game.pck and engine from /game/ not from /.
  4. Re-export or edit the exported files so all asset paths use the correct base (e.g. base = "/game/").

Generic / Phaser or other

  • Set the base URL in your loader/config (e.g. baseURL or path) to the full subpath, e.g. https://yoursite.com/games/my-game/.
  • Ensure every asset request (images, audio, JSON) uses that base.

Verification: Open the game URL in the browser, open DevTools → Network. Reload and check that all requests (e.g. .data, .wasm, .pck, images) return 200 and point to the correct paths (no 404s).

Solution 2: Fix 404s for Build Output (Missing or Wrong Files)

The host must serve every file the game requests. If something is 404, the game will not run.

Step 1: Confirm Build Output Locally

  1. Build the game for WebGL/HTML5.
  2. Open the build output folder (e.g. Build/, WebGL/, or the folder containing index.html plus .wasm/.data/.pck).
  3. Note the exact structure (e.g. index.html, Build/mygame.data, Build/mygame.wasm, Build/mygame.loader.js, TemplateData/).

Step 2: Upload the Entire Output

  1. Upload the entire folder contents to the host, not just index.html.
  2. Preserve structure: if the game expects Build/mygame.data, the host must have Build/mygame.data at that path relative to the page URL.
  3. For static hosts (Netlify, Vercel, GitHub Pages, itch.io): upload or deploy the folder so that the document root (or the folder you set as root) contains both index.html and the Build/ (or equivalent) directory.

Step 3: Check Case and Extensions

  • File names are case-sensitive on most Linux hosts. MyGame.data and mygame.data are different; use the exact names the loader expects.
  • Do not rename .data, .wasm, .mem, .pck, etc. unless you change the loader to match.

Verification: Open the direct URL to an asset in the browser (e.g. https://yoursite.com/game/Build/mygame.data). You should get the file (or a download), not 404 or an HTML page.

Solution 3: Fix CORS and MIME Types

Browsers require correct CORS headers and often correct MIME types for .wasm and custom formats.

Netlify

Add a _headers file in the folder you deploy (or in public/):

/*
  Access-Control-Allow-Origin: *
  Cross-Origin-Embedder-Policy: require-corp
  Cross-Origin-Opener-Policy: same-origin

If you need to allow specific origins, replace * with your site origin. For .wasm and .data, Netlify usually serves them; if you see MIME type errors, add in netlify.toml:

[[headers]]
  for = "/*"
  [headers.values]
    Access-Control-Allow-Origin = "*"

Vercel

In the project root, add vercel.json:

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "Access-Control-Allow-Origin", "value": "*" },
        { "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" },
        { "key": "Cross-Origin-Opener-Policy", "value": "same-origin" }
      ]
    }
  ]
}

itch.io

Upload the full build in a zip; itch.io serves files with acceptable defaults for many WebGL games. If you use a custom domain or embed, ensure the embed page is served from the same origin or that CORS is set on the asset host.

GitHub Pages

GitHub Pages does not let you set custom headers easily. If you hit CORS or COOP/COEP issues, use a different host that supports custom headers (Netlify, Vercel) or serve the game from the same origin as the page.

Verification: In DevTools → Network, click a .wasm or .data request and check Response Headers for Access-Control-Allow-Origin and that the response is not blocked. Fix any "blocked by CORS" or "required cross-origin request" errors in the console.

Solution 4: Fix SPA Routing (Don’t Rewrite Game Paths)

If the site is a single-page app (e.g. React Router, Vue Router) and the game is under a route like /game/:

  • Option A: Deploy the game in a subdirectory that is served as static files, and ensure the server does not rewrite requests under that path to index.html. For example, /game/ should serve the game’s index.html and /game/Build/* should serve files from the Build folder.
  • Option B: Add an exception in the SPA config so that paths starting with /game/Build/ or your asset path are not handled by the router and are instead requested from the server.

Netlify: Add a _redirects file (or in netlify.toml) so that /game/Build/* and /game/* are not rewritten to index. Often the default is "everything to index"; you need a rule that serves real files first.

Vercel: In vercel.json, use rewrites carefully so that /game/Build/* and similar asset paths are not rewritten to the SPA.

Verification: Request https://yoursite.com/game/Build/mygame.data in the browser. You should get the binary/file content, not the HTML of your main app.

Solution 5: Unity WebGL – Infinite Loading or "Downloading..."

If the Unity WebGL loader stays on "Downloading..." or a progress bar that never finishes:

  1. Check the browser console for 404, CORS, or failed network requests. Fix those first using the steps above.
  2. Enable compression the server supports: In Unity WebGL Player Settings, set compression to Gzip or Brotli. Then configure the server to serve .data/.wasm as gzip or brotli (many static hosts do this automatically for matching extensions).
  3. Memory: Very large WebGL builds can run out of memory in the browser. Reduce build size (strip unused code, compress assets) or suggest users run in a 64-bit browser with enough RAM.
  4. Base path: Confirm the loader’s base path matches the deployed URL (see Solution 1).

Verification: In Network tab, all Build/* requests should complete with 200. Progress callbacks in the loader should advance; if they never fire, the requests are likely failing (404/CORS) or the paths are wrong.

Prevention Tips

  • Test deployment locally: Serve the build folder with a simple HTTP server (e.g. npx serve build or python -m http.server) and test from another port or device to catch path and CORS issues.
  • Use a consistent base path in development: If the game will be at /game/, build and test with that base path from the start.
  • Document your host: Note which host you use and any config (base path, headers, redirects) so you can repeat or fix deployment later.
  • Keep build output intact: Do not delete or rename Build/ or asset folders; deploy the same structure the engine expects.

Related Problems and Links

Official docs:

Bookmark this guide and double-check base path, 404s, and CORS whenever you change host or subpath. Most web game deployment failures come from one of these three.