Skip to content

Commit c4f2c2d

Browse files
committed
feat: Add modifyScript option to injectScript
It enables the modification of the script element just before it is added to the DOM. It can be used to e.g. modify `script.async`/`script.defer`, add event listeners to the element, or pass data to the script via `script.dataset` (which can be accessed by the script via `document.currentScript`).
1 parent 41833c6 commit c4f2c2d

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

docs/guide/essentials/content-scripts.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,29 @@ For MV3, `injectScript` is synchronous and the injected script will be evaluated
591591
However for MV2, `injectScript` has to `fetch` the script's text content and create an inline `<script>` block. This means for MV2, your script is injected asynchronously and it will not be evaluated at the same time as your content script's `run_at`.
592592
:::
593593

594+
The `script` element can be modified just before it is added to the DOM by using the `modifyScript` option. This can be used to e.g. modify `script.async`/`script.defer`, add event listeners to the element, or pass data to the script via `script.dataset`. An example:
595+
596+
```ts
597+
// entrypoints/example.content.ts
598+
export default defineContentScript({
599+
matches: ['*://*/*'],
600+
async main() {
601+
await injectScript('/example-main-world.js', {
602+
manipulateScript(script) {
603+
script.dataset['greeting'] = 'Hello there';
604+
},
605+
});
606+
},
607+
});
608+
```
609+
610+
```ts
611+
// entrypoints/example-main-world.ts
612+
export default defineUnlistedScript(() => {
613+
console.log(document.currentScript?.dataset['greeting']);
614+
});
615+
```
616+
594617
## Mounting UI to dynamic element
595618

596619
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: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export async function injectScript(
3232
script.src = url;
3333
}
3434

35+
await options?.modifyScript?.(script);
36+
3537
(document.head ?? document.documentElement).append(script);
3638

3739
if (!options?.keepInDom) {
@@ -45,4 +47,12 @@ export interface InjectScriptOptions {
4547
* injected. To disable this behavior, set this flag to true.
4648
*/
4749
keepInDom?: boolean;
50+
/**
51+
* Modify the script element just before it is added to the DOM.
52+
*
53+
* It can be used to e.g. modify `script.async`/`script.defer`, add event
54+
* listeners to the element, or pass data to the script via `script.dataset`
55+
* (which can be accessed by the script via `document.currentScript`).
56+
*/
57+
modifyScript?: (script: HTMLScriptElement) => Promise<void> | void;
4858
}

0 commit comments

Comments
 (0)