Pageviews & SPA Tracking
When data-analytics="pageviews" (or all) is set, the SDK fires a pageview event on every page load. For single-page apps, add spa to capture client-side route changes too.
Initial pageview
Fires once on every fresh page load, after DOMContentLoaded (so document.title is final). Payload:
{
"event_type": "pageview",
"url": "https://example.com/pricing",
"path": "/pricing",
"referrer": "https://news.ycombinator.com/",
"visitor_id": "01HZ7XK4N8...",
"session_id": "01HZ7XK4P2...",
"timestamp": "2026-05-14T10:00:00.000Z",
"custom_props": {
"viewport": "1920x1080",
"title": "Pricing | Acme"
}
} If Loguro.identify() has been called, user_id is also attached.
SPA route changes
Enable with:
<script
src="https://app.logu.ro/loguro.js"
data-api-key="brk_..."
data-analytics="pageviews,spa"
></script> (Or data-analytics="all".)
The SDK monkey-patches history.pushState and history.replaceState, and listens to popstate (browser back/forward). On any of those, a new pageview is queued — debounced 50ms to coalesce burst navigations.
Works out of the box with:
- React Router (
useNavigate,<Link>) - Next.js App Router (
useRouter().push,<Link>) - SvelteKit (
goto,<a href>withdata-sveltekit-preload-data) - Vue Router (
router.push) - Any framework that uses the History API
You don’t need to wire anything up framework-side. The patch on history is universal.
What if my framework uses hashes? (#/about)
popstate fires on hash changes too, so the SDK captures them. path will include the hash (e.g. /#/about).
Manual pageview
For frameworks that don’t use the History API, or for splash-screen / modal flows that should count as a “view”:
window.Loguro.pageview(); // current URL + title
window.Loguro.pageview({ url: '/checkout/step-2' }); // override path
window.Loguro.pageview({ url: '/cart', title: 'Your Cart' }); Time on page
Enable with:
data-analytics-time-on-page="true" Before the next pageview (SPA navigation) or on pagehide, the SDK emits a pageview_end event with the milliseconds since the last pageview started:
{
"event_type": "pageview_end",
"path": "/pricing",
"url": "https://example.com/pricing",
"visitor_id": "01HZ...",
"session_id": "01HZ...",
"timestamp": "2026-05-14T10:01:23.000Z",
"custom_props": { "duration_ms": 83400 }
} Use to compute median time on page, bounce rate, etc.
Scroll depth
Enable with:
data-analytics-scroll="true" The SDK passively listens to scroll events (passive listener — zero perf cost) and tracks the maximum scroll percentage reached. Reported with the pageview_end event:
{
"event_type": "pageview_end",
"custom_props": {
"duration_ms": 83400,
"max_scroll_pct": 67
}
} Useful for content engagement: do readers actually reach the bottom of long-form articles?
Combined recommended setup for a marketing site
<script
src="https://app.logu.ro/loguro.js"
data-api-key="brk_..."
data-analytics="all"
data-analytics-time-on-page="true"
data-analytics-scroll="true"
></script> With this:
- Every page load fires a
pageview - SPA navigations fire a new
pageviewper route - Each page transition or close emits a
pageview_endwithduration_ms+max_scroll_pct - CTAs marked
[data-loguro-event]fire automatically - Web Vitals (LCP, CLS, INP) report once per page
- Long tasks > 50ms are logged as warnings
console.errorand unhandled exceptions still flow into your Loguro logs
Filtering / excluding pages
The SDK doesn’t have a built-in URL exclusion list. If you want to skip tracking on certain routes (admin pages, internal dashboards), wrap your scripts:
<script>
// Only load Loguro on public pages
if (!window.location.pathname.startsWith('/admin')) {
var s = document.createElement('script');
s.src = 'https://app.logu.ro/loguro.js';
s.setAttribute('data-api-key', 'brk_...');
s.setAttribute('data-analytics', 'all');
document.head.appendChild(s);
}
</script> Alternative: Loguro.setEnabled(false) on routes you don’t want tracked, then re-enable elsewhere.