Skip to content

Commit 1162b61

Browse files
committed
feat: Make injectScript return the created script element
It can be used to e.g. send messages to the script in the form of custom events. The script can add an event listener for them via `document.currentScript`.
1 parent a52b234 commit 1162b61

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

docs/guide/essentials/content-scripts.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,37 @@ export default defineUnlistedScript(() => {
614614
});
615615
```
616616

617+
`injectScript` returns the created script element. It can be used to e.g. send messages to the script in the form of custom events. The script can add an event listener for them via `document.currentScript`. An example:
618+
619+
```ts
620+
// entrypoints/example.content.ts
621+
export default defineContentScript({
622+
matches: ['*://*/*'],
623+
async main() {
624+
const { script } = await injectScript('/example-main-world.js');
625+
626+
script.dispatchEvent(
627+
new CustomEvent('greeting', {
628+
detail: 'Hello there',
629+
}),
630+
);
631+
},
632+
});
633+
```
634+
635+
```ts
636+
// entrypoints/example-main-world.ts
637+
export default defineUnlistedScript(() => {
638+
const script = document.currentScript;
639+
640+
script?.addEventListener('greeting', (event) => {
641+
if (event instanceof CustomEvent) {
642+
console.log(event.detail);
643+
}
644+
});
645+
});
646+
```
647+
617648
## Mounting UI to dynamic element
618649

619650
In many cases, you may need to mount a UI to a DOM element that does not exist at the time the web page is initially loaded. To handle this, use the `autoMount` API to automatically mount the UI when the target element appears dynamically and unmount it when the element disappears. In WXT, the `anchor` option is used to target the element, enabling automatic mounting and unmounting based on its appearance and removal.

packages/wxt/src/utils/inject-script.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ export type ScriptPublicPath = Extract<
1515
*
1616
* Make sure to add the injected script to your manifest's
1717
* `web_accessible_resources`.
18+
*
19+
* @returns A result object containing the created script element.
1820
*/
1921
export async function injectScript(
2022
path: ScriptPublicPath,
2123
options?: InjectScriptOptions,
22-
): Promise<void> {
24+
): Promise<InjectScriptResult> {
2325
// @ts-expect-error: getURL is defined per-project, but not inside the package
2426
const url = browser.runtime.getURL(path);
2527
const script = document.createElement('script');
@@ -43,6 +45,10 @@ export async function injectScript(
4345
}
4446

4547
await loadedPromise;
48+
49+
return {
50+
script,
51+
};
4652
}
4753

4854
function makeLoadedPromise(script: HTMLScriptElement): Promise<void> {
@@ -82,3 +88,12 @@ export interface InjectScriptOptions {
8288
*/
8389
modifyScript?: (script: HTMLScriptElement) => Promise<void> | void;
8490
}
91+
92+
export interface InjectScriptResult {
93+
/**
94+
* The created script element. It can be used to e.g. send messages to the
95+
* script in the form of custom events. The script can add an event listener
96+
* for them via `document.currentScript`.
97+
*/
98+
script: HTMLScriptElement;
99+
}

0 commit comments

Comments
 (0)