Resources
What & Link | Type |
---|---|
Chrome - Extension dev overview | Cheatsheet |
Mozilla - WebExtensions API Docs | Docs |
Mozilla - webextension Promise polyfill for Chrome | Package Repo |
Examples
What & Link | Type |
---|---|
Github - browser-extension repos | Collection |
Github - chrome-extension repos | Collection |
Github - firefox-addon repos | Collection |
Passing Data Between Browser Extension
There are many ways to pass data between your browser extension and a given webpage:
Passing Data - Capture results of executeScript
You can use executeScript (mdn, chrome) to run a snippet of JS, and capture values from that scope using the callback argument:
/**
* This is a Chrome specific example:
*/
chrome.tabs.executeScript(
{
code: `const numNodes = document.querySelectorAll('*').length; numNodes;`
},
(numNodes) => {
alert(`there are ${numNodes} nodes in the document`);
}
);
Warning: This method doesn't really work for async results, or results that cannot be
Passing Data - Runtime Message Passing
The Chrome Extension Docs has an entire section devoted to covering this topic. More generic docs can be found in MDN's runtime subsection.
The basic gist is that, runtime messaging is an extremely powerful way to pass messages between:
- Your extension and a webpage
- Your extension and other extensions
- Different scopes within your own extension (e.g. injected
content script
and extension code, such asbackground.js
)
Passing Data - Modifying the DOM
This is a bit of hack, but because the JS scope is not shared between website and extension, but the DOM is (via injected scripts), you can actually use the DOM itself as a kind of shared message space.
For example, to get around the lack of async value capturing in tab.executeScript
, you could write out the result of injected script to a hidden element, and then, after a setTimeout
in the extension, look for and grab the value of that element.
Using React in a Browser Extension
In general, it is not that much different from using React anywhere else, or building a browser extension without React.
The main differences are a few extra bundling / build tools and setup steps to ensure that the output files are properly prepped to match how the corresponding browser (Firefox, Chrome, Brave, etc.) is expecting the extension to be packaged.
Scaffolded / Boilerplate
You can fairly easily set this all up by hand, but if you are looking for a pre-built starting point, here are some I've found:
- https://github.com/jhen0409/react-chrome-extension-boilerplate
- Has full e2e test
- https://github.com/aeksco/react-typescript-web-extension-starter
- https://github.com/kryptokinght/react-extension-boilerplate
- Supports Hot-Reload
- https://github.com/satendra02/react-chrome-extension
Example Extensions:
- Tabliss (Uses React, TypeScript, & Redux)
- Chrome Fast Tab Switcher (Uses React, JS)
- Awesome JSON Viewer (Uses React, JS)
Try searching "react extension" on Github - search link
Further Reading
Testing
- Lever Engineering: End-to-End Testing of an iFrame Chrome Extension using Node Selenium Webdriver
- Gokul Kathirvel: Automate the UI Testing of your Chrome Extension