Back to Blog
·Summer Team

How to Export a Godot Game to Web (HTML5 Guide, 2026)

A step-by-step guide to exporting a Godot 4 game to the web as HTML5 and WebAssembly: export templates, the SharedArrayBuffer headers that break most builds, hosting on itch.io, and how to fix a black screen.

Godot exports to the web as HTML5 and WebAssembly, which means your game runs in a browser tab with no download and no plugin. That is the single fastest way to put a playable build in front of someone: paste a link, they click, they play.

The catch is that "export to web" is two jobs, not one. Producing the files is easy and takes about a minute. Getting those files to actually run in a browser is where almost everyone hits a black screen, because modern browsers require two specific HTTP headers that the threaded WebAssembly build depends on. This guide covers both halves, the exact settings, and the three errors that account for most failed exports.

It applies to Godot 4 and to Summer Engine, which is compatible with Godot 4 and uses the same export pipeline. If you built your game by describing it in plain language, the export step is identical to a hand-coded Godot project.

{/* IMAGE: The Godot Export dialog open with a Web preset selected, the Export Project button highlighted. 1200x675 editor screenshot. */}

What "web export" actually produces

When you export, Godot does not create a single file. It writes a small folder of static assets:

  • index.html is the page that loads everything. This is what the browser opens.
  • A .wasm file is the Godot engine itself, compiled to WebAssembly. This is the largest piece.
  • A .pck file is your game data: scenes, scripts, and assets packed together.
  • A .js file is the loader glue that wires the engine to the page.
  • Often a .worker.js and a .audio.worklet.js for threading and sound.

All of these must sit together and must be served over HTTP. You cannot double click index.html and expect it to run, which is the first thing that trips people up. We will come back to that.

Step 1: Install the export templates

Godot ships the editor and the export templates separately. The templates are the prebuilt engine binaries for each platform, including the WebAssembly build for the browser. A fresh install does not have them.

Go to Editor then Manage Export Templates, and click Download and Install. This pulls the templates for your exact engine version.

This is the most important rule in the whole process: the templates must match your engine version exactly. Templates for 4.3 will not run a project exported from 4.4. A version mismatch is the second most common cause of a broken web build, right after the headers. If you update your engine, reinstall the templates.

Step 2: Add a Web export preset

Open Project then Export. Click Add and choose Web.

A panel of options appears. The defaults are sensible, but two settings matter for the web specifically:

  • Export Type. "Regular" gives you the threaded build, which is faster and the default. There used to be a non-threaded fallback for hosts that could not send the special headers. On Godot 4 you almost always want the threaded build and you fix the headers on the host side instead, which we cover below.
  • VRAM Texture Compression. Tick the box for the targets you care about. The browser uses the "For Desktop" path on most machines, so leave that on. Mobile browsers may need the mobile compression option too.

Leave the Head Include and custom HTML shell empty unless you have a reason to change them. The default shell handles loading and the progress bar for you.

Step 3: Export the project

Pick a destination folder. Create an empty one named something like web-build so the output files do not mix with anything else.

Name the main file index.html, not the name of your game. Most hosts, including itch.io, look for an index.html as the entry point. If you name it mygame.html, the host will not find it and you will see a blank directory listing instead of your game.

Click Export Project. In a few seconds the folder fills with the files listed earlier. That is the easy half done.

{/* IMAGE: A file explorer showing the exported web-build folder contents: index.html, .wasm, .pck, .js files. 1000x500. */}

Step 4: The headers problem, explained plainly

Here is the part no quick tutorial mentions, and the reason most first web exports show a black screen.

Godot 4's threaded build uses SharedArrayBuffer, a browser feature that lets the WebAssembly engine run on multiple threads. For security reasons, browsers only enable SharedArrayBuffer when the page is served with two specific HTTP response headers:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

These two headers put the page in what browsers call a "cross origin isolated" state. Without them, SharedArrayBuffer is undefined, the engine fails to start its threads, and you get a black canvas and a console error that mentions SharedArrayBuffer is not defined or crossOriginIsolated is false.

You do not set these in Godot. You set them on whatever serves the files. That is the whole trick. Three things follow from it:

  1. Opening index.html from your hard drive will never work, because there is no server to send headers.
  2. A host that cannot send custom headers (plain GitHub Pages, for example) cannot run the threaded build as is.
  3. A host that sends them automatically (itch.io with the right toggle) just works.

Step 5: Test it locally before you upload

Never debug a web export by uploading and refreshing. Test on your own machine first with a local server that sets the headers.

The quickest option, if you have Python installed, is a tiny script that serves the folder with both headers. Save this as serve.py inside your web-build folder:

import http.server, socketserver

