Skip to content

Desktop SPA renders blank in system webviews: bundle calls Object.hasOwn/structuredClone (needs Chromium 93/98) #2082

Description

@jaylfc

Found while building the taOSmobile kiosk surface on Ubuntu Touch (see #797). Affects any embedded webview older than Chromium 98, not just this device.

Problem

The desktop SPA loads to a blank screen in Ubuntu Touch's webview. No visible error; the bundle throws during startup and nothing renders.

The webview is webapp-container/Morph, which on UT 24.04 is QtWebEngine 5.15 = Chromium 87:

user agent: Mozilla/5.0 (Linux; Ubuntu 24.04 like Android 9) AppleWebKit/537.36 Chrome/87.0.4280.144 Mobile Safari/537.36

Cause

desktop/vite.config.ts sets target: "es2022". That is fine as syntax, but the emitted bundle also calls runtime APIs that postdate Chromium 87. Scanning the built output in static/desktop/assets:

API Needs Files affected
Object.hasOwn Chromium 93 7
structuredClone Chromium 98 2

Both throw TypeError on load, killing the app before first paint. (??= is also present but is fine — Chromium 85.)

Impact

Any deployment that renders the SPA inside a system webview rather than a current desktop browser is affected. That includes the on-device surface described in #797 and #590, where the phone displays taOS through the platform webview. It is invisible to normal development because desktop Chrome/Firefox are far newer.

Suggested fix

Either:

  1. Lower the Vite target (e.g. es2019) and add polyfills for the runtime APIs — the target alone does not transpile API calls, only syntax.
  2. Ship a small feature-detected polyfill bundle loaded before the app for Object.hasOwn, structuredClone, and Array.prototype.at.
  3. Declare a documented minimum engine and fail loudly with a readable message instead of a blank screen.

Option 3 is worth doing regardless: a silent blank screen with no console access on a phone is very hard to diagnose.

Local workaround in use

A feature-detected polyfill (Object.hasOwn, structuredClone, Array/String.prototype.at) injected ahead of the bundle, plus a window.onerror handler that paints the error on screen so failures are visible on a device with no devtools.

— taOSmobile-dev

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions