@capgo/capacitor-webview-version-checker

June 16, 2026 · View on GitHub

Capgo - Instant updates for Capacitor

➡️ Get Instant updates for your App with Capgo

Missing a feature? We’ll build the plugin for you 💪

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

You can use our AI-Assisted Setup to install the plugin. Add the Capgo skills to your AI tool using the following command:

npx skills add https://github.com/cap-go/capacitor-skills --skill capacitor-plugins

Then use the following prompt:

Use the `capacitor-plugins` skill from `cap-go/capacitor-skills` to install the `@capgo/capacitor-webview-version-checker` plugin in my project.

If you prefer Manual Setup, install the plugin by running the following commands and follow the platform-specific instructions below:

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.

ParamType
optionsCheckWebViewOptions

Returns: Promise<WebViewVersionStatus>


startMonitoring(...)

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

Enables background monitoring (typically on app resume).

ParamType
optionsStartMonitoringOptions

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.

ParamType
optionsShowUpdatePromptOptions

Returns: Promise<ShowUpdatePromptResult>


openUpdatePage(...)

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

Opens the configured update page directly.

ParamType
optionsOpenUpdatePageOptions

Returns: Promise<OpenUpdatePageResult>


addListener('statusChanged', ...)

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

Fired for every successful status evaluation.

ParamType
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.

ParamType
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.

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

Returns: Promise<PluginListenerHandle>


Interfaces

WebViewVersionStatus

Snapshot of the currently detected WebView status.

PropTypeDescription
platformWebViewPlatformNative platform that generated the status.
stateWebViewVersionStateResolved version state.
isLatestbooleanConvenience boolean equivalent to state === 'latest'.
checkedAtstringISO-8601 timestamp of the check.
reasonstringHuman-readable explanation for the reported state.
currentVersionstringCurrent WebView (or iOS system WebKit) version string.
currentMajorVersionnumberCurrent detected major version (if parseable).
latestVersionstringResolved latest version used for comparison.
latestMajorVersionnumberResolved latest major version (if parseable).
currentVersionSharePercentnumberDevice-share percentage for the installed WebView major version. Present only when a version-share dataset is available and includes the current major version.
minimumDeviceSharePercentnumberConfigured threshold used by compatibility-threshold mode. Present only when minimumDeviceSharePercent was requested for that check.
versionShareSourcestringSource used for version-share data. Values: - versionShareByMajor (inline dataset) - versionShareApiUrl (remote dataset) - generatedVersionShareByMajor (built-in dataset generated at build time)
deviceShareErrorstringDiagnostic message for compatibility-threshold mode. Present when minimumDeviceSharePercent was requested but the threshold check could not be fully evaluated.
providerPackagestringAndroid package name of the active WebView provider.
updateUrlstringURL that should be opened to update when outdated.
sourcestringInternal source identifier for the check implementation.

CheckWebViewOptions

Options for running a WebView version check.

PropTypeDescriptionDefault
showPromptOnOutdatedbooleanForce showing a native prompt if an outdated WebView is detected.false
sourcestringOptional tag included in the status payload so you can identify the check origin."manual"

MonitoringStateResult

Result payload for monitor controls.

PropTypeDescription
monitoringbooleanWhether monitoring is currently active.
checkOnResumebooleanWhether checks run on app resume while monitoring is active.
autoPromptOnOutdatedbooleanWhether outdated checks auto-trigger the native prompt.

StartMonitoringOptions

Options for starting monitor mode.

PropTypeDescriptionDefault
checkOnStartbooleanRun a check immediately when monitoring starts.true
checkOnResumebooleanWhether foreground checks should run while monitoring is enabled.true

LastStatusResult

Last known check snapshot.

PropTypeDescription
statusWebViewVersionStatus | nullNull until the first check completes.

ShowUpdatePromptResult

Result payload for showUpdatePrompt().

PropTypeDescription
shownbooleanWhether a native prompt was actually shown.
openedUpdatePagebooleanWhether the update page was opened from the prompt action.

ShowUpdatePromptOptions

Options for showing the native update prompt.

PropTypeDescription
titlestringPrompt title.
messagestringPrompt message.
updateButtonTextstringUpdate CTA label.
cancelButtonTextstringCancel CTA label.
updateUrlstringOptional URL to open if the update action is selected.

OpenUpdatePageResult

Result payload for openUpdatePage().

PropTypeDescription
openedbooleanWhether opening the update URL succeeded.
urlstringURL that was attempted.

OpenUpdatePageOptions

Options for opening the update page directly.

PropTypeDescription
updateUrlstringOptional URL override.

PluginListenerHandle

PropType
remove() => Promise<void>

Type Aliases

WebViewPlatform

'android' | 'ios' | 'web'

WebViewVersionState

'latest' | 'outdated' | 'unknown'