Content Scripts
CRXJS provides content scripts with Vite HMR, so updates don't always require a full host page reload. In addition, frameworks like React and Vue work in content scripts the same as HTML pages.
The host page of a content script is the website where the content script is running.
Static Assets​
Feel free to import static assets! CRXJS automatically declares imported content
script dependencies as web_accessible_resources
in the manifest.
Use the extension URL​
Content scripts share the origin of the host page, so convert imported static assets to the extension origin using the Chrome API.
import logo from './logo.png'
const url = chrome.runtime.getURL(logo)
HTML in content scripts​
It is possible to inject an extension page into a host page using an iframe. The
host page CSP does not affect the injected iframe even if the host page
specifies the frame-src
policy.
An injected extension page loads inside a cross-origin iframe, so it does not have access to the host page DOM like a content script.
const src = chrome.runtime.getURL('pages/iframe.html')
const iframe = new DOMParser().parseFromString(
`<iframe class="crx" src="${src}"></iframe>`,
).body.firstElementChild
document.body.append(iframe)
Injected extension pages do have access to the full Chrome API, however.
If you load an HTML file from a content script, you need to declare the file as a web-accessible resource.
{
"web_accessible_resources": [
{
"resources": ["pages/iframe.html"],
"matches": ["https://*.google.com/*"]
}
]
}
You will also need to add the HTML file to your Vite config under
build.rollupOptions.input
.
export default defineConfig({
build: {
rollupOptions: {
input: {
welcome: 'pages/iframe.html',
},
},
},
})
Imported HTML​
If you need to render complex HTML in a content script without a framework, an
HTML file can serve as a static fragment by importing it as text using the
?raw
query. This technique does not require the file to be web-accessible, and
you don't need to declare it in the Vite config.
import html from './root.html?raw'
const iframe = new DOMParser().parseFromString(html).body.firstElementChild
iframe.src = chrome.runtime.getURL('pages/iframe.html')
document.body.append(iframe)
Importing an HTML file as text lets you take advantage of IDE language services
for HTML files. Depending on your HTML, this technique may be more concise than
using document.createElement()
.