I have always wanted to build a chrome extension but always thought its pretty daunting and require serious knowledge in javascript, especially when I am not a javascript developer, I always thought manifest file was a big deal. I finally made an attempt and it was pretty easy, I was able to understand the working and built a chrome extension in a few a hours.
Chrome Extensions are tiny software programs that enhance your web browsing experience. They’re like useful little robots ready to assist you whenever you call upon them. Our extension, which we’ll name “Search Highlighter”, is going to be one of these helpful bots. Let’s get started.
Manifest.json
At the heart of every Chrome extension, there’s a file called the Manifest file. They’re like ID cards for Chrome Extensions, telling Google Chrome vital details about the extension. This JSON-formatted file provides important information about the extension to Chrome, such as its name, description, version number, and the permissions it requires. It’s the first file Chrome looks for when loading an extension. In the evolution of Chrome extensions, Google recently introduced Manifest V3, a new version of the Manifest file, bringing significant changes to how extensions work. The update aims to enhance user privacy and security, and to make extensions more performant and powerful. It’s crucial for developers to understand these changes to create efficient, secure, and user-friendly extensions.
Understanding Manifest V3
Manifest V3 introduces several significant changes, including a new permission model and a shift towards a more secure and privacy-preserving extension model. This version marks a move away from background pages, which are now deprecated, and introduces service workers as their replacement.
The V3 update also changes the handling of network requests. Previously, extensions could use the blocking webRequest API to intercept and modify network requests. With V3, this has become observational, and a new API called declarativeNetRequest has been introduced.
In the new version, ‘persistent’ background scripts are replaced with ‘action’ for browser actions and page actions. There’s also a new ‘host_permissions’ feature to streamline permissions, which simplifies the process of requesting access to specific sites.
Finally, Manifest V3 introduces changes to content security policies (CSP), further enhancing the security of Chrome extensions.
Creating a Chrome Extension with Manifest V3
Let’s now walk through the process of creating a Chrome extension using Manifest V3.
Step 1: Start by setting up your development environment. You’ll need a text editor for writing code and a modern version of Google Chrome for testing the extension.
Step 2: Create the Manifest file. This is a JSON file that provides Chrome with information about your extension, such as its name, version, description, and the permissions it requires.
Step 3: Implement a service worker. This is a type of web worker that runs in the background and manages events such as network requests and push notifications.
Step 4: Add a browser action or page action using ‘action’. These actions allow your extension to interact with the current page or browser, respectively.
Step 5: Handle permissions with ‘host_permissions’. This feature streamlines the process of requesting access to specific sites.
Step 6: Implement network requests using the declarativeNetRequest API. This API allows your extension to observe and analyze network requests without having to modify them.
Step 7: Finally, adapt your extension to new content security policies (CSP). These policies help protect your extension from certain types of attacks, such as cross-site scripting (XSS).
Testing and Debugging Your Extension
Once you’ve built your extension, it’s time to test and debug it. Load your extension into Chrome through the Extensions page (chrome://extensions), and enable Developer Mode. From there, you can load your extension for testing.
Use Chrome’s developer tools for debugging. These tools provide a wealth of information about your extension and can help you pinpoint and resolve any issues.
Publishing Your Extension
When you’re satisfied with your extension, you can publish it on the Chrome Web Store. Follow the store’s publishing process and ensure you meet all the requirements.
Remember, if you’reupdating an existing extension from Manifest V2 to V3, you need to be careful not to disrupt your users’ experience. Always thoroughly test the new version before publishing it.
An Example: The “Search Highlighter” Extension
To give you a practical example, let’s consider a simple extension called “Search Highlighter”. This extension allows users to search and highlight words on a webpage.
manifest.json
{
"manifest_version": 3,
"name": "Search Highlighter",
"version": "1.0",
"description": "Highlight words on a webpage",
"permissions": ["tabs", "storage", "scripting"],
"host_permissions": ["<all_urls>"],
"action": {
"default_popup": "popup.html"
},
"icons": {
"16": "icon-16.png",
"48": "icon-48.png",
"128": "icon-128.png"
},
"background": {
"service_worker": "background.js"
}
}
The Manifest file for this extension uses Manifest V3, with permissions for “tabs”, “storage”, “scripting”, and “host_permissions” set to all URLs. It registers a service worker, background.js for background processes and defines a default popup for user interaction. The background script is essentially the extension’s behind-the-scenes worker.
background.js
chrome.runtime.onStartup.addListener(() => {
chrome.scripting.registerContentScript({
id: "content-script",
matches: ["http://*/*", "https://*/*"],
js: [{ file: "content.js" }],
runAt: "document_idle",
});
});
chrome.runtime.onMessage.addListener((message, sender) => {
if (message.message === "word_updated") {
chrome.scripting
.executeScript({
target: { tabId: message.tabId },
files: ["content.js"],
})
.then(() => {
console.log("Script executed successfully");
})
.catch(err => console.error(err));
}
});
In the background script, an event listener is set up to register a content script for the extension when Chrome starts up. Think of the content script as our foot soldier, ready to carry out orders on specific webpages. The background.js script listens for messages from other parts of the extension and when a message with ‘word_updated’ is received, it triggers the content script.
content.js
var word;
function updateWord() {
// remove old highlights
.
.
.
// get new word and apply highlights
chrome.storage.sync.get(['highlight_word'], function(result) {
word = result.highlight_word;
highlightWord(word);
});
}
updateWord();
function highlightWord(word) {
if (!word) return;
const regex = new RegExp(`\\b${word}\\b`, 'gi');
function highlight(node) {
// function to highlight the word
}
highlight(document.body);
}
Speaking of content scripts, let’s talk about ‘content.js’. This script waits for a ‘word_updated’ message. Once received, it swings into action. The old highlights are removed, and then it fetches the new word from storage to highlight it on the webpage. It uses regular expressions (regex) and the Document Object Model (DOM) to find and highlight the selected word.
popup.html
<!doctype html>
<html>
<head>
<style>
/* Add your CSS styles here */
</style>
</head>
<body>
<div class="container">
<input
type="text"
id="word"
name="word"
class="input-field"
autofocus
/><br />
<button id="submit" class="submit-button">Submit</button>
<script src="popup.js"></script>
</div>
</body>
</html>
popup.js
document.getElementById("word").addEventListener("keydown", function (event) {
if (event.key === "Enter") {
submitWord();
}
});
document.getElementById("submit").onclick = submitWord;
function submitWord() {
var word = document.getElementById("word").value;
chrome.storage.sync.set({ highlight_word: word }, function () {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
var activeTab = tabs[0];
chrome.runtime.sendMessage({
message: "word_updated",
tabId: activeTab.id,
});
});
});
}
The popup.html with popup.js script manages user interactions. It captures the word entered by the user and triggers the ‘submitWord’ function when the ‘Enter’ key is pressed or the ‘Submit’ button is clicked. The user-selected word is then stored using chrome.storage.sync.set, and a ‘word_updated’ message is sent to the background script along with the active tab ID.
The complete code can be found on GitHub, here.
Conclusion
- In a nutshell, our “Search Highlighter” extension is a well-coordinated team of scripts. The user enters a word, the popup script sends a message, the background script picks it up, and the content script does the actual highlighting on the webpage.
- Manifest V3 offers several benefits, including improved privacy, enhanced performance, and increased security. It’s crucial for developers to adapt to these changes to create effective Chrome extensions. Despite the challenges and potential roadblocks, the shift to V3 is a positive step towards making Chrome extensions more robust and user-friendly.
- Remember, creating Chrome extensions doesn’t have to be a daunting task. With a clear understanding of Manifest V3 and a step-by-step approach, you can build powerful extensions that enhance the browsing experience for millions of Chrome users worldwide. Happy coding!