
I have been learningSvelte. I find it extremely easy to work with. It is lightweight and fast, a suitable option for building small-scaled apps and websites. I've also been learning about how abrowser extension is made. Then I find it a perfect playmate for Svelte, and the learning paths crossed. So today I would like to share my process ofbuilding a complete cross-browser extension with Svelte.
Before reading on, make sure that you're familiar with a browser extension and how to construct one with pure HTML/CSS/JS, and how to work with a front-end library/framework in a NodeJS environment. Otherwise, here are some resources to get you started:
- Chrome Extension - Getting started (Manifest v2)
- Svelte - Getting started
- Build a cross-browser extension
- Extensionizr - Chrome extension structure generator
1. Setup
1.1. Initiate a Svelte project
From the CLI, runnpx degit sveltejs/template my-extension
. This will make a copy of theSvelte template to your machine with the namemy-extension
, and a basic structure as seen in the repository.
1.2. Install dependencies
Runnpm install
to install all necessary dependencies in the template'spackage.json
.
To build a cross-browser extension, thewebextension-polyfill is required. Therefore, runnpm install --save-dev webextension-polyfill
to install it.
2. Prepare the Manifest
Now that we have things ready. Let's create the heart of a browser extension, themanifest.json
.
Createmanifest.json
and place it inside thepublic
folder. A bare minimum content of a manifest is:
{"manifest_version":2,"name":"My Extension","version":"1.0.0",}
And depending on the purpose and functionality of the extension, other fields may be specified. For a complete list of supported fields, refer toChrome's manifest file format.
3. Add functionalities
Silly things that our extension will be capable of:
- Say hello when somebody installs our extension (background page)
- "Hack" the website's background (content script)
- Configure the desired background (popup page)
Now let's dig through.
3.1. Background page
The background page will be loaded whenever the extension is active, and react to the events we set. In our case, the extension reacts "say hello" to the event "somebody installs the extension".
Createbackground.js
inside thesrc
folder and add the following script:
importbrowserfrom"webextension-polyfill";browser.runtime.onInstalled.addListener(({reason})=>{if(reason==="install"){alert("Hello");}});
More about theruntime.onInstalled
event:MDN.
3.2. Content script
The content script has direct access to the current web page. Therefore, it is a perfect solution to "hack the website's background".
Createinjection.js
inside thesrc
folder and add the following script:
importbrowserfrom"webextension-polyfill";constkey="background";browser.storage.local.get(key).then((data)=>{document.body.style=`background: url(${data[key]})`;});
More about thestorage.local
API:MDN.
3.3. Popup page
The popup page is literally the front end of the extension, where users can interact with our extension. In our case, we give users the possibility to "configure the desired background". And this is where Svelte comes into the play.
Removeprops: { name: 'world' }
frommain.js
.
Replace content inApp.svelte
with the following script:
<script>importbrowserfrom"webextension-polyfill";letimage="https://images.unsplash.com/photo-1586074299757-dc655f18518c?fit=crop&w=1268&q=80";functionchange(){browser.storage.local.set({background:image});}</script><main> Image URL:<inputtype="text"bind:value={image}/><buttonon:click={change}>Change</button></main>
3.4. Add to the Manifest
Now modify themanifest.json
we created earlier to include these functionalities:
{..."permissions":["storage"],"background":{"scripts":["build/background.js"],"persistent":false},"browser_action":{"default_popup":"index.html"},"content_scripts":[{"matches":["https://*/*"],"js":["build/injection.js"]}]}
4. Config Rollup and build
The final step involves some configuration for Rollup to generate thebackground.js
andinjection.js
to thebuild
folder, so that the Manifest could recognize.
By default, therollup.config.js
file only outputs themain.js
entry to thebuild
folder under the aliasbundle.js
. To include the other scripts, modify the config as follows:
exportdefault[{input:"src/main.js",...},{input:"src/background.js",output:{sourcemap:true,format:"iife",file:"public/build/background.js",},plugins:[resolve(),commonjs()],watch:{clearScreen:false,},},{input:"src/injection.js",output:{sourcemap:true,format:"iife",file:"public/build/injection.js",},plugins:[resolve(),commonjs()],watch:{clearScreen:false,},},]
This will output multiple entries, including thebackground.js
andinjection.js
to thebuild
folder, and resolve any dependencies in our scripts.
And finally, runnpm run build
to compile our project and everything will be available in thepublic
folder. We may then load our extension in Chrome and see the result:
A complete repo you can find at:https://github.com/khang-nd/browser-extension-svelte
Thank you for reading, and see you in the next post.
Top comments(10)

- Joined
Have you tried building an extension with Astro? It's the hot new kid in town ^^ -astro.build/

- LocationSaskatchewan, Canada
- WorkCabinet maker and hobby programmer.
- Joined
Great article!
A quick question.
Do Svelte apps never stop loading?
I always have to click the X in some browsers to stop them. They continue to work after that.
Here's one that I've been working on:
frac-calc.netlify.app

- LocationHo Chi Minh, Vietnam
- Work💼 Unios / 🏠 Visnalize
- Joined

- LocationOntario, Canada
- WorkIndustrial Designer
- Joined
This is awesome man! Thank you! Would you happen to have any tutorials on the new MV3 for Chrome? The manifest in this tutorial is still on MV2.
Cheers!

- LocationHo Chi Minh, Vietnam
- Work💼 Unios / 🏠 Visnalize
- Joined
I don't have any I'm afraid, but there are some articles about migrating from V2 to V3 from other lovely folks that you might be interested:

Chrome Extensions: Migrating to Manifest v3
Paula Santamaría ・ Mar 26 ・ 7 min read

- Joined
Main gotcha with MV3 is if you plan on supporting Firefox: service workers aren't currently supported in add-ons :(.

- Email
- LocationHisar, Haryana, India
- EducationBachelor of Technology in Information Technology
- PronounsHe/Him
- WorkSenior Software Engineer at Infosys India
- Joined
nice article thanks for sharing, second time I heard of svelte, and I am now curious to check more..
Some comments may only be visible to logged-in visitors.Sign in to view all comments.
For further actions, you may consider blocking this person and/orreporting abuse