Contract
Life Cycle Events
Common native-to-web lifecycle events for visibility, loading, and host state changes.
Life cycle events are native → web notifications. They are not app-specific
Today Page events and they do not travel through the web → native
postMessage request channel.
Native dispatches them as DOM events:
window.dispatchEvent(
new CustomEvent('todayWebViewBridge:nativeEvent', {
detail: { type: 'webView.visibilityChanged', schemaVersion: 1, visible: true },
}),
)Web subscribes through the SDK:
const unsubscribe = bridge.onNativeEvent((event) => {
if (event.type === 'webView.visibilityChanged') {
// event.visible is the native-visible state
}
})onNativeEvent returns an unsubscribe function. Web code MUST ignore unknown
native event types so native clients can add new lifecycle events safely.
Events
| Type | Meaning |
|---|---|
webView.visibilityWillChange | Native is about to change whether this WebView is user-visible. Use this as an early signal to pause expensive work, stop impression windows, or prepare for visibility-dependent UI updates before the final visible state is committed. |
webView.visibilityChanged | Native has committed the WebView's visible state. visible: true means the page is now eligible for user-visible rendering, impressions, and refresh UI; visible: false means those behaviors should pause or close. |
webView.loadStarted | Native has started a new WebView load. When present, requestId identifies the native-owned load or refresh request that Web should echo on app-specific lifecycle events such as Today Page V2 render events. |
Type Shape
type NativeLifecycleEvent =
| { type: 'webView.visibilityWillChange'; schemaVersion: 1; visible: boolean }
| { type: 'webView.visibilityChanged'; schemaVersion: 1; visible: boolean }
| { type: 'webView.loadStarted'; schemaVersion: 1; requestId?: string }Platform Mapping
These events are platform-neutral:
- iOS maps view-controller and tab visibility into the same
webView.*events. - macOS maps window, tab, and WebView activity into the same event names.
- Android maps activity / fragment / tab lifecycle into the same event names.
- Windows maps WebView2 or Electron window activity into the same event names.
- Linux maps Electron window activity into the same event names.
The event name is the contract. Platform-specific lifecycle names should not leak into Web code.