Skip to content

Commit 64ffeb3

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 customa events if it has added an event listener via `document.currentScript`.
1 parent a52b234 commit 64ffeb3

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-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: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export type ScriptPublicPath = Extract<
1919
export async function injectScript(
2020
path: ScriptPublicPath,
2121
options?: InjectScriptOptions,
22-
): Promise<void> {
22+
): Promise<InjectScriptResult> {
2323
// @ts-expect-error: getURL is defined per-project, but not inside the package
2424
const url = browser.runtime.getURL(path);
2525
const script = document.createElement('script');
@@ -43,6 +43,10 @@ export async function injectScript(
4343
}
4444

4545
await loadedPromise;
46+
47+
return {
48+
script,
49+
};
4650
}
4751

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

0 commit comments

Comments
 (0)