The one fact every setting follows from
When a ZIP becomes an APK, your files are placed inside the app and served to its WebView from https://appassets.androidplatform.net/web/. That address has two properties that matter to a framework:
- It is a real https origin. ES modules,
fetch()of your own JSON files,localStorageand IndexedDB behave exactly as they do on a website. Modern build output —<script type="module">and all — runs unchanged. - Your site is one folder down, at
/web/. A URL that starts with/(the default for almost every framework) points at the root of that origin, outside your files, and returns a 404.
So the changes are about where, not what: make asset URLs relative (./) — or, for tools that cannot do relative, prefix them with /web/ — and use hash-based routes.
Why hash routing
A history-mode router shows /about in the address bar and relies on the server to answer any path with index.html. In the app there is no server doing that: the page starts at /web/index.html, the router sees a path it has no route for, and renders its not-found view — or nothing. Hash routing keeps the route after the # (index.html#/about), which never leaves the page, so it works from the first launch and after every reload. The SPA routing doc covers the alternatives, including memory routers and a basename.
What to zip
The output folder, and only its contents — never the project. The index.html in your project root is a development template that loads uncompiled source; the one in dist/ (or build/, out/, browser/) is the real app. If you already zipped the whole project, the root flattener can pull the build folder out.
Frameworks with a server side
Next.js, Nuxt, SvelteKit and Remix can all render on a server. An APK has no server, so only their static or single-page modes apply: API routes, middleware, server actions and incremental regeneration are simply absent. Calls to a real backend over https:// keep working — point them at your deployed API.