Why chrome://inspect does not show your app
Android lets desktop Chrome attach to an app's WebView only if the app is debuggable or explicitly opts in. Store-ready release builds do neither — a WebView anyone could attach to with a USB cable would expose every user's session. So the classic "plug in, open chrome://inspect" workflow applies to your own debug builds of native apps, not to a signed release APK.
That turns out to matter less than it sounds, because the app's environment is easy to reproduce exactly.
Step 1 — reproduce the app on your computer
The app serves your files from a sub-folder, /web/, of an https origin. Recreate that locally:
mkdir -p /tmp/app-sim/web
cp -R dist/* /tmp/app-sim/web/ # or your unzipped site
cd /tmp/app-sim
npx serve -l 5050 . # or: python3 -m http.server 5050
Open http://localhost:5050/web/index.html. Every path bug the app has, this has: a root-relative /assets/app.js 404s here too, a history-mode router misses its route, a missing file shows up in the Network panel in red. Open DevTools, then:
- Console — the first red error is usually the whole story.
- Network — filter by status 404, and tick "Disable cache".
- Device toolbar (Ctrl/⌘+Shift+M) — pick a phone, check layout, touch targets and the viewport tag.
- Network → Offline — the quick version of the airplane-mode test.
Case sensitivity is the one thing this misses on Windows and macOS, whose file systems ignore capital letters. Run the filename case checker on the ZIP to cover it.
Step 2 — a console on the phone
For problems that only happen in the app — an old WebView, a permission, touch behaviour — add an on-device console to a test build. Eruda is a small script that draws a DevTools-like panel (console, elements, network, storage) inside the page:
<script src="js/eruda.min.js"></script>
<script>eruda.init()</script>
Download eruda.min.js into the ZIP rather than loading it from a CDN, so it works offline too. Build, install, and tap the floating gear to see errors as they happen on the device. Remove both lines before the release build.
Step 3 — log what you cannot see
For intermittent issues, capture errors yourself and keep them where you can read them later:
addEventListener('error', (e) => saveLog(`${e.message} @ ${e.filename}:${e.lineno}`))
addEventListener('unhandledrejection', (e) => saveLog(`promise: ${e.reason}`))
function saveLog(line) {
const log = JSON.parse(localStorage.getItem('log') || '[]').slice(-49)
log.push(new Date().toISOString() + ' ' + line)
localStorage.setItem('log', JSON.stringify(log))
}
A hidden "About → diagnostics" screen that shows the log (and a Copy button) turns a user's "it doesn't work" into an actual error message.
Useful facts while debugging
location.originin the app ishttps://appassets.androidplatform.net;location.pathnamestarts with/web/.- The user-agent string reports a fixed Chrome version. Use feature detection, not the UA, to reason about capabilities.
- A missing file returns a real 404, visible in Eruda's network tab — not an empty 200.