Skip to content

Cap-go/capacitor-webview-version-checker

@capgo/capacitor-webview-version-checker

Capgo - Instant updates for capacitor

Capacitor plugin for checking whether the app WebView engine is up to date, emitting realtime status events, and optionally showing a native update prompt that redirects users to the proper update destination.

Install

bun add @capgo/capacitor-webview-version-checker
bunx cap sync

Usage

Main use case: Browserslist-style compatibility checks by default.

The plugin uses this strategy out of the box, even if you do not add any plugin options:

  • minimumDeviceSharePercent defaults to 3
  • version-share data comes from a built-in dataset generated at build time from caniuse
  • no runtime version-share URL call is required for the default flow

Default setup (no plugin settings):

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  plugins: {
    WebviewVersionChecker: {},
  },
};

export default config;

Simple config-only setup with native prompt:

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  plugins: {
    WebviewVersionChecker: {
      autoPromptOnOutdated: true,
      autoPromptDismissible: false,
    },
  },
};

export default config;

Advanced mode with custom threshold and custom dataset:

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  plugins: {
    WebviewVersionChecker: {
      autoCheckOnLoad: true,
      autoPromptOnOutdated: true,
      minimumDeviceSharePercent: 3,
      versionShareByMajor: {
        '137': 58.2,
        '136': 21.3,
        '135': 4.6,
        '134': 2.1,
      },
    },
  },
};

export default config;

What this means:

  • minimumDeviceSharePercent: 3 means "consider a version compatible only if that major version still represents at least 3% of devices in my dataset".
  • versionShareByMajor is your own dataset map where:
    • key = major version (for example 137)
    • value = share percent (0..100)
  • If you do not provide versionShareByMajor, the plugin uses its built-in generated dataset.

You can provide share data in two ways:

  • Inline with versionShareByMajor (as shown above)
  • Remote with versionShareApiUrl returning one of these shapes:
    • { "versionShareByMajor": { "137": 54.2, "136": 23.8 } }
    • { "shareByMajor": { "137": 54.2, "136": 23.8 } }
    • { "versions": [{ "major": 137, "share": 54.2 }, { "version": "136.0.0.0", "percent": 23.8 }] }

If you set versionShareApiUrl, the plugin fetches that URL at runtime and uses it as override.

Evaluation order:

  1. Browserslist-style threshold mode (minimumDeviceSharePercent + share dataset) is used first. By default this is 3% with the built-in generated dataset.
  2. Else the plugin compares against latestVersion / latestVersionApiUrl.
  3. Else it falls back to minimumMajorVersion.

Advanced usage with JavaScript (manual check, listeners, custom prompt):

import { WebviewVersionChecker } from '@capgo/capacitor-webview-version-checker';

const listener = await WebviewVersionChecker.addListener('webViewOutdated', (status) => {
  console.log('Outdated WebView detected', status);
});

const status = await WebviewVersionChecker.check({
  latestVersionApiUrl:
    'https://versionhistory.googleapis.com/v1/chrome/platforms/android/channels/stable/versions?page_size=1',
  minimumMajorVersion: 124,
  showPromptOnOutdated: true,
  autoPromptDismissible: false,
  promptTitle: 'Update WebView',
  promptMessage: 'Your WebView is outdated. Please update to continue safely.',
  promptUpdateButtonText: 'Update now',
  promptCancelButtonText: 'Later',
});

console.log('WebView status', status);

// later
listener.remove();

Why WebView Version Checker?

Capacitor already provides a built-in WebView minimum check through config:

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  android: {
    minWebViewVersion: 124,
  },
  server: {
    errorPath: 'unsupported-webview.html',
  },
};

export default config;

Why we're doing this instead

  • android.minWebViewVersion is static config; it does not give runtime plugin events like webViewOutdated.
  • With server.errorPath, users are redirected to a static error page (hard block UX) instead of seeing a native modal in your normal app flow.
  • Without server.errorPath, Capacitor only logs the issue, but does not provide a native update prompt + store deep link UX.
  • This plugin gives soft enforcement: users can still open/use the app, get a native update modal, and you decide whether to require update later.
  • Main use case: this plugin brings Browserslist-style compatibility logic to Android WebView (for example, "support versions still used by at least 3% of devices"), while keeping your app usable.

Android Provider Handling

The plugin resolves the active WebView provider package and version, then routes update links to the correct package:

  • Android 5-6 and 10+: Android System WebView (com.google.android.webview)
  • Android 7-9: Google Chrome (com.android.chrome)

When provider detection is unavailable, fallback routing follows the same API-range rule above.

API

Public API for checking WebView freshness and guiding users to updates.

check(...)

check(options?: CheckWebViewOptions | undefined) => Promise<WebViewVersionStatus>

Runs a version check and returns the latest known status.

Param Type
options CheckWebViewOptions

Returns: Promise<WebViewVersionStatus>


startMonitoring(...)

startMonitoring(options?: StartMonitoringOptions | undefined) => Promise<MonitoringStateResult>

Enables background monitoring (typically on app resume).

Param Type
options StartMonitoringOptions

Returns: Promise<MonitoringStateResult>


stopMonitoring()

stopMonitoring() => Promise<MonitoringStateResult>

Disables monitoring.

