Chrome Extension Session Manager — Developer Guide
5 min readBuild a Session Manager Extension
What You’ll Build
A browser session manager that saves/restores window tab states, names sessions, and auto-saves.
Prerequisites
- Tabs API (cross-ref
docs/api-reference/tabs-api.md) - [Storage API](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization) (cross-ref
docs/api-reference/storage-api-deep-dive.md)
Project Structure
session-manager/
manifest.json
background.js
popup/popup.html
popup/popup.js
Step 1: Manifest
{
"manifest_version": 3,
"name": "Session Manager",
"version": "1.0.0",
"permissions": ["tabs", "storage", "alarms"],
"action": { "default_popup": "popup/popup.html" },
"background": { "service_worker": "background.js" }
}
Step 2: Save Session
// background.js - capture all tabs in current window
async function saveSession(name) {
const tabs = await [chrome.tabs](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).query({ currentWindow: true });
const session = {
id: Date.now(),
name,
timestamp: Date.now(),
tabs: tabs.map(t => ({ url: t.url, title: t.title, pinned: t.pinned }))
};
const { sessions = [] } = await [[chrome.storage](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).local.get('sessions');
sessions.unshift(session);
await [[chrome.storage](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).local.set({ sessions });
}
Step 3: Storage Schema
// { sessions: [{ id, name, timestamp, tabs: [{ url, title, pinned }] }] }
Step 4: Popup UI
<input type="text" id="sessionName" placeholder="Session name">
<button id="saveBtn">Save</button>
<div id="sessionList"></div>
Step 5: Restore Session
async function restoreSession(sessionId) {
const { sessions } = await [[chrome.storage](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).local.get('sessions');
const session = sessions.find(s => s.id === sessionId);
for (const tab of session.tabs) {
// Skip restricted pages (chrome://, about:)
if (!tab.url.startsWith('chrome://') && !tab.url.startsWith('about:')) {
await [chrome.tabs](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).create({ url: tab.url, pinned: tab.pinned });
}
}
}
Step 6: Session Naming & Editing
async function renameSession(id, newName) {
const { sessions } = await [[chrome.storage](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).local.get('sessions');
const idx = sessions.findIndex(s => s.id === id);
if (idx !== -1) { sessions[idx].name = newName; await [[chrome.storage](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).local.set({ sessions }); }
}
async function deleteSession(id) {
const { sessions } = await [[chrome.storage](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).local.get('sessions');
await [[chrome.storage](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).local.set({ sessions: sessions.filter(s => s.id !== id) });
}
Step 7: Auto-Save
// background.js
[[chrome.alarms](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).create('autoSave', { periodInMinutes: 5 });
[[chrome.alarms](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).onAlarm.addListener(async (alarm) => {
if (alarm.name === 'autoSave') {
const tabs = await [chrome.tabs](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).query({ currentWindow: true });
const session = { id: Date.now(), name: `Auto ${new Date().toLocaleTimeString()}`,
timestamp: Date.now(), tabs: tabs.map(t => ({ url: t.url, title: t.title })) };
const { sessions = [] } = await [[chrome.storage](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).local.get('sessions');
await [[chrome.storage](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).local.set({ sessions: [session, ...sessions].slice(0, 50) });
}
});
Step 8: Merge & Export/Import
// Merge: add to current window instead of replacing
async function restoreMerge(sessionId) {
const { sessions } = await [[chrome.storage](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization)](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).local.get('sessions');
for (const tab of sessions.find(s => s.id === sessionId).tabs) {
if (!tab.url.startsWith('chrome://')) await [chrome.tabs](https://theluckystrike.github.io/extension-monetization-playbook/monetization/api-monetization).create({ url: tab.url });
}
}
// Export/Import
function exportSessions(sessions) {
const blob = new Blob([JSON.stringify(sessions)], { type: 'application/json' });
const a = document.createElement('a'); a.href = URL.createObjectURL(blob);
a.download = 'sessions.json'; a.click();
}
-e —
Part of the Chrome Extension Guide by theluckystrike. Built at zovo.one.
Turn Your Extension Into a Business
Ready to monetize? The Extension Monetization Playbook covers freemium models, Stripe integration, subscription architecture, and growth strategies for Chrome extension developers.