Side Panel development patterns for Chrome Extensions covering manifest configuration, chrome.sidePanel API, programmatic control, per-tab vs global panels, lifecycle management, and communication patterns. Use when building side panel features.
View on GitHubfrancanete/fran-marketplace
chrome-extension-expert
chrome-extension-expert/skills/side-panel-development/SKILL.md
January 20, 2026
Select agents to install to:
npx add-skill https://github.com/francanete/fran-marketplace/blob/main/chrome-extension-expert/skills/side-panel-development/SKILL.md -a claude-code --skill side-panel-developmentInstallation paths:
.claude/skills/side-panel-development/# Chrome Extension Side Panel Development
## Overview
Side panels provide a persistent UI alongside web pages, offering richer interaction than popups.
**Key Characteristics:**
- Persistent while browsing (unlike popups)
- Can be per-tab or global
- Requires `sidePanel` permission
- Available in Chrome 114+
---
## Manifest Configuration
### Basic Setup
```json
{
"manifest_version": 3,
"name": "Side Panel Extension",
"version": "1.0.0",
"permissions": ["sidePanel"],
"side_panel": {
"default_path": "sidepanel.html"
},
"action": {
"default_title": "Open Side Panel"
},
"background": {
"service_worker": "background.js"
}
}
```
### Side Panel HTML
```html
<!-- sidepanel.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="sidepanel.css">
</head>
<body>
<div id="app">
<header>
<h1>Side Panel</h1>
</header>
<main id="content">
<!-- Content here -->
</main>
</div>
<script src="sidepanel.js"></script>
</body>
</html>
```
---
## chrome.sidePanel API
### Opening Side Panel
```javascript
// background.js
// Open on action click
chrome.sidePanel.setPanelBehavior({
openPanelOnActionClick: true
});
// Or manually open on click
chrome.action.onClicked.addListener(async (tab) => {
await chrome.sidePanel.open({ tabId: tab.id });
});
// Open for entire window
chrome.action.onClicked.addListener(async (tab) => {
await chrome.sidePanel.open({ windowId: tab.windowId });
});
```
### Setting Panel Options
```javascript
// Set panel for specific tab
await chrome.sidePanel.setOptions({
tabId: tab.id,
path: 'sidepanel.html',
enabled: true
});
// Disable panel for specific tab
await chrome.sidePanel.setOptions({
tabId: tab.id,
enabled: false
});
// Set default panel (all tabs)
await chrome.sidePanel.setOptions({
path: 'sidepanel.html',
enabled: true
});
```
### Getting Panel O