Skip to content

React, Vue, and SPAs

Install the snippet once, in your app’s index.html, just before the closing </body>.

Copy your snippet from Pixels. It carries your install tag key and tracking domain.

<script defer src="https://10.vidstats.top/js/p.js?s=YOUR_TAG_KEY"></script>
<!-- Video pages only. Delete this block on pages with no video. -->
<script type="module">
window.webstats('content', {
type: 'movie',
ids: { tmdb: '278' },
title: 'The Shawshank Redemption',
});
</script>

The pixel watches history.pushState and replaceState, so each route change records a pageview automatically. Most apps need nothing else.

Using Next.js? Its <Script> component has its own rules. See Next.js.

Load your app, then navigate to a second route without reloading. Both should appear in your dashboard within seconds.

If only the first one does, your router changes the URL in a way the pixel cannot see. Use the fallback below.

Call webstats('pageview') after your router commits the new URL.

// React Router v6
import { useEffect } from 'react'
import { useLocation } from 'react-router-dom'
function PageviewTracker() {
const location = useLocation()
useEffect(() => {
// The guard matters: your router can fire before the deferred pixel has loaded.
window.webstats && webstats('pageview')
}, [location.pathname])
return null
}
// Vue Router
router.afterEach(() => {
window.webstats && webstats('pageview')
})
// Angular
import { Router, NavigationEnd } from '@angular/router'
router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => {
window['webstats'] && window['webstats']('pageview')
})
// Any router: wrap pushState once
const push = history.pushState.bind(history)
history.pushState = (...args) => {
push(...args)
window.webstats && webstats('pageview')
}

When the title lives in the query string or hash

Section titled “When the title lives in the query string or hash”

On a route like /watch?v=278 or /watch#278 the path never changes, so the pixel sees one long pageview instead of several. Tell it where to look, once, before any other call:

webstats('config', { contentNav: 'query' }) // /watch?v=278
webstats('config', { contentNav: 'fragment' }) // /watch#278

Or set it on the tag, which works even before your code runs:

<script defer
src="https://10.vidstats.top/js/p.js?s=YOUR_TAG_KEY"
data-content-nav="query"></script>

Route data usually arrives after the route renders, so call these when the data is ready rather than on mount:

webstats('content', { type: 'movie', ids: { tmdb: '278' }, title: 'The Shawshank Redemption' })
webstats('video', '#player', { id: 'tmdb-278', title: 'The Shawshank Redemption' })

webstats('video', ...) can be called before the element exists. The pixel applies the name as soon as the player mounts.