Other static hosts
Français · Type: how-to · Audience: author · Context: engine repository, created project · Status: ready · Applies from: 4.2.5
dist/ is a static folder: Netlify, Cloudflare Pages, an nginx or Apache server, an object storage bucket with a web
front, any host that serves files can serve the game. This page says what such a host needs, whether it builds the game
itself or you upload a dist/ built elsewhere.
What you get
The game served by the host of your choice, with its service worker updating cleanly and its offline cache working.
Context and versions
- A created project or the engine repository; the build is the same (Build and release a game).
- From 4.2.5.
- Verified on: not verified. The project builds and checks
dist/on every push, and deploys it to GitHub Pages only; no other host is tested by the project. The settings below follow from what the build produces (vite.config.ts), not from a run on each host.
Prerequisites
- The game builds on your machine.
- The host's address: at the root of a domain, or under a sub-path (which sets
BASE_PATH).
Where to run the commands
The build runs in the created project or the engine repository: on your machine, in your CI, or in the host's build step. The upload (or the host's settings) is the host's own tool.
Steps
Choose where the build runs.
- On your machine or in your CI, then upload
dist/: the host needs nothing but files. The simplest, and the only way when the host has no Python. - In the host's build step: give it the same settings as any CI.
Setting Value Build command (created project) pip install -r node_modules/quest-n-click/requirements.txt && npm run buildBuild command (engine repository, public/assetscommitted)npm run build:webafter the checks, ornpm run buildOutput folder distNode 22.12 or later Python 3, with pip (created project) ffmpeg when the game has audio or video to encode GAMEthe game's id (engine repository) - On your machine or in your CI, then upload
- Set
BASE_PATHwhen the site is not at the root of its domain:BASE_PATH=/games/my-game/forhttps://example.org/games/my-game/, with a slash at both ends. At a domain's root, leave it unset. See Sub-path.
Set the cache headers, where the host lets you:
Path Header Why index.html,sw.js,manifest.webmanifestCache-Control: no-cacheThe page and the worker must be checked at each visit for an update to be seen assets/*.js,assets/*.css,workbox-*.jslong, e.g. max-age=31536000, immutableTheir names carry a hash: a new build gives new names assets/img/,assets/audio/,assets/video/long is safe Their addresses carry ?v=<hash>, which changes when any asset changesdata/(the sealed ending's file)no-cacheThe game asks the network first for it Serve
.webmanifestasapplication/manifest+json,.webpasimage/webpand.oggasaudio/ogg.
- Upload all of
dist/at once, or in this order: everything butindex.htmlandsw.jsfirst, then those two. A page that names files not yet uploaded is a blank page for a new visitor (Incomplete deploy).
An nginx server, as an example (not tested by the project):
# the game at the root of play.example.org, dist/ copied to /srv/my-game
server {
server_name play.example.org;
root /srv/my-game;
location = /index.html { add_header Cache-Control "no-cache"; }
location = /sw.js { add_header Cache-Control "no-cache"; }
location = /manifest.webmanifest { add_header Cache-Control "no-cache"; }
location /data/ { add_header Cache-Control "no-cache"; }
location /assets/ { add_header Cache-Control "public, max-age=31536000"; }
}
Limit ·
https-requiredA service worker only registers on HTTPS (orlocalhost). On plain HTTP the game plays online but neither installs nor plays offline.
Expected result, and how to check it
- The game opens at its address; the browser's developer tools show
sw.jsactive, under the address's path. - The pause menu's "Offline" row ends at "complete" (the engine's default text; a game may change it).
- After a new deploy, the "A new version is ready." banner (in the game's own words when it is translated) appears on the next visit; "Save and update" (translated the same way) loads it.
- In the engine repository:
node scripts/e2e.mjs https://<your-site>/plays the deployed game to its ending.
Common errors
| Symptom | Cause | Fix |
|---|---|---|
A blank page, 404 on /assets/index-….js | Under a sub-path, built without BASE_PATH | Step 2 |
| Players never get the new version | sw.js or index.html cached long by the host or a CDN | Step 3 |
| The game neither installs nor plays offline | Served over plain HTTP: the browser gives no service worker | Serve on HTTPS |
| Music cuts or does not play | The host refuses the file, or serves a wrong type | Serve .ogg as audio/ogg |
Files or data changed
Only on the host: the files of dist/ and its settings. Nothing in the project.
Recovery or going back
Upload the dist/ of an earlier build (keep the builds you shipped, or rebuild the commit). Players move to it through
the update banner; see Going back.
References
vite.config.ts: the service worker, its precache and its runtime caches.src/engine/dom/assets.ts: the assets' addresses and their?v=.- Publish on GitHub Pages, The static game on Clever Cloud.