Content scripts have unique requirements in Chrome extensions. CRXJS provides specialized configuration options to handle content script loading, CSS injection, and Hot Module Replacement (HMR).Documentation Index
Fetch the complete documentation index at: https://mintlify.com/crxjs/chrome-extension-tools/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Content script options are configured under thecontentScripts key in your CRXJS configuration:
Configuration Options
preambleCode
Code injected before content scripts execute. Used to set up framework-specific functionality like React Fast Refresh.
Automatic Configuration
When using React with@vitejs/plugin-react, CRXJS automatically detects and applies the React preamble:
CRXJS automatically uses
@vitejs/plugin-react’s preambleCode to enable Fast Refresh in content scripts. No manual configuration needed for React projects.Manual Configuration
Disable Preamble
hmrTimeout
Timeout in milliseconds for establishing HMR WebSocket connections in content scripts.Default:
5000 (5 seconds)When to Adjust
Increase the timeout if:- Your development server starts slowly
- You’re experiencing network latency
- Content scripts are loading before the dev server is ready
How It Works
During development, CRXJS injects an HMR client into content scripts that connects to Vite’s dev server via WebSocket. ThehmrTimeout controls how long the client waits for the connection to establish before timing out.
MAIN World Content Scripts
Content scripts withworld: "MAIN" do not support HMR and will always require a full page reload:
injectCss
Controls how CSS imported by content scripts is handled in the built extension.Default:
trueWhen injectCss: true (default)
CSS is injected into the page via JavaScript at runtime:
- CSS loads immediately with the content script
- No additional web_accessible_resources entries needed
- Simpler manifest configuration
- Small JavaScript overhead for injection
- CSS isn’t cached separately
When injectCss: false
CSS files are emitted separately and added to web_accessible_resources:
injectCss: false:
- Full control over when/how CSS loads
- CSS can be cached separately
- Useful for conditional CSS loading
- Requires manual loading code
- More complex setup
Content Script Types
CRXJS handles three types of content scripts differently:Module Scripts (default)
Standard ES module content scripts:- Supports HMR
- Runs in ISOLATED world by default
- Can use
import/export - Supports dynamic imports
Loader Scripts
When content scripts have imports or dynamic imports, CRXJS automatically creates a loader:- Script has imports
- Script has dynamic imports
- Script exports functions (e.g.,
onExecute)
- Script has no imports
- Script has no dynamic imports
- Script has no exports
MAIN World Scripts
Content scripts that run in the main page context:Dynamic Content Scripts
CRXJS supports dynamically injected content scripts viachrome.scripting.executeScript:
- Added to
web_accessible_resources - Configured with appropriate match patterns
- Bundled with their dependencies
Development vs Production
Development Mode
During development (vite dev):
- All resources loaded from dev server
- HMR enabled (except MAIN world scripts)
- Source maps available
Production Build
During build (vite build):
- All resources bundled and optimized
- No HMR overhead
- Minimal loader code
Complete Example
Troubleshooting
HMR Not Working
- Check console for timeout warnings
- Increase
hmrTimeout - Verify dev server is running
- Check if script uses
world: "MAIN"(not supported)
CSS Not Loading
- With
injectCss: true- CSS should auto-inject - With
injectCss: false- Ensure manual loading code is present - Check
web_accessible_resourcesin built manifest
React Fast Refresh Not Working
- Ensure
@vitejs/plugin-reactis installed - Check that
preambleCodeisn’t set tofalse - Verify React plugin is before CRXJS plugin
See Also
- Plugin Options - All CRXJS configuration options
- Vite Configuration - Vite-specific settings
- Chrome Content Scripts Documentation