Adding Items to the Action Icon Menu

Put useful commands in the right-click menu of an MV3 extension's toolbar icon: the action context, Chrome's six-item limit, toggles, quick links to options, per-tab state, and when to use it instead of the popup.

Published October 2, 2026 Updated October 2, 2026 7 min read
Table of Contents

Right-clicking an extension’s toolbar icon shows the browser’s own entries — Options, Remove, Manage — and below them, whatever the extension adds with the action context. Most extensions add nothing, wasting a surface users already reach for when they want a quick command without opening the popup: pause on this site, open the dashboard, toggle a mode, report a problem. The action menu is small and constrained — Chrome shows only a handful of top-level items — but for two or three well-chosen commands it is the fastest UI the extension has. This guide shows how to use it. It belongs to context menus and right-click actions.

What the action context offers

Items created with contexts: ["action"] appear in the menu shown when the user right-clicks the extension’s toolbar icon (and in the extensions menu entry for it). Clicks fire contextMenus.onClicked with the active tab, just like page context menus, and grant activeTab for that tab. Chrome limits the number of top-level items an extension can add to this menu — chrome.contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT is 6 — and items beyond the limit are ignored. Nested items under a parent are allowed. The menu is available whether the action has a popup or not, which makes it a useful complement to a popup: the popup for rich UI, the action menu for one-click commands.

Two surfaces on one toolbar iconLeft-click opens the popup for rich UI; right-click opens the action menu with up to six extension items for one-click commands such as pause on this site, open dashboard and report a problem.Left-clickaction popupPopuprich UI, formsCloses on blurshort taskssame icon, right-clickRight-clickaction context≤ 6 top-level itemsplus browser entriesonClicked + activeTabone-click commands
Left-click for the full UI, right-click for quick commands.

Step-by-step: a useful action menu

1. Choose two to four commands

