Add analytics to Next.js without cookies
One script tag, about 1.2 KB compressed, with no visitor cookies and no build step.
Where the tag goes
App Router: add it to app/layout.tsx with next/script. Pages Router: pages/_document.tsx, inside <Head>.
import Script from 'next/script'
<Script
async
src="https://simplytics.dev/track.js"
data-key="YOUR_SITE_KEY"
strategy="afterInteractive"
/>
Where your key comes from
Swap YOUR_SITE_KEY for your own key, which is on your dashboard beside each site. One key covers the whole site.
Is the key a secret?
No. It is a public identifier that ships in the tag on every page you track. But a tag carrying YOUR_SITE_KEY reports nothing at all, so swap it before you deploy.
Worth knowing on Next.js
- App Router navigations are already counted: since Next.js 14.1, a
<Link>click goes through the History API the tag patches. Do not also fire from ausePathname()/useSearchParams()effect; that double-counts. - The App Router has no
router.eventsorrouteChangeComplete. Guides that hook those were written for the Pages Router. - To keep your own
next devvisits out, render the tag only whenprocess.env.NODE_ENV === 'production'.
Check that it is working
- Deploy, then open any page of your site in a normal browser window.
- Open your dashboard. The visit appears within seconds.
Nothing after 60 seconds?
- Your own ad blocker. Most silently block any script with "analytics" in the path. Try a private window with the blocker off, or open the site on your phone.
- A subdomain.
www.example.comandexample.comare treated as the same site, butblog.example.comis not — add it as its own site. - Not deployed yet. Views from
localhostor a preview URL are refused: the hostname has to match a site on this account. - A Content-Security-Policy. If your site sends one, add
https://simplytics.devto bothscript-srcandconnect-src: the tag loads from there and reports back to it. - Your own browser is opted out. Brave and DuckDuckGo send Global Privacy Control by default, so the tag sends nothing and your visit looks like a broken install. Test in a browser that does not send it, or see the opt-out page.
Single-page navigation
Client-side navigations are counted automatically. Do not fire anything yourself; that double-counts.
Which navigations count, and which do not
Client-side navigations are counted automatically: the tag patches history.pushState, history.replaceState and popstate, and counts again whenever the path changes. Do not fire anything yourself; that double-counts. Changes to only the query string or the # fragment are ignored, so a router that navigates by # alone is not counted automatically.
30 days free, no card. See what it costs after that.
Other platforms: HTML · WordPress · Nuxt · Astro · SvelteKit · Hugo · Ghost · Webflow · Framer · Squarespace · Shopify