Chrome Side Panel API: Build a Sidebar Extension (2026) | ExtensionBooster
UI design in Chrome extensions is where most developers struggle. After building several, here's what I've learned about making extensions look good and work well.
The highlights
- Chrome Side Panel API: Build a Sidebar Extension (2026) | ExtensionBooster You’re building a Chrome extension, and a popup feels wrong for it
- Your feature needs to stay open while the user reads a page, takes notes, or navigates between tabs
- Every time the popup closes, the workflow breaks
- You’ve tried injecting a sidebar with a content script, but it keeps fighting with page styles and breaks on half a dozen sites
Here's the thing
Chrome Side Panel API: Build a Sidebar Extension (2026) | ExtensionBooster You’re building a Chrome extension, and a popup feels wrong for it. Your feature needs to stay open while the user reads a page, takes notes, or navigates between tabs. Every time the popup closes, the workflow breaks. You’ve tried injecting a sidebar with a content script, but it keeps fighting with page styles and breaks on half a dozen sites. The Chrome Side Panel API gives your extension a native, persistent sidebar that lives completely outside the page’s DOM. It shipped as a stable API in Chrome 114 (May 2023) and requires Manifest V3. What the Side Panel API Actually Is The Chrome Side Panel API ( chrome. sidePanel ) lets your extension render a full extension page in Chrome’s built-in side panel, the same panel Chrome uses for its own Reading List and Bookmarks features. A few things that make it different from what you’ve probably built before: It’s a full extension page, meaning it has complete access to all Chrome extension APIs. Unlike content scripts, there are no restrictions. It persists across tab navigation. The user can click through 10 different pages and your panel stays open, maintains state, and keeps running. It’s isolated from the host page’s CSS and JS. No style conflicts, no breakage on SPAs that rewrite the DOM. The user controls which side the panel docks on (left or right) in Chrome settings. Your extension doesn’t set that. Manifest Setup: Two Things You Need Getting the side panel working starts with two additions to manifest. Add "sidePanel" to your permissions array, and declare the side_panel key with a default_path. { "manifest_version" : 3 , "name" : "My Side Panel Extension" , "version" : "1. 0" , "permissions" : [ "sidePanel" ], "side_panel" : { "default_path" : "sidepanel. html" }, "background" : { "service_worker" : "background. js" }, "action" : {} } The default_path points to an HTML file at the root of your extension package. That file loads just like any other extension page. Give it its own CSS, its own JS, the works. Key: The "action" key is required in the manifest even if you don’t define a popup. setPanelBehavior won’t wire up the toolbar icon correctly. See the full manifest reference for other keys you might need alongside this. Making the Toolbar Icon Open the Panel By default, clicking your extension’s toolbar icon does nothing unless you define a popup. To make it open the side panel instead, call setPanelBehavior in your service worker: // background. addListener (() => { chrome. setPanelBehavior ({ openPanelOnActionClick: true }); }); That’s it. One call, and clicking the toolbar icon toggles the panel open and closed. You’ll want this in onInstalled so it runs when the extension first loads (and after updates). Per-Tab Panels: Show Different Content Per Site The API shines when you need to show different panels depending on what tab the user is on. The setOptions method accepts an optional tabId. Pass it to scope a panel path (or enable/disable the panel) to a specific tab. js: show a special panel on github. addListener (( tabId , changeInfo , tab ) => { if (changeInfo. == 'complete' ) return ; const isGithub = tab. setOptions ({ tabId, path: isGithub. html' , enabled: true , }); }); Omit tabId entirely to set a global default that applies when no per-tab override is set. The two layers compose cleanly: tab-level settings take priority over the global default. You can also disable the panel for a specific tab (pass enabled: false ). This is useful if your extension only makes sense on certain pages. Opening the Panel Programmatically Sometimes you want to open the panel from code rather than waiting for the user to click the toolbar icon. open() does this, but with one hard constraint: it must be called in direct response to a user gesture. Chrome blocks calls outside a user gesture context. This API is available from Chrome 116+.
💡 Quick tip: Keep popup UI minimal — users close it fast if it's slow to load.
If you build Chrome extensions
You'll eventually need tools for icons, screenshots, MV2→MV3 conversion, and bundle analysis.
ExtensionBooster has free versions of all of these — I keep it bookmarked for every extension project.
Top comments (0)