1action-menu.md
21. Pause on this site        (toggle, per site)          — most frequent quick action
32. Open dashboard            (opens library tab)
43. Keyboard shortcuts…       (opens chrome://extensions/shortcuts)
54. Report a problem          (opens support form with version prefilled)

Execution context: a design note. The best candidates are commands users want without opening any UI, and destinations that are otherwise buried. Avoid duplicating everything in the popup; the action menu should feel like a shortcut list, not a second interface. The browser already provides “Options”, so a separate options item is usually redundant.

2. Create the items with the action context

 1// sw.js
 2chrome.runtime.onInstalled.addListener(createActionMenu);
 3chrome.runtime.onStartup.addListener(createActionMenu);
 4
 5async function createActionMenu() {
 6  await chrome.contextMenus.removeAll();
 7  const items = [
 8    { id: "pause-site",   title: "Pause on this site", type: "checkbox", checked: false },
 9    { id: "dashboard",    title: "Open dashboard" },
10    { id: "shortcuts",    title: "Keyboard shortcuts…" },
11    { id: "report",       title: "Report a problem…" },
12  ];
13  for (const item of items.slice(0, chrome.contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT)) {
14    chrome.contextMenus.create({ ...item, contexts: ["action"] });
15  }
16}

Execution context: the service worker. Slicing to the platform limit makes the code safe if the list grows. If page-context items exist too, create them in the same function — removeAll clears every item the extension owns. Items with contexts: ["action"] appear only on the toolbar icon, never in page menus.

Good and poor action menu itemsCandidate action menu items rated as good or poor fits for the toolbar icon's right-click menu, with the reason for each.ItemFitWhyPause on this siteGoodOne click, frequentOpen dashboardGoodOtherwise buriedKeyboard shortcutsGoodHard to findOptionsRedundantBrowser adds itEvery popup featurePoorDuplicates the popup
Quick, frequent, or hard-to-find — otherwise leave it to the popup.

3. Handle clicks with the active tab

 1chrome.contextMenus.onClicked.addListener(async (info, tab) => {
 2  switch (info.menuItemId) {
 3    case "pause-site":
 4      if (tab?.url) await setSiteOverride(siteKey(tab.url), { enabled: !info.checked });
 5      return;
 6    case "dashboard":
 7      return openOrFocus(chrome.runtime.getURL("library.html"));
 8    case "shortcuts":
 9      return chrome.tabs.create({ url: "chrome://extensions/shortcuts" });
10    case "report": {
11      const v = chrome.runtime.getManifest().version;
12      return chrome.tabs.create({ url: `https://readable.example/support?v=${v}&b=${encodeURIComponent(navigator.userAgent)}` });
13    }
14  }
15});

Execution context: the service worker. The click grants activeTab for the tab the icon belongs to, so the handler can read tab.url and act on it without host permissions. Extensions can open chrome://extensions/shortcuts with tabs.create — the most reliable way to send users to rebind shortcuts. Prefilling the support URL with the version saves a round of questions.

4. Keep the toggle in sync with the active tab

1chrome.tabs.onActivated.addListener(async ({ tabId }) => updatePauseItem(await chrome.tabs.get(tabId)));
2chrome.tabs.onUpdated.addListener((id, change, tab) => { if (change.url && tab.active) updatePauseItem(tab); });
3
4async function updatePauseItem(tab) {
5  const paused = tab?.url ? !(await effectiveSettings(tab.url)).enabled : false;
6  chrome.contextMenus.update("pause-site", { checked: paused, enabled: Boolean(tab?.url?.startsWith("http")) });
7}

Execution context: the service worker. Checked state is global, so a per-site toggle must follow the active tab, as described in checkbox context menu items that reflect state. Disabling the item on browser pages avoids a toggle that cannot do anything.

Pausing from the toolbar iconThe user right-clicks the icon on news.site and chooses Pause on this site; the worker saves the override; the content script on the page tears down; the badge shows a paused state.UserService workerPage (content script)right-click icon → Pause on this sitesave site:news.site {enabled:false}storage.onChangedteardownbadge "II" for this tab
One right-click and one click — no popup needed.

5. Group extra items under a parent

1chrome.contextMenus.create({ id: "more", title: "More", contexts: ["action"] });
2chrome.contextMenus.create({ id: "export", parentId: "more", title: "Export library…", contexts: ["action"] });
3chrome.contextMenus.create({ id: "import", parentId: "more", title: "Import…", contexts: ["action"] });

Execution context: the service worker. Child items do not count against the top-level limit. A “More” submenu keeps the top level short while keeping less frequent commands reachable. Do not nest deeply — one level is plenty.

6. Signal state on the icon too

When the action menu toggles a mode (paused, focus mode), reflect it on the icon with a per-tab badge or title so the user can see the state without opening the menu. See setting the action title and tooltip.

7. Mention the menu once

Users rarely discover right-click menus on toolbar icons. A single line in onboarding — “Right-click the Readable icon for quick actions” — or in the popup footer is enough to make the surface useful.

Common mistakes

  • More than six top-level items. Extras are dropped; use a submenu.
  • Duplicating the browser’s Options entry. Redundant clutter.
  • Global toggles that look per-site. Follow the active tab or label clearly.
  • Commands that need confirmation. Destructive actions belong in UI with confirmation.
  • No discoverability. Tell users the menu exists.

Cross-browser variation

  • Chrome / Edge: action context with ACTION_MENU_TOP_LEVEL_LIMIT of 6.
  • Firefox: supports the action context (browser_action in MV2), with onShown to update items as the menu opens and support for item icons.
  • Safari: support for action-icon menus is limited; test, and fall back to the popup for these commands.

Verification

  1. Right-click the toolbar icon and confirm the items appear below the browser’s own entries.
  2. Use “Pause on this site”, switch tabs and back, and confirm the checkbox reflects each site.
  3. Add a seventh top-level item in a test build and confirm it does not appear.
  4. Confirm “Keyboard shortcuts…” opens the browser’s shortcut page.

FAQ

Do action menu clicks grant activeTab?

Yes, for the tab the icon is shown for.

Can items appear only on certain sites?

Use documentUrlPatterns or toggle visible from tab events. In Firefox, onShown can hide items as the menu opens.

Does the menu work in the extensions puzzle menu?

Yes — the same items appear when the user opens the extension’s menu from the extensions puzzle menu.

What happens to the items if the extension has no popup?

Nothing changes: the action menu works the same way. Without a popup, left-click fires action.onClicked, which pairs well with an action menu — left-click performs the main action, right-click offers the alternatives.

Can I localise the item titles?

Yes. Pass chrome.i18n.getMessage("menu_pause") as the title when creating the items, and recreate them on startup so a changed browser language takes effect. Keep translated titles short; long titles are truncated in the narrow toolbar menu.

Does the action menu work when the extension is unpinned?

Yes. Users reach it from the extensions puzzle menu by opening the extension’s entry, where the same items appear.

Can I use separators in the action menu?

Yes. A type: "separator" item groups related commands, but it counts toward the top-level limit, so use one at most.

Other UI/UX Patterns & Interactive Components Resources