Chrome Extension Notifications — Developer Guide
4 min readRich Notifications in Chrome Extensions
Introduction
- System-level notifications that appear outside the browser
- Requires
"notifications"permission - Cross-ref:
docs/permissions/notifications.mdfor permission details
manifest.json
{ "permissions": ["notifications"] }
Notification Types
Basic Notification
chrome.notifications.create("my-notif", {
type: "basic",
iconUrl: "icon128.png",
title: "Hello!",
message: "This is a basic notification.",
priority: 2 // -2 to 2
});
Image Notification
chrome.notifications.create("img-notif", {
type: "image",
iconUrl: "icon128.png",
title: "New Photo",
message: "Check out this image",
imageUrl: "preview.png"
});
List Notification
chrome.notifications.create("list-notif", {
type: "list",
iconUrl: "icon128.png",
title: "Tasks Due Today",
message: "3 tasks pending",
items: [
{ title: "Task 1", message: "Fix login bug" },
{ title: "Task 2", message: "Update docs" },
{ title: "Task 3", message: "Deploy v2.0" }
]
});
Progress Notification
chrome.notifications.create("progress-notif", {
type: "progress",
iconUrl: "icon128.png",
title: "Downloading...",
message: "extension-data.zip",
progress: 45 // 0 to 100
});
Notification Options
title: Bold header textmessage: Body texticonUrl: 128x128 icon (required)contextMessage: Additional context textpriority: -2 (low) to 2 (urgent)buttons: Up to 2 action buttons[{ title: "Open" }, { title: "Dismiss" }]requireInteraction: Keep notification visible until user acts (priority 2 only)silent: Suppress notification sound
Event Handling
onClicked — User clicked notification body
chrome.notifications.onClicked.addListener((notificationId) => {
chrome.tabs.create({ url: "https://example.com" });
chrome.notifications.clear(notificationId);
});
onButtonClicked — User clicked an action button
chrome.notifications.onButtonClicked.addListener((notificationId, buttonIndex) => {
if (buttonIndex === 0) openItem();
else dismissItem();
});
onClosed — Notification was dismissed
chrome.notifications.onClosed.addListener((notificationId, byUser) => {
console.log(byUser ? "User dismissed" : "System cleared");
});
Updating Notifications
chrome.notifications.update("progress-notif", {
progress: 75,
message: "75% complete..."
});
- Updates in-place without creating a new notification
Clearing Notifications
chrome.notifications.clear("my-notif");
chrome.notifications.getAll((notifications) => {
Object.keys(notifications).forEach(id => chrome.notifications.clear(id));
});
Common Patterns
Timer/Alarm Notifications
- Use
chrome.alarmsto trigger periodic notifications - Show task reminders, break timers, etc.
- Store notification preferences with
@theluckystrike/webext-storage
Download Progress
- Create progress notification, update as download progresses
- Clear on completion
New Content Alerts
- Background checks for new data (API polling, RSS)
- Notify user of new items
- Click opens relevant tab
Message from Background to User
- Use
@theluckystrike/webext-messagingfor internal communication - Use notifications for user-facing alerts
Best Practices
- Don’t spam — respect user attention
- Use
requireInteractionsparingly — only for urgent items - Always provide a click action (open tab, show popup)
- Use unique
notificationIdstrings — allows update/clear - Clean up old notifications
- Let users control notification frequency via options page
Platform Differences
- Windows: Action Center integration
- macOS: Notification Center (may require system notification permission)
- Linux: Varies by desktop environment
- ChromeOS: Native notification panel
Common Mistakes
iconUrlmust be a local file or data URL — no remote URLs- Forgetting to handle
onClicked— dead-end notifications frustrate users - Creating too many notifications — OS may throttle or user will disable
- Not clearing notifications — stale notifications pile up
Related Articles
Related Articles
Part of the Chrome Extension Guide by theluckystrike. Built at zovo.one.