webviewbridge-guide
Guide for using WebViewBridge Swift package to build WebPage (macOS 26.0+) bridges with JavaScript injection and bidirectional communication. Use when integrating WebPage with Swift, injecting JavaScript, or handling JS↔Swift messaging.
When & Why to Use This Skill
This Claude skill serves as a comprehensive integration guide for the WebViewBridge Swift package, specifically designed for macOS 26.0+ (WebPage API). It empowers developers to implement seamless bidirectional communication between Swift and JavaScript, providing robust patterns for JavaScript injection, message handling, and WebSocket interception to enhance hybrid application development.
Use Cases
- Case 1: Building hybrid macOS applications that require high-performance, low-latency communication between native Swift logic and web-based user interfaces.
- Case 2: Injecting custom JavaScript modules and core utilities into WebPages to extend web content functionality with native system capabilities.
- Case 3: Implementing complex data synchronization and event handling between JavaScript environments and Swift controllers using structured messaging.
- Case 4: Debugging and intercepting WebSocket traffic within a WebView to monitor real-time data flows or implement custom network security protocols.
| name | webviewbridge-guide |
|---|---|
| description | Guide for using WebViewBridge Swift package to build WebPage (macOS 26.0+) bridges with JavaScript injection and bidirectional communication. Use when integrating WebPage with Swift, injecting JavaScript, or handling JS↔Swift messaging. |
| allowed-tools | Read, Glob, Grep, Write, Edit, Bash |
WebViewBridge Guide
This skill helps use the WebViewBridge Swift package for WebPage (macOS 26.0+) bidirectional communication.
Package Overview
WebViewBridge is a Swift framework for WebPage API with JavaScript injection and bidirectional communication.
- Repository: https://github.com/Sunalamye/WebViewBridge
- Platforms: macOS 26.0+ (WebPage API)
- License: MIT
Installation
// Package.swift
dependencies: [
.package(url: "https://github.com/Sunalamye/WebViewBridge.git", from: "1.0.0"),
]
targets: [
.target(
name: "YourApp",
dependencies: ["WebViewBridge"]
),
]
Architecture
WebViewBridge/
├── Core/
│ └── WebViewBridge.swift - Main bridge class
├── JavaScript/
│ └── bridge-core.js - Core JS utilities
└── WebViewBridgeKit.swift - Version info
Quick Start
1. Create Bridge & Register Modules
import WebViewBridge
import WebKit
@available(macOS 26.0, *)
@MainActor
class MyViewController: NSViewController {
let bridge = WebViewBridge(handlerName: "myBridge")
var webPage: WebPage?
override func viewDidLoad() {
super.viewDidLoad()
// Register core modules
bridge.registerCoreModules()
// Register custom module
bridge.registerModule(JavaScriptModule(
name: "my-module",
source: """
window.myApp = {
sendMessage: function(msg) {
window.__bridgeCore.sendToSwift('custom_message', { message: msg });
}
};
"""
))
// Handle messages
bridge.onMessage = { type, data in
print("Received: \(type) - \(data)")
}
// Configure WebPage
var configuration = WebPage.Configuration()
let userContentController = WKUserContentController()
bridge.configure(contentController: userContentController)
configuration.userContentController = userContentController
// Create WebPage
webPage = WebPage(configuration: configuration)
bridge.configure(webPage: webPage!)
}
}
2. JavaScript → Swift
// Using bridge-core
window.__bridgeCore.sendToSwift('my_event', { key: 'value' });
// Using custom API
window.myApp.sendMessage('Hello!');
3. Swift → JavaScript
Task {
// ⚠️ MUST use `return` statement!
let title = try await bridge.callJavaScript("return document.title")
}
⚠️ Critical: Return Statement
WebPage.callJavaScript() requires return statement!
// ❌ WRONG - returns null
try await bridge.callJavaScript("document.title")
// ✅ CORRECT
try await bridge.callJavaScript("return document.title")
try await bridge.callJavaScript("return JSON.stringify({a: 1})")
JavaScriptModule
let module = JavaScriptModule(
name: "my-module",
source: "window.myAPI = { ... };",
injectAtStart: true, // default: true
mainFrameOnly: false // default: false
)
// Load from bundle
let module = JavaScriptModule.fromBundle(named: "my-script", bundle: .main)
WebViewBridgeDelegate
@available(macOS 26.0, *)
public protocol WebViewBridgeDelegate: AnyObject {
func bridge(_ bridge: WebViewBridge, didReceiveMessage type: String, data: [String: Any])
func bridge(_ bridge: WebViewBridge, webSocketStatusChanged connected: Bool) // optional
func bridge(_ bridge: WebViewBridge, didEncounterError error: Error) // optional
}
bridge-core.js API
// Send to Swift
window.__bridgeCore.sendToSwift(type, data)
// Log
window.__bridgeCore.log(message)
// Base64
window.__bridgeCore.arrayBufferToBase64(buffer)
window.__bridgeCore.base64ToArrayBuffer(base64)
window.__bridgeCore.blobToBase64(blob, callback)
// WebSocket interceptor
window.__bridgeCore.installWebSocketInterceptor({
shouldIntercept: (url) => url.includes('api.example.com')
})
Message Types
| Type | Direction | Description |
|---|---|---|
websocket_open |
JS → Swift | WebSocket connecting |
websocket_connected |
JS → Swift | WebSocket connected |
websocket_message |
JS → Swift | WebSocket message |
websocket_closed |
JS → Swift | WebSocket closed |
console_log |
JS → Swift | Log message |
Complete Example
@available(macOS 26.0, *)
@MainActor
class WebManager {
let bridge = WebViewBridge(handlerName: "app")
var webPage: WebPage?
func setup() {
bridge.registerCoreModules()
bridge.registerModule(JavaScriptModule(
name: "app-api",
source: """
window.App = {
notify: (msg) => __bridgeCore.sendToSwift('notify', {msg})
};
"""
))
bridge.onMessage = { type, data in
if type == "notify", let msg = data["msg"] as? String {
print("Notification: \(msg)")
}
}
var config = WebPage.Configuration()
let ucc = WKUserContentController()
bridge.configure(contentController: ucc)
config.userContentController = ucc
webPage = WebPage(configuration: config)
bridge.configure(webPage: webPage!)
}
func getTitle() async -> String? {
try? await bridge.callJavaScript("return document.title") as? String
}
}
Checklist
- Using
@available(macOS 26.0, *) - Called
registerCoreModules() - Configured both
contentControllerandwebPage - Using
returnincallJavaScript() - Set
onMessageor delegate
Reference Documentation
- WebViewBridge Reference - Full API and examples