Usage: Injected Scripts (Window)
Relevant source files
The following files were used as context for generating this wiki page:webext-bridge facilitates communication between scripts injected directly into a webpage (the window context) and other parts of a web extension, such as the content script, background script, or popup. Since injected scripts operate in an isolated world and cannot use the browser.runtime APIs directly, webext-bridge uses the content script as a secure proxy. This is achieved through a combination of window.postMessage for communication between the page and the content script, and the standard extension messaging ports for communication between the content script and the rest of the extension.
To enable this communication, you must use the webext-bridge/window module in your injected script and the webext-bridge/content-script module in your content script. A shared, unique namespace must be configured in both contexts to establish a secure communication channel and prevent conflicts with other scripts that might be running on the same page.
Sources: src/window.ts, src/content-script.ts, src/internal/post-message.ts
Architecture and Initialization
The core architecture relies on the content script acting as a message broker between the window context and the extension's other runtimes (e.g., background). Communication is initialized by establishing a namespaced message channel.
Initialization Steps
- In the Injected Script (
window): CallsetNamespace()with a unique string. This prepares the script to send and receive messages viawindow.postMessagewithin that namespace. - In the Content Script: Call
allowWindowMessaging()with the exact same namespace string. This instructs the content script to listen for messages from thewindowon that namespace and enables the relay.
This two-way handshake is mandatory. Communication will fail if the namespaces are not set or do not match.
Sources: src/window.ts:18-21, src/content-script.ts:34-37, src/internal/post-message.ts:28-36
Initialization Functions
| Function | Context | Description | Source File |
|---|---|---|---|
setNamespace(nsps: string) | window | Sets the communication namespace. This must be called before any messages can be sent or received. | src/window.ts:18 |
allowWindowMessaging(nsps: string) | content-script | Authorizes communication with the window context on the specified namespace. | src/content-script.ts:34 |
Architectural Flow
The following diagram illustrates the high-level communication path between the window context and the background script.
This diagram shows that the window script and content-script communicate via window.postMessage, while the content-script and background script use a persistent runtime.Port.
Sources: src/window.ts:9, src/content-script.ts:10-12, src/background.ts:251
Message Flow
The endpointRuntime module is responsible for creating, handling, and routing messages, while the post-messaging module abstracts the window.postMessage API.
Sources: src/internal/endpoint-runtime.ts, src/internal/post-message.ts
Sending a Message from window to background
When an injected script sends a message, it is first posted to the content script, which then relays it to the background script for routing to the final destination.
This sequence shows the journey of a message from the window context to the background context.
Sources: src/window.ts:9, src/content-script.ts:15-22, src/background.ts:300-305
Receiving a Message in window from background
Messages destined for the window context are first received by the content script, which then posts them to the page.
This sequence illustrates how a message from another extension context is delivered to the injected script.
Sources: src/content-script.ts:10-12, src/window.ts:13-16
API Reference
The API for sending messages and opening streams is consistent across contexts.
| Function | Description | Source Files |
|---|---|---|
sendMessage(id, data, dest) | Sends a one-time message and returns a Promise that resolves with the response. | src/internal/endpoint-runtime.ts:100 |
onMessage(id, callback) | Registers a listener for a specific message ID. | src/internal/endpoint-runtime.ts:127 |
openStream(channel, dest) | Opens a long-lived, namespaced communication channel. | src/internal/stream.ts:140 |
onOpenStreamChannel(channel, cb) | Registers a listener for incoming stream requests on a specific channel. | src/internal/stream.ts:152 |
Error Handling
If a message is sent from the window context but the recipient terminates before replying (e.g., the background service worker is killed), the sendMessage promise in the window will be rejected. This is handled by the content-script, which listens for port failures and forwards an error message back to the window context.
Sources: src/content-script.ts:24-32, src/window.ts:13-15
Summary
The webext-bridge modules for window and content-script provide a robust and necessary abstraction for enabling communication between sandboxed page scripts and the privileged environment of a web extension. By enforcing a namespaced channel via setNamespace and allowWindowMessaging, it ensures that this communication is both secure and isolated. The content script acts as an intelligent and transparent proxy, allowing developers to use the same sendMessage and onMessage API in the window context as they would in any other part of the extension.
Sources: README.md:11, CHANGELOG.md:12-13