Vercel Analytics vs Matomo: Five Events, Zero Servers
This site's entire analytics surface is five typed events and one CSP entry. What Matomo's self-hosted depth would actually cost to run instead.
Matomo is a full analytics platform — funnels, heatmaps, session recording, an API — that you self-host or pay Matomo Cloud to run for you. Vercel Web Analytics is a pageview-and-custom-event counter that only works on a Vercel deployment. They aren't really competing for the same job; the choice mostly comes down to whether your site needs Matomo's depth or your event list already fits on one screen.
The short answer
Choose Vercel Web Analytics if you deploy on Vercel, don't want to run infrastructure, and your reporting needs are a handful of named conversion events. Choose Matomo if you need session-level detail (funnels, heatmaps, visitor-level replay), must keep analytics data inside infrastructure you control, or don't deploy on Vercel at all.
The axes that actually diverge
| Vercel Web Analytics | Matomo | |
|---|---|---|
| Infrastructure to run | None — a platform feature | A PHP/MySQL server (self-hosted), or Matomo Cloud |
| Install | npm i @vercel/analytics, one component | A tracking script pointed at your Matomo instance |
| Data depth | Pageviews + typed custom events | Funnels, heatmaps, session recording, goals, A/B testing |
| Data location | Vercel's infrastructure | Your server (self-hosted) or Matomo's cloud |
| Works off Vercel | No | Yes — any host |
| Cookies | None by default | Configurable; cookieless mode available |
| CSP cost | One script-src host, same-origin in production | Your own domain (self-hosted) or Matomo Cloud's host, on both script-src and connect-src |
| Ongoing maintenance | None | Updates, backups, and uptime for the analytics server itself, if self-hosted |
Matomo Cloud narrows that infrastructure gap — Matomo hosts the server for you, for a subscription — but the data-depth and CSP-host tradeoffs in the table above still apply either way, since Cloud is the same tracking script and the same dashboard, just not one you patch yourself.
What this site actually tracks, and why that decides it
The entire analytics surface is one typed union in src/lib/analytics.ts:
type ConversionEvent =
| "preview_opened" // { slug, framework, view? }
| "buy_clicked" // { tier, slug? }
| "waitlist_joined"
| "blog_cta_clicked" // { post, target }
| "wishlist_added"; // { slug }
export function track(
event: ConversionEvent,
props?: Record<string, string | number>,
) {
try {
vercelTrack(event, props);
} catch {
// Analytics must never break UX — swallow any client-side error.
}
}
Five events, each firing at one funnel step, none carrying PII. That list is small on purpose — it answers "did this visitor take the action that matters," not "reconstruct their whole session." Matomo is built for the second question: it can tell you where on the page someone hesitated before clicking, or replay the session that didn't convert. Installing it for five named events would be running a database server to answer a question this site never asks.
Mounting it is the whole client-side footprint:
import { Analytics } from "@vercel/analytics/next";
// …inside <body>, after the app's children:
<Analytics />
No site ID, no account linking — the deployment already knows which project it is. A self-hosted Matomo needs the opposite: your own domain or subdomain, a running instance, and a site ID baked into the tracking script.
The CSP line, and what it hides
This site runs a Content-Security-Policy (next.config.ts), and Vercel Web Analytics costs exactly one entry in it:
script-src 'self' 'unsafe-inline' … https://va.vercel-scripts.com
That single host is the development debug script. In production on Vercel, @vercel/analytics v2 uses what Vercel calls Resilient Intake — the script and event beacon are served from the site's own origin (/_vercel/insights/{script.js,event,view}), already covered by script-src 'self' and connect-src 'self'. No connect-src addition, no third-party beacon host, because there is no third party in production: it's a first-party path built at deploy time.
A self-hosted Matomo needs the true version of what that pattern avoids: your Matomo domain in script-src for the tracking script and in connect-src for the beacon it posts events to — two directives naming infrastructure you now also have to keep running. That's not a mark against Matomo; it's the cost of the thing it buys you, which is a server you fully control instead of a beacon path Vercel operates for you.
Self-hosted Matomo is a second thing to operate
This storefront already runs one backend service — Supabase, and only for the commerce pages (/login, /dashboard, checkout). Every marketing page — /, /templates, /pricing, /blog — is statically generated at build time with nothing behind it at request time. Adding self-hosted Matomo would mean standing up a second service with its own lifecycle: a PHP runtime, a MySQL (or MariaDB) database, scheduled archiving jobs so the dashboard doesn't recompute reports on every page load, version upgrades, and backups of a database that, unlike the rest of this site's content, isn't checked into git and can't be rebuilt from source.
None of that is a knock on Matomo — plenty of teams want exactly that level of control and are willing to run the server for it. It's a mismatch for a site whose entire non-commerce surface is prerendered HTML with no server to speak of, where the honest cost of "just add analytics" should be one dependency and one component, not a second piece of infrastructure to patch.
Where Matomo is the correct answer
- You need visitor-level session replay or heatmaps — Vercel Analytics has neither, by design.
- Your compliance posture requires analytics data to never leave infrastructure you operate.
- You run marketing funnels, goal tracking, or A/B tests that need a dedicated analytics product, not a five-event counter.
- You don't deploy on Vercel, which makes this comparison moot — Vercel Web Analytics simply isn't available off-platform.
And where Vercel Analytics is: a Vercel-hosted site whose entire reporting need is "how many visitors took this specific action," answered without running a server, storing a cookie, or adding a second host to the CSP.
Mistakes and how they show up
| Symptom | Cause | Fix |
|---|---|---|
No events show up after deploying <Analytics /> | Vercel Web Analytics only reports from production Vercel deployments | Check the dashboard against a production URL, not localhost or a preview |
| CSP blocks a self-hosted Matomo's beacon | Only script-src was updated, not connect-src | Add the Matomo host to both directives — the script load and the event POST are separate requests |
track() throws and breaks a click handler | A conversion event fired outside of try/catch | Wrap every call site the way this repo's track() wrapper does — analytics must never break the UI it's measuring |
| Event volume looks wrong halfway through the month | Custom events on Vercel Analytics count against a metered allowance beyond the included tier | Check your plan's event allowance before shipping a high-frequency custom event |
| Matomo dashboard is empty after install | Self-hosted instance isn't reachable from the tracked site, or the site ID is wrong | Verify the tracking script's URL and idsite against the Matomo admin panel |
Frequently asked questions
Can I use both?
Yes — nothing about mounting <Analytics /> conflicts with also loading a Matomo tracker, other than the extra CSP entries and script weight. Some teams run Vercel Analytics for the zero-config baseline and Matomo (or another tool) for deeper funnel work.
Is Vercel Web Analytics cookieless? Yes, by default, which is why this site runs it without a consent banner. Matomo can also run cookieless, but it's a configuration choice, not the default.
Does Matomo cost more than Vercel Analytics? Self-hosted Matomo's software is free; what you pay for is the server it runs on and the time to maintain it. Matomo Cloud is a subscription. Vercel Web Analytics is bundled into your Vercel plan up to an included allowance, then billed per event — check both current pricing pages, since neither is stable enough to quote here.
Does either option track individual visitors across sessions? Not in the configuration this site uses. Vercel Web Analytics is cookieless and aggregates rather than identifying returning visitors by default. Matomo can do visitor-level tracking (that's what session recording requires), but doing so cookieless, without persistent identifiers, is a deliberate configuration choice you have to make — it isn't the out-of-the-box behavior once you enable the features that make Matomo worth self-hosting in the first place.
Why not just use Google Analytics instead of either? That's a real third option, covered in Vercel Analytics vs Google Analytics — GA is cookie-based by default and carries its own consent-banner and CSP cost, which is the axis that ruled it out here.
Templates in this post
ASoc Beacon is a mobile-device-management marketing site covering enrolment, compliance, and remote control. ASoc Beaker is a science-lab services site with pricing built around its capabilities. ASoc Blueprint is an app-development agency site with a project-pricing calculator. Each ships as a static marketing front where a five-event conversion model — not a full analytics platform — is the right amount of measurement to start with.
Browse the full sets: Next.js landing page templates, Tailwind landing page templates.
