Build a Powerful Web Browser Side Panel Browser Extension with Manifest V3

Introduction

A few days ago, I launched my new Page Sidebar browser extension, which is available for Google Chrome, Firefox, and Microsoft Edge. The browser extension enables users to open any website in a side panel. And where you can drag anything on the side panel page. Such as a hyperlink or selected text. And instantly show it in the panel. The Page Sidebar browser extension is free and open-source, allowing users and developers to learn how to write such a useful tool for users around the world.

Use the chrome.sidePanel API to host content in the browser’s side panel alongside the main content of a webpage.

Chrome developer documentation page

In this developer article, I delve into my experience with developing Side Panel extensions and the challenges encountered in ensuring compatibility across major web browsers such as Google Chrome, Firefox, and Microsoft Edge. Thereby I will give you an overview of what I have learned. But first how beginner developers like yourself can create high-quality browser extensions with any website content (YouTube, Facebook, Reddit, etc.) in a side panel.

Google Chrome Side Panel open on the Extension Developer Documentation
Google Chrome Side Panel open on the Extension Developer Documentation

Create a Side Panel and Sidebar Browser Extension

Building a side panel presents challenges, especially since each web browser structures the sidebar differently. In Opera and Firefox is it called Sidebar. In Google Chrome, it is referred to as a side panel. Furthermore, the Safari web browser does not currently support this feature, though this status may change in the upcoming Apple WWDC 2024. The developer conference to announce software updates for macOS, iOS, and iPadOS.

Development of your Side Panel

Google Chrome code version

When you want to load a website in the side panel of the Chrome web browser. The first step is to make sure you are using the latest Manifest V3 technology version. That has improvement in performance, privacy, and security. Thereby, to enable the display of all websites in the panel, utilize the “host_permissions” and set it to include all websites.

This is how the “manifest.json” file should look:

Manifest.json

{
  "manifest_version": 3,
  "name": "__MSG_namefull__",
  "short_name": "__MSG_name__",
  "description": "__MSG_description__",
  "version": "1.0.2",
  "background": {
    "service_worker": "scripts/background.js"
  },
  "host_permissions": [ "<all_urls>" ],
  "icons": {
    "16": "images/icon16.png",
    "24": "images/icon24.png",
    "32": "images/icon32.png",
    "48": "images/icon48.png",
    "96": "images/icon96.png",
    "128": "images/icon128.png"
  },
  "default_locale": "en",
  "side_panel": {
    "default_path": "panel.html"
  },
  "action": {
    "default_title": "__MSG_name__"
  },
  "options_ui": {
    "page": "options.html",
    "open_in_tab": true
  },
  "offline_enabled": true,
  "minimum_chrome_version": "114",
  "permissions": ["contextMenus", "storage", "sidePanel", "declarativeNetRequestWithHostAccess"]
}

Note that there is a limit in the Google Chrome web browser, and that is that you can not switch the panel to left or right. There is only the right side to open and close the panel.

Background.js

In the “Background.js” file, utilize this code to ensure that clicking the button will open your side panel.

chrome.sidePanel.setPanelBehavior({openPanelOnActionClick: true}).catch((error) => console.error(error));

Panel.html

Now add a “panel.html” file in your Chrome extension. This iframe element will be used to show any websites in your side panel. That can be a YouTube video, Google News website, X, Reddit, etc.

<iframe id="preview" class="stefanvdpagesidebar" allow="camera; clipboard-write; fullscreen; microphone; geolocation"></iframe>

The “allow” attribute is required to enable access to hardware and allow copying to the clipboard in your iframe web browser for websites such as Google Search, YouTube, Telegram, etc.

Panel.js

Lastly, your “panel.js” script file enables the display of any website. To allow us to see any websites we need to adjust the frame. If we use no chrome.declarativeNetRequest then it results in a blocked website by anchor frame. As you can see in the screenshot here below:

Error message www.google.com refused to connect in the side panel
Error message www.google.com refused to connect in the side panel

Use this code, this code is designed to remove specific security-related headers from the response of network requests made by the browser, particularly affecting iframes with the ID “preview” on any page. This is to bypass certain security restrictions related to framing content from different domains. That is thanks to the powerful chrome.declarativeNetRequest API.

