Inject Script Into Pages As Early As Possible With Web Extension Content Script
Tldr
- set
run_at
todocument_start
inmanifest.json
- inject code before
<head>
- set the injected script tag to
async=false
- inject with
scriptTag.textContent='inpage code'
instead of using thesrc=
Background Knowledge Requirement
- know whats web extension
manifest.json
- know whats content script
Main Article
Web extensions can inject js into web pages with content script.
I’m developing a crypto wallet as browser extension like MetaMask.
These kinds of browser extension usually inject JavaScript code into users’ web pages so that the developer of the web page (usually dapp developers) can use them to contact with users’ wallet.
The problem I was facing early this week is how to inject the js as early as possible so that dapp devs can assume the wallet is available when their code loaded.
What I did is:
- set the
run_at
incontent_scripts
inmanifest.json
todocument_start
- use the content script to inject a
<script async=false src="web-extension-xxx/inpage.js></script>"
tag into user’s page before<head>
tag and after<html>
tag.
Since I set async=false
, the script is supposed to be loaded, parsed and executed synchronously. And my injected api methods should be present when the page’s js is executed. The truth I found is, it won’t. Actually, it did work once or twice in 10 refresh.
I then changed the content script to inject the inpage.js content directly with scriptTag.textContent = inpageJSContent
. The tag is now <script async=false>...inpage.js code...</script>
, which requires me to tweak the build process and use mustache
and js-string-escape
to generate the content script file.
And it works.
You can checkout the code:
- the
run_at
in manifest.json - code in content script that inject the script tag
- build script to add the compiled inpage.js string into content script
November 21, 2021 web extension frontend