Adding analytics to a Next.js app without slowing it down
What makes Next.js analytics different
Next.js apps often serve the first page from the server and then handle further navigation in the browser. A plain script tag only runs on a full page load. If you only track full loads, you miss visits that click from one page to another without reloading the document.
That means you need two things in a Next.js project. First, load the analytics script once in the root layout. Second, tell the analytics tool when the route changes after the initial page load.
Load the tracker once in the root layout
In the App Router, put the script in the root layout so it appears on every page. In the Pages Router, add it to _document or _app. Avoid placing it in a component that can remount, because that can load the script more than once.
<script defer src="https://a.measuremy.site/t.js" data-key="YOUR_KEY"></script>
Replace YOUR_KEY with the key from your analytics account. The defer attribute lets the browser keep parsing while the script downloads, and the script runs after the document is parsed.
Do not add the tag inside a client component that re-renders often. A root layout or document is enough. If you use Next.js next/script, check the Next.js documentation for where it belongs and what strategy to use. For a simple hosted tracker, a plain script tag in the layout works.
Track client-side route changes
After the initial pageview, Next.js may update the URL without a full load. You need a small client component that notices pathname and query string changes. In the App Router, that usually means a component using usePathname and useSearchParams. In the Pages Router, you can listen to router events.
The exact function to call depends on your analytics tool. Some tools expose a pageview function. Others let the script observe browser history changes. Check your analytics provider's documentation for its Next.js or single-page app instructions.
The important part is to fire one pageview when the route actually changes, not on every render. Put the component high in the tree, but keep its logic small.
Track custom events and clicks
Pageviews show you which pages get traffic. Custom events show you what people do. For example, a signup button can send an event without writing extra JavaScript:
<button data-measuremysite-event="signup_click">Sign up</button>
This is useful in Next.js because you can add the attribute in a server component and the event fires in the browser. Keep event names stable and readable. Use a consistent style such as signup_click, checkout_started and docs_search. These are easier to group later than names like button1.
Use funnels and UTM tags with Next.js campaigns
Next.js sites often have marketing pages, a signup area and an app area. A funnel can be built from page paths and events: /pricing to /signup to signup_click to /welcome. UTM tags on campaign links still work normally in Next.js. If you use redirects, keep the UTM parameters intact, or use tracked links from your analytics tool so later traffic and signups are credited.
Let a coding agent read the analytics
If you already use Claude Code, Cursor or Codex, an MCP server can read analytics, create funnels and tracked links without you copying numbers into a prompt. For a Next.js project, this is useful when you are already in the repo and want to ask questions like “which page lost the most traffic this week” or “show me the signup funnel for the last seven days.” The agent handles the connection and data reading; you just sign in through your browser.
measuremy.site is a hosted cookieless tracker with an MCP server. You add one script tag and it sets no cookies, uses no local storage, and counts visitors with an anonymous id that changes every day. It stores no personal data. The dashboard shows visitors, pages, sources, countries, browsers and systems.
Check your setup
A short checklist for Next.js analytics:
- Load the script once in the root layout or document.
- Fire a pageview on client-side route changes.
- Use custom events for signups, searches and other actions.
- Keep UTM tags through redirects.
- Check that the script is not loading twice.
For a Next.js app, the main work is loading the tracker once and firing a pageview on route changes. Once that is in place, custom events, funnels and UTM tracking give you a practical view of what people do after the page loads.
See it on your own site
measuremy.site is cookieless analytics your coding agent can read. 30-day free trial, no card. Plans from $9/month.
Start free trial See the live demoAdd measuremy.site analytics to this project: connect the measuremy.site MCP server at https://a.measuremy.site/mcp for all my projects (claude mcp add --scope user; it signs in with OAuth, no key, and one sign-in covers every site), then tell me how to sign in. Details: measuremy.site/llms.txt
Free tools
- Analytics tag checker: Which analytics and pixels a site runs, plus duplicate and broken tags.
- Free UTM link builder: Add utm_source, medium and campaign to any link.
- Website traffic checker: A site's popularity rank and estimated monthly visits.
More from the blog
- How to calculate your website conversion rate, and what to compare it to
- Is my A/B test result significant? A plain-English guide with a worked example
- What is bounce rate, how is it calculated, and is yours a problem?
- How to add a visitor counter to your website or GitHub README
- How much traffic does a website get? How to estimate any site's visits
- How to track QR code scans: count them, and see which poster worked
- How to see how many people clicked your link (without a paid shortener)
- How to check if your Google Analytics 4 tag is installed (and only counting once)
- Why GA4 shows your campaign traffic as Unassigned (and how to fix the links)
- Does your redirect keep your UTM tags? How to check before a campaign goes out
- How I built a self-hosted analytics MCP server on Cloudflare Workers and D1
- UTM tracking explained: what the parameters mean and how to use them
- Conversion funnel analysis for small sites: a practical guide
- Sudden drop in website traffic? A checklist for finding the cause
- What is an MCP server? A plain-English guide for people who run websites
- Core Web Vitals and Traffic: Is There a Link?
- Analytics After Cookies: What Actually Changes
- GDPR and website analytics: a practical guide for small sites
- How to Compare Website Analytics Tools by Privacy
- GA4 Events Explained for Beginners
- How to measure a newsletter send with UTM links
- How to track Hacker News traffic
- Adding Analytics to a Framer Site
- How to ask your coding agent about your analytics
- What Is Bounce Rate and How Is It Calculated?
- A practical website analytics retention policy
- Map your site's funnel from first visit to signup
- What Is a Good Bounce Rate?
- How to automate a weekly traffic report
- A Practical Privacy-Friendly Analytics Checklist
- Adding an MCP server to Claude Code
- How long should you keep analytics data?
- How to Build a Small MCP Server That Actually Helps
- How to Find the Biggest Drop Off in a Funnel
- What Is the Urchin Tracking Module?
- What Microsoft MCP servers actually do
- UTM parameters for email newsletters
- Track Button Clicks Without Google Tag Manager
- How to track the results of a social media post without cookies
- How to track traffic from a GitHub README
- How to measure a product launch without guessing