Troubleshooting
Start here
Three things to establish before anything else:
- The app version —
document.querySelector('meta[name="version"]').content - The browser console — most failures leave a message there and nowhere else
- The network tab — a failed
data.jsonor asset request is visible at once
To debug a phone, connect it: Safari's Web Inspector for iOS, chrome://inspect for Android. Guessing from the phone screen alone wastes an afternoon.
The app does not load
Blank white page
Open the console.
- A module loading error — the
.jsfiles are served with the wrong MIME type. See Self-hosting. - 404 on
/build/…— a subdirectory deployment without the path fixes. See Deployment. - Nothing at all — check that
index.htmlis served, and is the build you think it is.
It goes straight to the error screen
The content could not be loaded. In order of likelihood:
data_urlis wrong. Open it directly in a browser.- CORS. The console says so explicitly. See Media.
- Mixed content. The app is on HTTPS and the data URL is HTTP. The browser blocks it.
- Invalid JSON. A trailing comma is enough. Run it through a validator.
- The content host is down.
The language screen is empty, or the content never updates
A required key is missing from data.json — checksum, assets, stations, languages or texts. The app ignores such a file without an error: a fresh device has no languages to offer and shows an empty language screen, and a device that loaded the guide before keeps its old content. Validate against the schema.
It loads but the station list is empty
The content loaded but has nothing for the chosen language: no station carries that language. Validate against the schema.
Stations appear in one language but not another
Stations are looked up by language, without a fallback. A station missing from the Spanish set does not exist for a Spanish visitor. Run the checklist script.
Content
Content changed but the app shows the old version
Check the checksum first. Nearly always it was not changed — and devices that loaded the guide before keep their stored content until it does. See Data format.
Then:
- Is the change actually published?
curlthe data URL. - A CDN in front of your content host may serve the old file. Purge it.
- With offline support, the device has to be online once to fetch the new file.
A new station does not show up
- It is missing in one or more languages
- Its
idduplicates another station's — both entries then show whichever comes later in the file. A duplicatenumberhides nothing; it only makes the keypad open one of the two. - The
checksumdid not change
Images do not load
- An id in
stations.imagesdoes not exist inassets— the page then fails to render, with an error in the console - On the main screen, a station has only one image; it needs two, see Stations
- The
externalUrlreturns 404. Open it directly. - CORS, or mixed content
The keypad cannot find a station
It matches number exactly, as a string, and takes two digits by default. See Stations.
A text shows as its key, such as "try again" or "menu share-app"
The key is missing from texts for the current language. See UI texts.
Audio
Audio does not play
- Open the asset URL directly. Does it download and play?
- CORS on the media host
- Range requests:
curl -I -H "Range: bytes=0-99" <url>should give206 - The codec — re-encode to plain MP3
- The first play in a session must come from a tap. See Audio.
It plays but cannot be scrubbed
The media host does not support range requests. See Media.
Audio stops when the screen locks
Test the deployed app on a real device, not the dev server. If it persists, note the browser and system versions and open an issue — background audio is platform-specific.
The lock screen shows the wrong title
Some platforms prefer the MP3's own ID3 metadata. Strip or correct it:
ffmpeg -i in.mp3 -map_metadata -1 -metadata title="1 – The Great Hall" -codec copy out.mp3
Offline
No service worker registers
- The build has no offline support —
offline_supportwas not"true", and it was not built withnpm run build:offline - The site is on plain HTTP — service workers need HTTPS (
localhostexcepted) - The registration path is wrong for a subdirectory deployment
Media is missing offline
Its URL does not contain assets/, so the service worker does not cache it. See Offline.
The download never finishes
An asset fails. Open the network tab while the loading screen is up; the failed request is there.
An old version keeps being served
A service worker doing its job with stale files.
index.htmlandsw.jsmust be served withCache-Control: no-cache- Purge your CDN for both
- To reset a test device: DevTools → Application → Storage → Clear site data
A menu icon is missing offline
Ionic icons are precached one by one. A new icon has to be added to globPatterns in stencil.config.ts. See Configuration.
Build and customization
npm install fails
Node 22 or newer — check with node --version.
The build stops with an error about DATA_URL, FONT_DIR or ICON_SOURCE
A repository path has to sit inside a folder, stay inside the repository and use forward slashes, and the icon source has to exist. The message names the path it got.
engraft did not change anything
- A misspelled variable — engraft does not warn about values the template does not declare
logo,logo_darkandfont_stylesheetare relative to the values file;icon_source,data_urlandfont_dirto the repository root- Check with
git diff --statafter the apply
A variant shows values of another one
Applies are not additive. Reset the files between them:
git checkout -- src stencil.config.ts scripts/generate-icons.mjs
See Variants.
The deployed guide is the Animals demo
The engraft step is missing from your build command. See Deployment.
Appearance
Colours look wrong in dark mode
The dark palette is derived from the light background. Override the derived value if it comes out badly — see Colors.
The logo is invisible in dark mode
logo_dark is a separate file, not a filter. See Logos and icons.
The station progress ring is hard to see
It is the primary colour stepped 18 % off the background. If your primary is close to your background, that is not enough — override station_icon_progress_color.
Deployment
GitHub Pages returns 404
The Pages source is still "Deploy from a branch". Set it to GitHub Actions.
The custom domain disappears on every deploy
The CNAME file is not in the uploaded artifact. See GitHub Pages.
Getting help
Search the existing issues first — app, library — or ask in the discussions.
A useful report has:
- The app version from the meta tag
- Browser and its version, system version, device
- What you did, what happened, what you expected
- Console output and the failing network request
- A link to a deployment showing the problem, if it is public
Security problems do not go into the issue tracker; see the security policy.