SPA routes
How Sift follows client-side navigation, and what it ignores.
Single-page apps change the URL without a page load. Sift watches the History API and sends a pageview when the URL actually changes.
What is watched
The script patches three things:
history.pushStatehistory.replaceState- the
popstateevent, which fires on back and forward
The original functions are called first, then Sift compares the current URL with the last one it saw. A pageview is sent only when they differ.
Because the patch is installed once and guarded by a flag, loading the script twice does not produce double pageviews.
The referrer on an SPA
When the URL changes without a reload, the browser's document.referrer still
points at wherever the user came from. Sift sends the previous URL as the
referrer instead, so internal navigation is attributed to the page the visitor
just left rather than the original external source.
Session-level attribution still comes from the first pageview of the session. See How visitors are counted.
Hash changes
example.com/docs#install and example.com/docs#usage are the same page: the
reported pathname is the path, not the hash.
Sift compares the full URL, hash included, so whether a hash change counts depends on how it happens:
- A plain anchor link (
<a href="#install">) does not touch the History API, so nothing is sent. - A router that calls
pushStateorreplaceStatewith a new hash does trigger a pageview, and it lands on the same pathname as the previous one.
If your router pushes hash-only changes and you see inflated pageviews, that is why.
Duplicate URLs
Sift compares the URL with the last one it sent. Repeated calls that set the same URL produce one pageview.
Different URLs each produce a pageview. A router that writes /posts/123 and
then /posts/hello-world for the same screen sends two, and both are stored.
Sift does not retroactively edit stored pageviews, so a URL that is rewritten after the pageview was sent stays as it was.
What is not tracked
- Renders that do not change the URL.
- State changes inside a route, such as opening a modal.
- Scroll position or time on page.
Sift records pageviews, not interactions.