Hiding Tabs in Firefox with the browser.tabs.hide() API

This article provides a comprehensive overview of how the browser.tabs.hide() WebExtensions API allows developers to hide inactive tabs from the top tab bar in the Firefox Web Browser. It covers the required manifest permissions, the programmatic process of identifying and hiding inactive tabs, the system limitations regarding active or pinned tabs, and how extensions manage the lifecycle of these hidden tabs to create a cleaner browsing interface.

Required Permissions

Before an extension can manipulate the visibility of tabs, it must request the appropriate permissions. In the extension's manifest.json file, developers must include both the tabs and tabHide permissions. The tabHide permission is specific to Firefox and is mandatory for unlocking the ability to remove tabs from the default horizontal tab strip without closing them.

Identifying and Hiding Inactive Tabs

The browser.tabs.hide() API works by accepting either a single tab ID (an integer) or an array of tab IDs. However, the API has a strict built-in rule: it cannot hide the currently active tab.

To hide inactive tabs, a tab management extension follows a standard workflow:

  1. Querying Tabs: The extension uses browser.tabs.query({ active: false, pinned: false }) to retrieve a list of all tabs that the user is not currently looking at and has not pinned.
  2. Extracting IDs: The extension loops through the returned tab objects and extracts their unique id properties into an array.
  3. Executing the Hide Function: The array of IDs is passed into browser.tabs.hide(tabIds).

Once executed, the API immediately removes the specified tabs from the top tab bar, and returns a Promise that resolves to an array containing the IDs of the tabs that were successfully hidden.

System Limitations and Restrictions

Firefox enforces specific boundaries to prevent extensions from disrupting the user experience. Alongside the restriction on hiding the currently active tab, browser.tabs.hide() will also fail to hide tabs that are:

  • Pinned to the tab bar.
  • Currently sharing the screen, microphone, or camera.
  • In the process of being closed.

If an extension passes an array of tab IDs that includes a restricted tab, the API will simply ignore the restricted tab and hide the rest.

Background Behavior and Memory Management

Hiding a tab with browser.tabs.hide() is purely a visual change to the Firefox user interface. The hidden tabs are not closed; their DOM state, running scripts, and active network connections remain fully intact in the background. If a hidden tab starts playing audio, Firefox will display an audio indicator in the browser toolbar so the user isn't confused by the source of the sound.

Because hidden tabs still consume system memory, tab management extensions frequently pair browser.tabs.hide() with browser.tabs.discard(). After hiding the inactive tabs from the top bar, the extension passes the same tab IDs to the discard API, which unloads the web pages from RAM while preserving their existence for when the user wants them back.

Restoring Tabs and User Control

Extensions that hide tabs from the top bar typically provide an alternative user interface, such as a vertical sidebar, to organize the hidden tabs. When a user clicks a hidden tab inside the extension's sidebar, the extension calls browser.tabs.update(tabId, { active: true }) to make it the active tab, or browser.tabs.show(tabIds) to manually return the tab to the top bar. Automatically activating a hidden tab will immediately force it to become visible again on the top bar.

To ensure user security and prevent extensions from maliciously hiding content, Firefox triggers a one-time doorhanger notification the very first time an extension uses browser.tabs.hide(), asking the user to confirm they want to allow the behavior. Furthermore, whenever one or more tabs are hidden, Firefox displays a down-arrow icon on the tab bar that allows users to view and access all hidden tabs natively, ensuring the user never permanently loses their data.