Returns: Promise<MonitoringStateResult>


getLastStatus()

getLastStatus() => Promise<LastStatusResult>

Returns the last resolved status, or null if no check was run yet.

Returns: Promise<LastStatusResult>


showUpdatePrompt(...)

showUpdatePrompt(options?: ShowUpdatePromptOptions | undefined) => Promise<ShowUpdatePromptResult>

Shows a native prompt asking the user to update the WebView.

Param Type
options ShowUpdatePromptOptions

Returns: Promise<ShowUpdatePromptResult>


openUpdatePage(...)

openUpdatePage(options?: OpenUpdatePageOptions | undefined) => Promise<OpenUpdatePageResult>

Opens the configured update page directly.

Param Type
options OpenUpdatePageOptions

Returns: Promise<OpenUpdatePageResult>


addListener('statusChanged', ...)

addListener(eventName: 'statusChanged', listenerFunc: (status: WebViewVersionStatus) => void) => Promise<PluginListenerHandle>

Fired for every successful status evaluation.

Param Type
eventName 'statusChanged'
listenerFunc (status: WebViewVersionStatus) => void

Returns: Promise<PluginListenerHandle>


addListener('webViewLatest', ...)

addListener(eventName: 'webViewLatest', listenerFunc: (status: WebViewVersionStatus) => void) => Promise<PluginListenerHandle>

Fired when the state resolves to latest.

Param Type
eventName 'webViewLatest'
listenerFunc (status: WebViewVersionStatus) => void

Returns: Promise<PluginListenerHandle>


addListener('webViewOutdated', ...)

addListener(eventName: 'webViewOutdated', listenerFunc: (status: WebViewVersionStatus) => void) => Promise<PluginListenerHandle>

Fired when the state resolves to outdated.

Param Type
eventName 'webViewOutdated'
listenerFunc (status: WebViewVersionStatus) => void

Returns: Promise<PluginListenerHandle>


Interfaces

WebViewVersionStatus

Snapshot of the currently detected WebView status.

Prop Type Description
platform WebViewPlatform Native platform that generated the status.
state WebViewVersionState Resolved version state.
isLatest boolean Convenience boolean equivalent to state === 'latest'.
checkedAt string ISO-8601 timestamp of the check.
reason string Human-readable explanation for the reported state.
currentVersion string Current WebView (or iOS system WebKit) version string.
currentMajorVersion number Current detected major version (if parseable).
latestVersion string Resolved latest version used for comparison.
latestMajorVersion number Resolved latest major version (if parseable).
currentVersionSharePercent number Device-share percentage for the installed WebView major version. Present only when a version-share dataset is available and includes the current major version.
minimumDeviceSharePercent number Configured threshold used by compatibility-threshold mode. Present only when minimumDeviceSharePercent was requested for that check.
versionShareSource string Source used for version-share data. Values: - versionShareByMajor (inline dataset) - versionShareApiUrl (remote dataset) - generatedVersionShareByMajor (built-in dataset generated at build time)
deviceShareError string Diagnostic message for compatibility-threshold mode. Present when minimumDeviceSharePercent was requested but the threshold check could not be fully evaluated.
providerPackage string Android package name of the active WebView provider.
updateUrl string URL that should be opened to update when outdated.
source string Internal source identifier for the check implementation.

CheckWebViewOptions

Options for running a WebView version check.

Prop Type Description Default
showPromptOnOutdated boolean Force showing a native prompt if an outdated WebView is detected. false
source string Optional tag included in the status payload so you can identify the check origin. "manual"

MonitoringStateResult

Result payload for monitor controls.

Prop Type Description
monitoring boolean Whether monitoring is currently active.
checkOnResume boolean Whether checks run on app resume while monitoring is active.
autoPromptOnOutdated boolean Whether outdated checks auto-trigger the native prompt.

StartMonitoringOptions

Options for starting monitor mode.

Prop Type Description Default
checkOnStart boolean Run a check immediately when monitoring starts. true
checkOnResume boolean Whether foreground checks should run while monitoring is enabled. true

LastStatusResult

Last known check snapshot.

Prop Type Description
status WebViewVersionStatus | null Null until the first check completes.

ShowUpdatePromptResult

Result payload for showUpdatePrompt().

Prop Type Description
shown boolean Whether a native prompt was actually shown.
openedUpdatePage boolean Whether the update page was opened from the prompt action.

ShowUpdatePromptOptions

Options for showing the native update prompt.

Prop Type Description
title string Prompt title.
message string Prompt message.
updateButtonText string Update CTA label.
cancelButtonText string Cancel CTA label.
updateUrl string Optional URL to open if the update action is selected.

OpenUpdatePageResult

Result payload for openUpdatePage().

Prop Type Description
opened boolean Whether opening the update URL succeeded.
url string URL that was attempted.

OpenUpdatePageOptions

Options for opening the update page directly.

Prop Type Description
updateUrl string Optional URL override.

PluginListenerHandle

Prop Type
remove () => Promise<void>

Type Aliases

WebViewPlatform

'android' | 'ios' | 'web'

WebViewVersionState

'latest' | 'outdated' | 'unknown'

About

Capacitor plugin for checking outdated Android WebView engines with native update prompts and runtime status events.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors