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.
Verify
Section titled “Verify”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.
Fallback: record pageviews yourself
Section titled “Fallback: record pageviews yourself”Call webstats('pageview') after your router commits the new URL.
// React Router v6import { 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 Routerrouter.afterEach(() => { window.webstats && webstats('pageview')})// Angularimport { Router, NavigationEnd } from '@angular/router'router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => { window['webstats'] && window['webstats']('pageview')})// Any router: wrap pushState onceconst 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=278webstats('config', { contentNav: 'fragment' }) // /watch#278Or 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>Titles and players on SPA routes
Section titled “Titles and players on SPA routes”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.