Hey everyone. Welcome to today’s tutorial. In today’s tutorial, we will learn how to create a Context Menu search browser extension (manifest version 3). To create this projects we will use Json and JavaScript. We do not make external libraries and plugins to create this projects.
A browser extension is a small software add-on that runs on your web browser. You can install these by going to your browser's web store. Such as Chrome Web Store or Microsoft Edge Add-ons.
Today's tutorial is not just for beginners, it is for everyone from beginners to advanced. Although today's tutorial is about creating a Context Menu Search extension. The Contact Menu Search extension is a browser add-on(for Chrome, Edge, etc.) that allows users to select text from the browser's contact menu and search for that text in Google or other search engine.
We have already created a browser extension and uploaded it to the chrome webstore. The name of which is "MenuSearch", you can search for it on the chrome webstore if you want. it will give you an idea of how developers create browser extensions. I hope you can learn something from today's tutorial.
let's begin your journey to becoming a browser extension developer. Let's start step by step.
Step: 1 (Project Folder Structure)
Before we start coding let us take a look at the project folder structure. We create a project folder called – ‘Context Menu search’. Inside this folder, we have two files . These files are – manifest.json, and background.js. If you want to know about the structure of proper extensions, you can read this tutorial.
Step: 2 (manifest.json)
We begin with the Json code. First, copy the code below and paste it into your manifest.json. This manifest.json file the main configuration of the browser extension. With the help of this file, the browser understands what the extension does and what permissions it requires. If this file has errors, your extension will never work. If you have created a 128/128 size icon, you can add it like this - "icons":{"128": "128.png"}.
{
"manifest_version": 3,
"name": "context Menu Search",
"short_name": "contextMenus",
"description": "Right-click any text or image to search it directly.",
"version": "0.0.1",
"permissions": [
"storage",
"contextMenus"
],
"background": {
"service_worker": "background.js"
}
}
Step: 5 (background.js)
We begin with the javaScript code. First, copy the code below and paste it into your background.js.
(() => {
"use strict";
const API = typeof chrome !== 'undefined' ? chrome : (typeof browser !== 'undefined' ? browser : null);
const fieldsets = [
{
name: 'Google - Exact match',
url: 'https://www.google.com/search?q="%s"',
},{
name: 'Google - Images',
url: 'https://www.google.com/search?q=%s&tbm=isch',
},{
name: 'Bing',
url: 'https://www.bing.com/search?q=%s',
},{
name: '_separator_',
},{
name: 'Naver (네이버)',
url: 'https://search.naver.com/search.naver?query=%s',
},{
name: 'Baidu (百度)',
url: 'https://www.baidu.com/s?wd=%s',
}
];
const setContextMenuItems = () => {
if (!API || !API.contextMenus) {
console.error("Browser Context Menu API not found. Unable to set menu items.");
return;
}
try {
if (fieldsets.length > 0) {
for (const index in fieldsets) {
const item = fieldsets[index];
if (item && item.name) {
const menuItemProperties = {
id: item.id || String(index), // Use item.id if available, otherwise fallback to index
contexts: ['selection', 'image'], // Contexts where the menu item appears
};
if (item.name === '_separator_') {
menuItemProperties.type = 'separator';
delete menuItemProperties.title; // Separators don't have titles.
console.log(`Creating separator menu item with ID: ${menuItemProperties.id}`);
} else {
menuItemProperties.title = item.name;
console.log(`Creating menu item: "${item.name}" with ID: ${menuItemProperties.id}`);
}
API.contextMenus.create(menuItemProperties);
}
}
console.log('Finished creating new context menu items.');
} else {
console.log('No fieldsets to add to the context menu.');
}
} catch (error) {
console.error("Error setting context menu items:", error);
}
};
const setContextMenuClick = () => {
if (!API || !API.contextMenus) {
console.error("Browser Context Menu API not found. Unable to set menu items.");
return;
}
API.contextMenus.onClicked.addListener(async (info) => {
try {
let targetUrl = fieldsets[info.menuItemId]?.url; // Use optional chaining for safer access
if (!targetUrl) {
console.warn(`No URL found for context menu item with ID: ${info.menuItemId}`);
return;
}
const contentToInject = info.srcUrl || info.selectionText;
// Handle specific URLs (webstore, homepage) by resetting rating status.
if (contentToInject) {
targetUrl = targetUrl.replace('%s', encodeURIComponent(contentToInject));
} else if (targetUrl.includes('%s')) {
targetUrl = targetUrl.replace('%s', '');
}
const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
// Ensure that an active tab was found.
if (!tabs || tabs.length === 0) {
console.error('Error: No active tab found to open a new tab next to.');
return;
}
const currentTab = tabs[0];
const newTab = await chrome.tabs.create({
url: targetUrl,
index: currentTab.index + 1, // Open the new tab immediately after the current one
openerTabId: currentTab.id, // Link the new tab to the current tab as its opener
});
} catch (error) {
console.error("Error fetching settings or handling context menu click:", error);
}
});
};
(async() => {
Promise.all([
await setContextMenuItems(),
await setContextMenuClick(),
]);
})();
})();
JavaScript logic
The logic behind how the above script works is explained. Hopefully, here is a discussion about main logics that you need to know.
setContextMenuItems();
: This function is adding all the names and URLs from the fieldsets list to the contact menu.setContextMenuClick();
: With this function, when you click on the item in the contact menu, the URL of that item will open in a new tab.
How to Use:
- Go to chrome://extensions/
- Enable Developer Mode
- Click Load unpacked and select your Context Menu search/ folder
- Select any text on a webpage → Right-click → Choose "Search 'text' on Google".
That’s it for this tutorial. If you have any queries, suggestions or feedback you can comment below. Happy Coding!
Post a Comment