Quick answer: HTML, CSS, images, fonts, classic JavaScript, canvas, audio, video, localStorage, IndexedDB, forms, links between pages and back navigation all work offline in a ZIP-to-APK app. Four things do not, because bundled pages load from
file://with no origin:<script type="module">,fetch()/XHR of local files, service workers, and cookies. Each has a simple workaround.
Why the origin matters
A web page served from https://example.com has an origin, and browsers use the origin to decide what the page may read, store and request. Files in an APK are loaded from the app's bundle, which the WebView treats like file://: a page with a null origin. Nearly everything still works, because nearly everything is origin-agnostic. The exceptions are the features whose security model is built entirely on origins.
Works exactly as on the web
| Feature | Notes |
|---|---|
| HTML, CSS, images, SVG, fonts | Relative paths. WOFF2 and WebP supported. |
Classic <script src> and inline scripts | Any JavaScript Chrome runs. ES2020+ syntax is fine; only the module loading is blocked. |
| Links between bundled pages | about.html, ../index.html, anchors, the back button. |
localStorage, sessionStorage | Persisted in the app's private data. Shared between all your pages. |
| IndexedDB | Works; suitable for large offline datasets. |
| Canvas, WebGL, Web Audio | Games and visualisations run at Chrome speed. |
<audio>, <video> | From bundled files. Autoplay-with-sound needs a user gesture, as in Chrome. |
Forms, validation, <input type=file> | File picker opens the Android chooser. Submission needs JavaScript — there is no server. |
| CSS animations, transitions, media queries | Including prefers-color-scheme and safe-area insets. |
Requests to https:// APIs | Work when online, subject to the API's CORS headers (a null origin is sent as Origin: null). |
window.open, mailto:, tel: | Hand off to the system. |
Does not work, and the workaround
Module scripts
<script type="module"> is fetched with CORS, and a null origin fails the check — blank page. Workaround: bundle to a classic script (IIFE) and load it with <script src>. Every bundler does this; hand-written modules can be concatenated.
fetch() and XMLHttpRequest of local files
Chrome forbids a file:// page from reading other file:// URLs via XHR/fetch. Workaround: ship data as JavaScript — data.js with window.DATA = […] — and load it as a script. For text content, a <template> element or a hidden <script type="text/plain"> block. Requests to https:// endpoints are unaffected.
Service workers
Require a secure origin; registration throws on file://. Workaround: none needed — the app is already offline. Guard the registration so it does not throw: if (location.protocol.startsWith('http')) navigator.serviceWorker.register(…).
Cookies
Cookies are keyed by origin, and a null origin has nowhere to keep them. Workaround: use localStorage, which works.
History-mode routing
history.pushState('/about') works, but a reload or deep link to /about has no server to answer it. Workaround: hash routing (#/about).
Web Share, clipboard, notifications
navigator.share and navigator.clipboard require a secure context and may be unavailable; Notification is not supported in a WebView. Workaround: feature-detect and fall back; for push, use the builder's Pro push feature, which is native.
Storage limits
The WebView allows a generous quota — typically a percentage of free device storage, hundreds of megabytes on any modern phone. localStorage is capped at about 5 MB per origin as in Chrome; IndexedDB is the place for anything larger. Storage is wiped when the app is uninstalled and preserved across updates as long as the package name and signing key stay the same.
Testing offline behaviour
On your computer, open index.html from disk (file://) in Chrome: every limitation above appears there too, with errors in the console. On the phone, enable aeroplane mode and open the app; anything that still relied on the network will show up. The ZIP checker lists external hosts a page loads from, so you can see what depends on a connection before you build.