Lesson 13 of 15
Tab & Window Visibility
Track when a visitor switches away and returns, via tab visibility (Page Visibility API) and window focus.
① Connect your GTM container
Paste your container ID to load it into this page. It only ever runs here.
Advanced: use a specific environment
Goal
Track when a visitor leaves the page and returns — both when they switch tabs (Page Visibility API) and when they click another window or app (window focus). Push visibility_change with the source and new state.
- Click another window or app and come back (window focus)
Two different APIs: visibilitychange tracks the tab, while window focus/blur tracks the window. The listener covers both, but you can't exercise the tab path here — Tag Assistant opens this lesson in its own tab, so there's no second tab to switch to. Test with the window focus method below; the tab path still fires normally on a real site.
Build it in GTM
Add the visibility listener
GTM has no built-in trigger for this, so a small Custom HTML tag does the listening and pushes its own event. This one script covers two different signals:
- Tab visibility — the Page Visibility API (
visibilitychange/document.visibilityState) fires when the tab is switched away or the window is minimized. - Window focus — the window's
focusandblurevents fire when another window or app comes forward, even while this page stays on screen.
- Go to Tags → New and choose Custom HTML.
- Paste the script below into the HTML field. It pushes
visibility_changewith avisibility_source(taborwindow) plus the current state. - Set its firing trigger to All Pages, name it
Listener - Visibility, and Save.
<script> (function () { window.dataLayer = window.dataLayer || []; function pushVisibility(source) { window.dataLayer.push({ event: 'visibility_change', visibility_source: source, // 'tab' or 'window' page_visible: document.visibilityState === 'visible', // tab on screen? window_focused: document.hasFocus() // window in front? }); } // Tab visibility: switching tabs or minimizing the window. document.addEventListener('visibilitychange', function () { pushVisibility('tab'); }); // Window focus: clicking another window or app, even if this page // stays visible. Lets you test without opening a second tab. window.addEventListener('focus', function () { pushVisibility('window'); }); window.addEventListener('blur', function () { pushVisibility('window'); }); })(); </script>- Tab visibility — the Page Visibility API (
Create the Custom Event trigger
- Go to Triggers → New and choose Custom Event.
- Set Event name to
visibility_change(it must match theeventyou pushed). - Name it
Event - visibility_changeand Save.
Capture the state in variables
Add a Data Layer Variable (a User-Defined variable) for each field you pushed so your tag can report which signal changed and its new state:
- Go to Variables → New (under User-Defined Variables) and choose Data Layer Variable.
- Create
DLV - visibility_source(namevisibility_source),DLV - page_visible(namepage_visible), andDLV - window_focused(namewindow_focused). - Save each one.
Attach a tag
- Go to Tags → New and choose Custom HTML with
<script></script>(or your GA4 Event tag). Name itCustom HTML - Test. - Under Triggering, add
Event - visibility_change. If it's a GA4 tag, sendDLV - visibility_source,DLV - page_visible, andDLV - window_focusedas parameters. Then Save.
- Go to Tags → New and choose Custom HTML with
Debug in Tag Assistant
Open the live version of this lesson, that is the page you point Tag Assistant at. It has the clickable elements next to a live dataLayer, so this page stays clean for reading.
- In your GTM, click Preview.
- Paste the live page URL above and click Connect.
- Interact with the live page and watch your tags fire in Tag Assistant.
What you should expect to see
visibility_change event appears in the timeline and dataLayer with visibility_source set to tab or window, the matching state, and your tag fires.