Work with documentId

A documentId is a UUID string that identifies a unique document loaded in a tab or frame. This guide explains what documentId is, why it is useful, and how to use it in the WebExtension APIs.

Tabs, frames, and documents

A browser tab, identified by a tabId, is the top-level container for web content. Within a tab, content can be structured into multiple frames: the main (outermost) frame, which has a frameId of 0, and any nested <iframe> elements, each with a frameId. As the top frameId is 0, frameId cannot be used to uniquely identify all frames across all tabs.

Each frame holds a document, the HTML page loaded at a URL. The relationship between these three concepts is:

  • A tab contains one or more frames.
  • A frame contains a document.
  • Navigating a frame to a new URL replaces its document but keeps the same frame and, therefore, the same frameId.

This means that the combination of tabId and frameId identifies a frame (a stable browsing context), but not the document loaded in that frame.

Documents and frames are also present in non-tab contexts, including but not limited to:

Operations using tab and frame IDs

Many WebExtension APIs use tabId and frameId to identify where to perform an operation:

Because frameId identifies the frame rather than its content, there is a potential race condition. After your extension has obtained the tabId and frameId, the loaded document may change, so the extension's subsequent operation no longer targets the intended document. documentId was introduced to address this problem.

What is a documentId?

A documentId is assigned to each document when it loads and remains constant throughout the document's lifetime. When a frame navigates to a new URL, it retains its frameId but receives a new documentId. This distinguishes documentId from frameId: a frameId identifies the browsing context (the frame element itself), whereas a documentId identifies the document loaded within it.

The documentId also correctly handles edge cases that frameId cannot distinguish:

  • Navigations: Each new document load, including cross-origin navigations, receives a new documentId even though the frameId is unchanged.
  • Reloads: A page reload creates a new documentId, indicating a fresh document.
  • history.pushState() and fragment updates: These don't create a new document, so the documentId is unchanged.

As it changes with each document load, the ID your extension obtained for a document remains valid only for that document. If the frame has navigated away, the documentId no longer matches. So, if your extension injects a script or sends a message using the documented ID after the navigation, the operation fails rather than silently targeting the wrong document.

When a document is restored from the back/forward cache (bfcache), its original documentId is also restored.

Get a documentId

There are several ways to obtain a documentId:

Using documentId to target documents

When you have a documentId, you can use it to target that document:

APIs supporting documentId

These APIs include documentId support.

Obtain a documentId

documentId in return values and event details

documentId for targeting

Future developments

The WebExtensions Community Group (WECG) is discussing relaxing the requirement to provide tabId alongside documentId when targeting documents. See WECG issue #91 for the discussion.