const open = async(currenturl) => {
	const iframe = document.getElementById("preview");
	await chrome.declarativeNetRequest.updateSessionRules({
		removeRuleIds: [1],
		addRules: [{
			id: 1,
			priority: 1,
			action: {
				type: "modifyHeaders",
				responseHeaders: [
					{header: "x-frame-options", operation: "remove"},
					{header: "content-security-policy", operation: "remove"},
				],
			},
			condition: {
				urlFilter: "*",
				resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest", "websocket"],
			},
		},
		],
	});
};

Firefox code version

In Firefox, the sidebar operates differently as it does not require additional permission in the Manifest file. And can contain the same background and panel script files.

Manifest.json

{
  "manifest_version": 3,
  "name": "__MSG_namefull__",
  "short_name": "__MSG_name__",
  "description": "__MSG_description__",
  "version": "1.0.2",
  "background": {
    "scripts": ["scripts/constants.js","scripts/background.js"]
  },
  "host_permissions": [ "*://*/*" ],
  "icons": {
    "16": "images/icon16.png",
    "24": "images/icon24.png",
    "32": "images/icon32.png",
    "48": "images/icon48.png",
    "96": "images/icon96.png",
    "128": "images/icon128.png"
  },
  "default_locale": "en",
  "sidebar_action": {
    "default_icon": {
      "16": "images/icon16.png",
      "32": "images/icon32.png"
    },
    "default_title": "__MSG_name__",
    "default_panel": "panel.html",
    "open_at_install":true
  },
  "action": {
    "default_icon": {
      "16": "images/icon16.png",
      "32": "images/icon32.png"
    },
    "default_title": "__MSG_name__"
  },
  "options_ui": {
    "page": "options.html",
    "open_in_tab": true
  },
  "permissions": ["contextMenus", "storage", "declarativeNetRequestWithHostAccess"],
  "browser_specific_settings": {
    "gecko": {
        "id": "pagesidebar@stefanvd.net",
        "strict_min_version": "113.0"
    }
  }
}

What is useful for the user if they use the Firefox web browser, is that you can choose which side you want the sidebar must be visible. That is on the left or the right side.

Firefox Sidebar to Left or Right
Firefox Sidebar to Left or Right

Access your data for all websites

Here comes the difficulty with Firefox, which differs from Chrome extensions. Firefox does not allow the automatic display of the website content for all websites; it blocks this as default permission (when using the Manifest V3). Users need to manually grant permission on their Add-on page and toggle the switch to enable it.

Firefox Access your data for all websites permission
Firefox Access your data for all websites’ permission

Another option to improve this user experience is to detect it using the browser permission API. Then, when the user clicks on the button of your sidebar extension, prompt them to allow adding "*://*/*". As you can see in the below code example:

browser.permissions.contains({
			origins: ["*://*/*"]
		}, (result) => {
			if(result){
				// The extension has the permissions.
				chrome.tabs.sendMessage(sender.tab.id, {text: "receiveallhost", value: result});
			}else{
				// The extension does not have the permissions
				chrome.tabs.sendMessage(sender.tab.id, {text: "receiveallhost", value: result});
			}
		});

Full Open-Source code

I have developed two Side Panel browser extensions which are presently accessible in the Extension Gallery. Both browser extensions, namely Note Sidebar and Page Sidebar, are freely available and Open-Source. As a developer or user, you have the opportunity to examine the code, initiate the process immediately, and engage in testing and constructing your initial browser extension.

GitHub Browser Extension Code

What browser vendors need to do for users and developers

For Users

  • Google Chrome, should provide an option to choose which side panel can be visible (left and right).
  • Have a pinned shortcut on the side panel, that opens that specific extension panel.
  • The permission “Access your data for all websites” in Firefox should not be disabled for the user. As the user already provided permission during the initial installation to either allow or not allow the installation of this Firefox extension.

For Developers

  • There should be consistent permission requirements for harmony in browser extension development. Currently, one web browser requires permission "sidePanel" to open a side panel, while the other does not.
  • Reduce the code without using the chrome.declarativeNetRequest API

Addition resource

To further explore the Side Panel Manifest V3 and the Sidebar APIs and advance in crafting innovative experiences for users, please refer to the following resources:

Conclusion

I hope you learn something new in this informative guide, particularly in creating a robust Side Panel Chrome extension using Manifest V3, especially for beginner developers. Now that you have acquainted yourself with the Side panel and its limitations across various web browsers. If you like my open work I share this with the browser extension community. And if you would like to support my work in the web community, please consider making a small donation to help drive future initiatives and advancements. Your generosity is greatly appreciated.

About The Author

Stefan Van Damme avatar