Why Does My Vue App Show a White Screen on Old Android Devices? Fixing Vite Legacy Compatibility
This article uses a fictional story to illustrate a front‑end white‑screen problem on an old Android phone, analyzes the root causes such as unsupported Chrome versions, missing globalThis and Vue loading failures, and provides a step‑by‑step Vite legacy downgrade solution with code examples and configuration tips.
Story Background
Recently a "shocking incident" occurred: a man in Chongqing drove alone at 7 pm, completed a two‑hour trip in one hour, earned money, and tried to invite a friend using a driver‑referral cash‑gift feature, only for the page to disappear.
The police investigated and found no page disappearance on other devices. A lawyer later confirmed the page truly vanished on the suspect's phone, which was a low‑cost Android device bought during JD's 618 sale.
The story is fictional and is used to describe a front‑end white‑screen issue.
Problem Investigation
The lawyer identified the device as an old model; further questioning revealed it was a Vivo X20 released in 2017, running Android 7.x with Chrome 53 (though versions can be upgraded).
Chrome version: Android 7.0 corresponds to Chrome 51 (official reference).
Console error: no Vue instance found.
Import syntax not supported. globalThis variable error.
These factors caused the page to go completely blank.
Solution
Immediate Tasks
Resolve the globalThis issue.
Fix Vue loading failure.
Apply Vite project compatibility downgrade.
Vite Modern Build
Vite is designed for modern browsers, producing fast builds and ESM‑compatible output.
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>Adding type="module" makes the browser load the script as an ES module.
JS Loading Methods
Direct load: <script src="main.js"></script> (blocks DOM rendering).
Async: <script async src="main.js"></script> (loads asynchronously, execution order not guaranteed).
Defer: <script defer src="main.js"></script> (loads asynchronously, preserves order).
Module: <script type="module" src="main.js"></script> (modern browsers, async, ordered).
Modules can be combined with importmap , but the importmap must be defined before the module script.
Preload: <link rel="preload" href="main.js"> (pre‑loads important resources).
Prefetch: <link rel="prefetch" href="main.js"> (loads resources for future use).
Modern browsers can continue using ESM; older browsers need polyfills.
How to Downgrade
Vite’s default build supports ES Modules. To add legacy support, use @vitejs/plugin-legacy:
Installation
# Install plugin
yarn add @vitejs/plugin-legacy -D
# Install terser (used by the legacy plugin)
yarn add terser -DVite normally uses esbuild for compression, but the legacy plugin compresses with terser for older browsers.
Configuration
// vite.config.js
import legacy from '@vitejs/plugin-legacy';
import { defineConfig } from 'vite';
export default defineConfig({
build: {
target: ['es2015'],
},
plugins: [
legacy({
targets: ['chrome > 52'],
}),
],
});The build target defaults to ESM; the legacy plugin overrides it. Targets follow the browserslist syntax (e.g., last 2 versions , not ie <= 8 , chrome > 61 ).
globalThis Handling
globalThisprovides a unified global object across environments. It is missing in older browsers, so a polyfill is required.
Browser environments: window, self, frames, globalThis.
Node environment: global, globalThis.
Compatibility info: https://caniuse.com/?search=globalThis
Two solutions:
Add a script in the page header:
<script>
this.globalThis || (this.globalThis = this);
</script>Configure the legacy plugin to include the polyfill:
legacy({
targets: ['chrome > 52'],
modernPolyfills: ['es.global-this'],
});Adding the polyfill directly is recommended to avoid pulling in the entire core‑js bundle.
Vue Loading Issue
The error no Vue instance found indicates that vue.js failed to load, often due to the globalThis error or an outdated Vue version. Upgrading Vue 3 and applying the compatibility downgrade resolves the issue.
Conclusion
Enable Vite legacy compatibility for older browsers.
Leverage module and nomodule scripts for graceful fallback.
Fix globalThis errors via polyfills or inline assignment.
Legacy builds use @babel/preset‑env and core‑js under the hood.
Legacy mode switches compression from esbuild to terser.
Vite still delivers on‑demand loading while supporting both modern ESM and legacy scripts.
References
https://github.com/vitejs/vite/tree/main/packages/plugin-legacy
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
