Page visibility change events
A page-visibility event comes from the Page Visibility API's visibilitychange event, which fires when a tab becomes hidden or visible. Analytics uses it two ways: to pause engagement timing when a tab is backgrounded, and as the safest moment to flush pending events before a user leaves. It is a browser primitive that underpins reliable measurement, not a GA4 event you name yourself.
What the API provides
The Page Visibility API exposes document.visibilityState and fires visibilitychange when it flips between 'visible' and 'hidden' (MDN). The hidden transition is the most reliable 'page is going away' signal across browsers — more dependable than unload — which is why it is recommended for final sends.
Why analytics relies on it
Engagement time should accrue only while the page is actually visible; pausing on hidden and resuming on visible keeps the figure honest. Separately, browsers may discard a backgrounded tab without firing unload, so flushing pending events on the hidden transition (often with sendBeacon) prevents silent data loss. Both uses are about accuracy, and both rely only on a coarse visible/hidden flag.
- visibilitychange flips between visible and hidden
- Pause engagement timing while hidden
- Flush queued events on hidden, not on unload
How it appears in analytics and logs
Engagement time that keeps climbing while a tab is backgrounded means the tracker is ignoring visibilitychange; lost end-of-visit events often mean it is not flushing on hidden.
Diagnostic use case
Stop counting engagement time while a tab is hidden, and flush queued events on the hidden transition so data is not lost when the user navigates away.
What WebmasterID can help detect
WebmasterID's tracker can use visibilitychange to bound engagement time and to reliably send queued first-party events before the page is discarded.
Common mistakes
- Counting engagement time while the tab is hidden.
- Relying on unload instead of the hidden transition to send.
- Treating visibility as identity rather than a timing state.
Privacy and accuracy notes
visibilitychange exposes only a hidden/visible state, never identity. It is a timing primitive; keep any events you flush on it non-identifying.
Related pages
- Engagement time and the user_engagement event
Engagement time measures how long a page was actually in the foreground and active, recorded through GA4's user_engagement event. It replaces the old, unreliable time-on-page that could not measure the last page of a visit. By only counting time when the tab is visible and focused, engagement time is a more honest attention signal — though still not a guarantee that anyone read anything.
- Idle and active state signals
Idle and active signals separate time a user is actually interacting from time the page is merely open. Analytics derives an active state from recent interaction (clicks, keypresses, scroll) and treats prolonged silence as idle, so engagement time does not inflate. This is a derived concept built from input events and visibility, not a single named GA4 event. It keeps engagement-based metrics meaningful.
- The user_engagement event
user_engagement is the GA4 event that carries active engagement time. The SDK and tag send it periodically — and when the page or app goes to the background — to report how long the user was actively engaged via the engagement_time_msec parameter. It underpins engaged sessions, engagement rate, and average engagement time. It measures attention duration, never who the user is.
- Website observability
Time engagement honestly using visibility state.
Sources and verification notes
Last reviewed 2026-06-24. Facts are checked against primary/official sources where available; uncertain specifics are marked “Data not yet verified” rather than guessed.