tamer-webview

Embedded in-app WebView for Lynx: iOS WKWebView, Android android.webkit.WebView. Registers the native custom element <webview> with props such as uri, html, and baseUrl (no JSON blob on the JS side). There is no React wrapper component—you use <webview> in JSX.

Behavior and API are informed by react-native-webview (see reference/react-native-webview in this repo). Pages can post messages to the app using the same bridge name as RN: ReactNativeWebView (window.ReactNativeWebView.postMessage(...)).

Installation

t4l add tamer-webview

The CLI resolves npm’s default installable version for the package. Then run t4l link so native projects pick up lynx.ext.json, CocoaPods, and Gradle. t4l link also refreshes .tamer/tamer-components.d.ts and your tsconfig.json include when syncTamerComponentTypes is enabled (default in tamer.config.json).

Requirements

  • Native host must register the element (autolink does this for Tamer dev app and embeddable).
  • ATS (iOS) / cleartext (Android): loading non-HTTPS URLs may require app-side configuration (NSAppTransportSecurity, usesCleartextTraffic, etc.).

TypeScript

Ambient typings live in dist/webview-jsx.d.ts (declared in package.json exports["./webview-jsx"] and tamer.ambientTypeExports). They augment @lynx-js/types so <webview> is typed.

Typings: t4l init / t4l link generate .tamer/tamer-components.d.ts with path references into node_modules/.../dist/webview-jsx.d.ts and update tsconfig.json include when syncTamerComponentTypes is enabled (default). You do not need import '@tamer4lynx/tamer-webview' for types alone—that file is enough. If the Lynx app uses src/tsconfig.json, include ../.tamer/tamer-components.d.ts there as well—see Ambient types (CLI).

Import the package only when you use JS exports (imperative helpers):

import { useWebViewRef, callWebViewMethod } from '@tamer4lynx/tamer-webview'

Usage

<webview
  uri="https://example.com"
  injectedJavaScript="window.__tamer = 1;"
  bindload={(e) => console.log(e.detail.url, e.detail.title)}
  binderror={(e) => console.log(e.detail)}
  bindmessage={(e) => console.log(e.detail.data)}
/>
<webview html="<p>Hello</p>" baseUrl="https://example.org/" />

If uri is non-empty, it is loaded first. Otherwise html + optional baseUrl are used.

Props (WebViewProps)

These match packages/tamer-webview/src/types.ts (ambient <webview> uses the same shape).

PropTypeDescription
uristringURL to load
htmlstringInline HTML string
baseUrlstringBase URL when loading html
injectedJavaScriptstringScript evaluated after load
injectedJavaScriptBeforeContentLoadedstringScript evaluated before the page’s own scripts run
javaScriptEnabledbooleanEnable/disable JavaScript in the page
messagingEnabledbooleanWhen enabled, exposes window.ReactNativeWebView.postMessage to the page
userAgentstringOverride the WebView user agent
stylestring | CSSPropertiesLynx styles
classNamestringCSS class name
idstringElement id (e.g. for selector queries)
bindloadhandlerSee Events
binderrorhandlerSee Events
bindmessagehandlerSee Events

Native defaults (not encoded in TypeScript): javaScriptEnabled and messagingEnabled default to true on iOS/Android; userAgent falls back to a Chrome Mobile–style UA when unset.

Events

Handlers use Lynx BaseEvent: e.detail carries the payload (not React-style).

Bind attributee.detail type
bindload{ url: string; title: string; loading: boolean; canGoBack: boolean; canGoForward: boolean }
binderror{ domain?: string; code?: number; description?: string }
bindmessage{ data: string } (from window.ReactNativeWebView.postMessage)

Imperative APIs (invoke / WebViewRef)

Use NodesRef.invoke with callWebViewMethod, or useWebViewRef() — the ref’s imperative surface is WebViewRef in packages/tamer-webview/src/index.tsx.

MethodParamsDescription
reloadReload the current page
goBackGo back in history
goForwardGo forward in history
stopLoadingStop the current load
loadUrl{ url: string }Load a URL
injectJavaScript{ script: string }Run JS in the page
postMessage{ data: string }Dispatch a message event on window in the page

See also