Skip to main content

Fallback Mode

Develop the web app in a plain browser before any host exists. When no transport is available and fallback is enabled, calls are answered by mock handlers instead of failing.

Plugins carry their own mocks — typed against the contract:

export const camera = definePlugin('camera', {
takePhoto: action<{ quality?: number }, { uri: string }>(),
}).withFallback({
takePhoto: async () => ({ uri: 'https://picsum.photos/400/300' }),
});

createBridgeReact / createBridgeVue merge every plugin's mocks automatically. With @webview-ts/core directly:

import { mergeFallbacks } from '@webview-ts/shared';

const bridge = new BridgeClient({ fallback: mergeFallbacks([camera], undefined) });

Config forms​

fallback: true; // log a warning and reject each call (visible, not silent)
fallback: false; // disabled — calls fail with NATIVE_UNAVAILABLE (default)
fallback: fallbackMap; // answer calls with these handlers

Checking the mode​

bridge.connectionMode; // 'native' | 'fallback' | 'disconnected'

The React and Vue bindings expose this as connectionMode / isAvailable — useful for a dev-mode badge. The iframe example shows the full pattern: the same page shows native inside the shell and fallback when opened standalone.

Precedence​

Fallback only activates when the real transport is unavailable. Inside an actual host, plugin mocks are inert — there is no "mock in production" failure mode. This also applies when a custom adapter is injected: if it reports unavailable and fallback is enabled, fallback takes over.