class Handler(http.server.SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_header("Cross-Origin-Opener-Policy", "same-origin")
        self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
        super().end_headers()

with socketserver.TCPServer(("", 8000), Handler) as httpd:
    print("Serving on http://localhost:8000")
    httpd.serve_forever()

Run python serve.py and open http://localhost:8000. If the game loads here, the export is correct and any remaining problem is a host configuration issue, not a Godot one.

If you prefer not to write a script, the Remote Debug run option in Godot's editor (the dropdown next to the play button, "Run in Browser") spins up a correctly configured local server for you and opens the build. That is the fastest sanity check during development.

Step 6: Host it

itch.io (easiest, free)

This is the recommended path for sharing and for game jams.

  1. Zip the entire web-build folder. Zip the contents, not the parent folder, so index.html is at the top level of the zip.
  2. On itch.io, create a new project and set Kind of project to HTML.
  3. Upload the zip and tick This file will be played in the browser.
  4. In the embed options, set a viewport size that matches your game's resolution, and tick SharedArrayBuffer support if itch offers it (it sets the two headers for you).

itch.io handles the headers automatically, which is why it is the path of least resistance. If your game works locally with the script above but not on itch, the SharedArrayBuffer toggle is almost always the missing piece.

Netlify, Vercel, or your own server

These hosts let you set custom headers, so the threaded build runs fine once configured.

On Netlify, add a _headers file to the deploy root:

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

On Vercel, set the same two headers in vercel.json under a headers rule. On your own nginx or Apache server, add them to the location block. The principle is identical everywhere: send those two headers for the page and the assets.

GitHub Pages

Plain GitHub Pages cannot send custom headers, so the threaded build will not run there directly. People work around it with a small service worker that injects the headers client side (the "coi-serviceworker" approach is the common one), but it is a hack and not every browser respects it. If GitHub Pages is a hard requirement, expect to add that workaround. Otherwise, use itch.io or Netlify and save yourself the trouble.

Fixing a black screen: the three-question checklist

If you see a black canvas, open the browser's developer console (press F12, then the Console tab) and read the first red error. It will match one of three causes.

  1. Did you open the file directly? If the URL starts with file://, that is the problem. Serve it over HTTP with the local script above.
  2. Is SharedArrayBuffer or crossOriginIsolated in the error? The headers are missing. Add them on the host, or flip the itch.io SharedArrayBuffer toggle.
  3. Does the error mention a version or a failed template load? Your export templates do not match your engine version. Reinstall them via Manage Export Templates.

Ninety percent of failed web exports are one of these three. Work through them in order before assuming your game has a deeper bug.

What does not carry over to the browser

Web export is real, but it is not desktop with a URL. A few things behave differently:

  • File system access is sandboxed. Save data goes to the browser's IndexedDB, not to a folder on disk. Plan your save system around this if web is your target.
  • Native plugins (GDExtension libraries compiled for desktop) usually do not work in the browser. Anything that links a native .dll or .so needs a web compatible alternative or has to be cut for the web build.
  • Load size matters more than anywhere else. On the web the player downloads the engine, the data pack, and every asset before the game starts. Compress textures, remove unused assets, and keep 3D scope realistic if the web is your main channel. A heavy 3D game can be a 30 to 100 MB first load, which is painful on mobile data.
  • Audio latency is slightly higher in the browser than on desktop. Usually fine, occasionally noticeable in rhythm-tight games.

If you built the game with Summer Engine

The export steps above are identical, because Summer Engine is compatible with Godot 4 and uses the same HTML5 and WebAssembly pipeline. The difference is upstream, in how the game gets built. Instead of hand-writing the player controller, the scene setup, and the game logic, you describe what you want in plain language and the AI builds it. When you are ready to share, you export to web exactly as described here.

Web export is part of the free tier. Building and exporting are free, and the paid plan only covers higher AI usage and team features, so the full loop from idea to a link someone can click costs nothing to try.

If you have not started a project yet, the fastest route to a web-ready build is to begin from a template that already has movement and a camera wired up, describe the mechanics you want on top, then follow the six steps above to put it in a browser. The whole loop, from blank project to a playable itch.io link, fits in an afternoon.

Frequently asked questions

Can you export a Godot game to the web?

Yes. Godot 4 exports to HTML5 using WebAssembly, so your game runs in any modern browser with no plugin or install. You add a Web export preset, install the export templates, and Godot produces a folder of static files you can host anywhere. The main limits are that the threaded build needs two specific HTTP headers to run, and some desktop only features like custom window management or certain native plugins do not carry over to the browser.

Why is my Godot web export a black screen?

A black screen is almost always one of three things. First, you opened the index.html directly from your file system instead of serving it over HTTP, which browsers block. Second, your host is not sending the Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers the threaded build requires. Third, your export templates do not match your engine version. Open the browser developer console, read the first red error, and it will point at one of these three. itch.io sets the headers for you, so uploading there is the fastest way to rule out the header problem.

How do I host a Godot web game for free?

itch.io is the easiest free host. Zip the exported folder, upload it as an HTML project, tick the option to run in the browser, and itch sets the required cross origin headers automatically. GitHub Pages and Netlify also work and are free, but you have to configure the two headers yourself, which GitHub Pages cannot do without a workaround. For a quick share link, itch.io is the path of least resistance.

Is a Godot web export smaller than a desktop build?

No, web exports are often the heaviest version to load because the player downloads the entire WebAssembly engine, your game data pack, and all assets before anything runs. A small 2D game is usually a few megabytes, but a 3D game can be 30 to 100 megabytes or more, which is a slow first load on mobile data. Compress textures, strip unused assets, and keep the scope tight if the web is your main target.

Does Summer Engine export to the web?

Yes. Summer Engine is compatible with Godot 4, so it uses the same HTML5 and WebAssembly export pipeline described in this guide, and the AI can set up the export preset and explain the header requirement for you. Web export is part of the free tier. The difference is in the building, not the exporting: you describe the game in plain language and the AI writes the code and builds the scenes, then you export to web the same way you would in any Godot 4 project.