gronxb / webview-bridge
Fully Type-Safe Integration for React Native WebView and Web
webview-bridge
Fully Type-Safe Integration for React Native WebView and Web
webview-bridge
is a powerful interface that acts as a bridge between React Native and web applications using react-native-webview
. It providing seamless interaction and ensuring type safety.
Inspired by the functionality of tRPC
, webview-bridge
simplifies the communication process between react-native-webview
and web applications.
Key Features:
- Built upon
react-native-webview
. - Designed with zero external dependencies (except for
react-native-webview
). - Type-Safety
- Backward Compatibility
- No App Review Needed
- Shared State
Documentation
visit Docs
Example
visit Example
Exporting Type Declarations
To enhance your experience with webview-bridge, it's recommended to export the type declaration of the native bridge object to the web application. Here are a few ways to achieve this:
- Monorepo Setup (Recommended): Use a monorepo setup to export the type of the native bridge.
- Custom Declaration File: Build a bridge declaration file using tsc and move the file as needed.
- …
Summary
When developing with WebView, it's essential to implement communication between the web and native environments. This could be for functionalities such as in-app browsers
, alerts
, navigation
, etc.
In this post, I'll share how to type-safe
and simple
communication using the webview-bridge. Additionally, this approach supports shared state
, enabling the integration of native states reactively with other web frameworks.
React Native Part
Installation
> pnpm add @webview-bridge/react-native react-native-webview
Setup Bridge WebView
import { bridge } from "@webview-bridge/react-native";
type AppBridgeState = {
count: number;
increase(): Promise<void>;
};
export const appBridge = bridge<AppBridgeState>(({ get, set }) => ({
count: 0,
async increase() {
set({
count: get().count + 1,
});
},
}));
// It is exported via the package.json type field.
export type AppBridge = typeof appBridge;
export const { WebView } = createWebView({
bridge: appBridge,
debug: true, // Enable console.log visibility in the native WebView
});
// Use the WebView component in your app
function App(): JSX.Element {
return (
<SafeAreaView style={{ height: "100%" }}>
<WebView
source={{
uri: "http://localhost:5173",
}}
style={{ height: "100%", flex: 1, width: "100%" }}
/>
</SafeAreaView>
);
}
export default App;
Web (React) Part
Installation
> pnpm add @webview-bridge/web @webview-bridge/react
Native Method
import { linkBridge } from "@webview-bridge/web";
import type { AppBridge } from ""; // Import the type 'appBridge' declared in native
const bridge = linkBridge<AppBridge>({
onReady: async (method) => {
console.log("bridge is ready");
const version = await method.getBridgeVersion();
console.log("currentBridgerVersion", version);
},
});
bridge.getMessage().then((message) => console.log(message)); // Expecting "Hello, I'm native"
bridge.sum(1, 2).then((num) => console.log(num)); // Expecting 3
bridge.openInAppBrowser("https://google.com"); // Open google in the native inAppBrowser
Shared State
import { useBridge } from "@webview-bridge/react";
function Count() {
// render when only count changed
const count = useBridge(bridge.store, (state) => state.count);
return <p>Native Count: {count}</p>;
}
- Docs
Top comments (0)