Expose Chrome 150 foreground-tab and tab-strip metadata
Current package version
github.com/chromedp/chromedp v0.16.0
Feature request: expose Chrome 150 foreground-tab and tab-strip metadata
Chrome 150 now exposes authoritative browser-UI tab state through CDP. It would be useful for chromedp to provide a high-level, read-only way to determine:
- which tab is selected in each Chrome window;
- each tab's tab-strip index, pinned state, and group ID;
- the containing Chrome window ID; and
- the relationship between a browser tab and chromedp page target/context(s).
This is especially valuable when attaching to a user-owned browser or sharing a headed browser with a human. chromedp.Targets(ctx) currently enumerates page-like targets; neither its result order nor creation order identifies the tab selected in Chrome's UI.
Why this was not possible before
Historically CDP exposed renderer/page targets but not the embedder's tab-strip state. The usual workarounds are not equivalent:
document.hasFocus(),document.visibilityState, and focus/blur listeners are renderer-level signals.Page.bringToFrontandTarget.activateTargetchange the active tab and can raise the browser window, so they cannot perform a non-disruptive read.Emulation.setFocusEmulationEnabledchanges renderer focus behavior rather than reporting real tab selection.--disable-backgrounding-occluded-windows,--disable-renderer-backgrounding, and--disable-background-timer-throttlingaffect scheduling/rendering, not browser UI state.Page.addScriptToEvaluateOnNewDocumentcan install heuristics, but scripts cannot observe authoritative tab-strip order, pinning, grouping, or window membership.
This is why previous answers correctly focused on explicit activation: #1101, #1291, and #1365 use Target.activateTarget or Page.bringToFront; #1604 uses Target.createTarget(background: true) to avoid initially selecting a new tab. Those APIs solve mutations, not discovery.
Chrome 150 protocol support
Chrome 150 Stable adds Target.TargetInfo.embedderData for targets of type "tab":
infos, err := target.GetTargets().
WithFilter([]*target.FilterEntry{
{Type: "tab", Exclude: false},
{Exclude: true},
}).Do(ctx)The JSON object can contain:
{
"tabStripIndex": 0,
"tabActive": true,
"tabPinned": false,
"tabGroupId": "optional-group-id"
}The current chromedp/cdproto target.Info already includes EmbedderData jsontext.Value, so the raw field is available in the latest generated protocol package. The remaining opportunity is typed parsing and a discoverable chromedp-level API.
Possible shapes could include:
type TabInfo struct {
TargetID target.ID
Active bool
Index int
Pinned bool
GroupID string
WindowID browser.WindowID
Targets []*target.Info
}
tabs, err := chromedp.Tabs(ctx)
tab, err := chromedp.TabInfo(ctx)I do not have a strong preference on the exact API. An incremental implementation could first add a typed helper around target.Info.EmbedderData, followed by a chromedp.Tabs inventory grouped/ordered by Chrome window. Chrome <150 and embedders without the data should return an explicit unavailable result rather than infer it from page order.
Implementation details worth preserving:
- The metadata is on
"tab"targets, not"page"targets. - One tab may contain multiple page targets under Chromium's multi-page architecture.
Target.autoAttachRelatedcan identify related targets; URL matching or a one-tab/one-page assumption is unsafe. Browser.getWindowForTargetreturns the containing Chrome window ID.- The metadata is currently pull-based; metadata-only changes do not generate
Target.targetInfoChangedevents. tabActivemeans selected within its containing Chrome window. Multiple Chrome windows can each have an active tab even though only one native window/app is foreground at the OS level.
References:
- Chromium CL: https://chromium-review.googlesource.com/c/chromium/src/+/7787097
- Chromium issue: https://issues.chromium.org/issues/497896141
- Explanation and end-to-end example: https://www.browserbase.com/blog/cdp-foreground-tab-tracking
- Chrome 150 Stable announcement: https://chromereleases.googleblog.com/2026/06/stable-channel-update-for-desktop_0175352312.html
Related chromedp issues
- #1604 — open a new tab without switching focus (
CreateTarget(...).WithBackground(true)) - #1365 — activate a tab with
Page.bringToFront - #1291 — activate a tab with
Target.activateTarget - #1101 — switch/foreground a tab
- #250 and #228 — early tab-handling and multiple-tab API discussions
- #1309 — concurrent/background work and renderer behavior
- #1019 —
Page.addScriptToEvaluateOnNewDocument
The proposed feature is complementary to all of these. It should not activate a tab, change chromedp's current context semantics, raise an OS window, or change existing focus emulation/background flags. It simply exposes Chrome's real current tab-strip snapshot so applications no longer need to guess or mutate browser state to discover it.
Source: chromedp/chromedp