A TypeScript/React bridge for seamless communication between Flutter WebView and web applications
npm install flutter-webview-bridgepostWebMessage
bash
npm install flutter-webview-bridge
`
Quick Start
$3
`dart
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
class WebViewExample extends StatefulWidget {
@override
_WebViewExampleState createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State {
InAppWebViewController? webViewController;
WebMessagePort? port1;
WebMessagePort? port2;
@override
Widget build(BuildContext context) {
return InAppWebView(
onWebViewCreated: (controller) {
webViewController = controller;
},
onLoadStop: (controller, url) async {
// Create message channel
final webMessageChannel = await controller.createWebMessageChannel();
port1 = webMessageChannel!.port1;
port2 = webMessageChannel.port2;
// Set up message listener
await port1?.setWebMessageCallback((message) async {
print("Message from WebView: ${message.data}");
// Echo the message back
await port1?.postMessage(WebMessage(data: "Echo: ${message.data}"));
});
// Send the port to WebView
await controller.postWebMessage(
message: WebMessage(data: 'capturePort', ports: [port2!]),
targetOrigin: WebUri('*')
);
},
);
}
}
`
$3
`tsx
import React, { useEffect } from "react";
import { useFlutterBridge } from "flutter-webview-bridge";
function MyComponent() {
const { sendMessage, lastMessage, isConnected } = useFlutterBridge();
const handleSendMessage = () => {
sendMessage({
type: "greeting",
payload: { message: "Hello from React!" },
});
};
return (
Connection Status: {isConnected ? "✅ Connected" : "❌ Disconnected"}
{lastMessage && (
Last Message:
{JSON.stringify(lastMessage, null, 2)}
)}
);
}
`
API Reference
$3
React hook for Flutter WebView communication.
#### Parameters
- options (optional): Configuration object
- bridge: Custom FlutterBridge instance
- onMessage: Callback for incoming messages
#### Returns
- sendMessage(data): Function to send messages to Flutter
- lastMessage: Last received message from Flutter
- isConnected: Boolean indicating connection status
- connectionStatus: Detailed connection information
#### Example
`tsx
const { sendMessage, lastMessage, isConnected, connectionStatus } =
useFlutterBridge({
onMessage: message => {
console.log("New message:", message);
},
});
`
$3
Core bridge class for managing Flutter communication.
#### Constructor
`typescript
new FlutterBridge(options?: FlutterBridgeOptions)
`
#### Options
- debug: Enable debug logging (default: false)
- captureCommand: Command to capture port (default: 'capturePort')
- confirmationMessage: Confirmation message (default: 'portReceived')
#### Methods
- sendMessage(data): Send message to Flutter
- subscribe(callback): Subscribe to messages
- getConnectionStatus(): Get connection status
- isConnected(): Check if connected
- disconnect(): Disconnect and cleanup
#### Example
`typescript
import { FlutterBridge } from "flutter-webview-bridge";
const bridge = new FlutterBridge({ debug: true });
bridge.subscribe(message => {
console.log("Received:", message);
});
bridge.sendMessage({ type: "test", data: "Hello Flutter!" });
`
$3
`typescript
import { flutterBridge } from "flutter-webview-bridge";
// Use the global singleton instance
flutterBridge.sendMessage({ type: "global", data: "Hello!" });
`
Advanced Usage
$3
`tsx
import { useFlutterBridge } from "flutter-webview-bridge";
function AdvancedComponent() {
const { sendMessage, lastMessage, isConnected } = useFlutterBridge({
onMessage: message => {
// Handle specific message types
if (message?.type === "navigation") {
window.location.href = message.payload.url;
} else if (message?.type === "alert") {
alert(message.payload.message);
}
},
});
const sendCommand = (command: string, payload?: any) => {
sendMessage({
type: "command",
command,
payload,
timestamp: Date.now(),
});
};
return (
onClick={() => sendCommand("share", { url: window.location.href })}
>
Share Current Page
);
}
`
$3
`tsx
import { useFlutterBridge } from "flutter-webview-bridge";
function ConnectionMonitor() {
const { connectionStatus, isConnected } = useFlutterBridge();
return (
Connection Status
Connected: {isConnected ? "Yes" : "No"}
Subscribers: {connectionStatus.subscribersCount}
);
}
`
Troubleshooting
$3
1. Port not initialized
- Ensure Flutter calls postWebMessage with capturePort command
- Check timing - WebView should be fully loaded
- Verify ports are included in the message
2. Messages not received
- Enable debug mode to see detailed logs
- Check console for error messages
- Verify message format
3. Connection drops
- Monitor connection status
- Implement reconnection logic if needed
$3
Enable debug logging to troubleshoot issues:
`typescript
import { FlutterBridge } from "flutter-webview-bridge";
const bridge = new FlutterBridge({ debug: true });
`
This will log all communication attempts and help identify issues.
TypeScript Support
The library is written in TypeScript and includes complete type definitions:
`typescript
import {
FlutterBridge,
MessageCallback,
ConnectionStatus,
FlutterBridgeOptions,
} from "flutter-webview-bridge";
const callback: MessageCallback = (data: unknown) => {
console.log("Received:", data);
};
const options: FlutterBridgeOptions = {
debug: true,
captureCommand: "customCaptureCommand",
};
`
Contributing
1. Fork the repository
2. Create your feature branch (git checkout -b feature/amazing-feature)
3. Commit your changes (git commit -m 'Add some amazing feature')
4. Push to the branch (git push origin feature/amazing-feature`)