What the checker looks for
A ZIP converts to a working APK when four things are true, and this tool tests each of them the way the build does. The entry page: an index.html must sit at the root of the archive, not inside a folder. The paths: every src and href must be relative, because inside an app there is no web server to resolve /css/style.css against. The scripts: type="module" scripts are refused on bundled file:// pages, which is the single most common cause of a blank screen. The size: 5 MB of web content on the free tier, 18 MB with Pro.
Around those it flags the things that are merely annoying — macOS's __MACOSX folder, .DS_Store files, links to files that are not in the archive, a <base> tag pointing at your old domain, fetch() calls to local JSON that Chrome will block, and libraries loaded from a CDN that will not be there when the phone is offline.
The wrapper-folder mistake
Nine out of ten failed ZIPs share one cause: the user right-clicked the folder and chose "Compress", so the archive contains my-site/index.html rather than index.html. The build opens the archive, finds no page at the root, and has nothing to show. The checker recognises this exact shape — a single top-level folder with an index.html inside — and tells you to zip the folder's contents instead. Or skip the problem: the Folder to ZIP tool packs a folder with its contents at the root every time.
Why absolute paths break in an app
On a website, /images/logo.png means "from the root of this domain". Inside an APK there is no domain; the pages are read from the app's bundle, and the root is the root of the device's file system. The browser engine looks for /images/logo.png on the phone itself, finds nothing, and you see a broken image — or, when it is the stylesheet, an unstyled page. Relative paths (images/logo.png, or ../images/logo.png from a sub-folder) work identically on the web and in the app, so use them everywhere. If the site is already written with absolute paths, the Absolute Path Fixer converts them.
Why module scripts show a blank page
<script type="module"> is loaded with CORS rules, and a file opened from file:// has an opaque origin, so the browser engine refuses to run it. Nothing is displayed and the only clue is a console message you cannot see on a phone. Every bundler can emit a classic script instead: in Vite, target older browsers with the legacy plugin or build an IIFE; in webpack, leave output.module off; in hand-written code, remove the type attribute and replace import statements with a single concatenated file. The blank-screen guide shows each fix.
What it cannot check
The tool reads the archive structure and the text of your HTML; it does not execute your JavaScript. Runtime errors, a router that expects a server, or a page that draws itself only after an API call will pass the check and still misbehave in the app. When the checklist is green but the app is not, open the same files in Chrome from disk (file:///path/to/index.html) — the app behaves almost exactly like that.