BlogGuides
Cookieless page analytics: what you can measure without a consent banner
Views, daily unique visitors, referrers and devices, with nothing stored in the browser. How glokki page analytics works, what it deliberately leaves out, and the two files it takes to set up.
glokki team3 min read

Most cookie banners exist because of analytics. A script sets an identifier in the browser so it can recognise a visitor tomorrow, and storing that identifier is what needs consent. glokki ships a page counter that doesn't store anything in the browser, which is why glokki.com has no banner.
This post covers what it measures, how it gets away without cookies, what it deliberately leaves out, and the setup.
What you get
The Analytics dashboard in the CMS shows, for 7, 30 or 90 days:
- Views: total page views, with a trend chart.
- Unique visitors: distinct visitors, counted per day.
- Referrers: where the traffic came from.
- Devices: desktop, mobile and tablet, worked out on the server from the User-Agent.
There's no separate analytics account and no third-party script tag. If the site renders glokki pages, the data appears as soon as the two pieces below are deployed.
How it works
There are two parts: a component in the page and a route on your own domain.
browser ── POST /_e { path, referrer } ──► your app (same origin)
│ + visitor IP, User-Agent
▼
glokki ingest ──► hash, count, discard IP
The beacon. <PageAnalytics /> from @glokki-cms/react renders
nothing. After the page loads, and on every client-side navigation, it
sends one request with exactly two fields:
JSON.stringify({ path: pathname, referrer: document.referrer || undefined })
It uses navigator.sendBeacon (or a keepalive fetch where that is
missing), so the request never blocks rendering and still goes out if the
visitor clicks away straight after.
The proxy. The beacon doesn't talk to a third-party domain. It posts to
/_e on your own site, a route that createInsightsRoute() from
@glokki-cms/sdk creates. The route holds the API key on the server, adds
the visitor's IP address and User-Agent, and forwards the beacon to glokki.
It replies 204 immediately and ignores upstream errors, so analytics can't
break or slow down a page.
Unique visitors without an identifier. glokki computes a SHA-256 hash of IP + User-Agent with a salt that changes every day. The raw IP is used for that hash and then discarded, not stored. Since the salt changes daily, today's hash can't be matched to yesterday's. That's what "unique per day" means, and why nothing has to be kept in the browser.
Why there is no banner
The consent requirement for cookies (in the EU, the ePrivacy rules) is about
storing or reading information on the visitor's device. This setup does
neither: there are no cookies, nothing in localStorage and no fingerprint
script. You can check glokki.com yourself. Its pages send no Set-Cookie
header, and the analytics request carries only a path and a referrer.
We're not your lawyers, though. An IP address is still personal data while it is being processed, so describe the analytics in your privacy policy, and ask someone qualified if your situation is unusual.
What it doesn't measure
These are choices, not missing features:
- Returning visitors. No identifier survives the day, so "came back on Tuesday" can't be recorded.
- Sessions, funnels and events. It counts page views. It doesn't track clicks, scroll depth or sign-ups.
- Campaign tags. The beacon sends the path without the query string, so
?utm_source=…doesn't reach the stats. The referrer usually tells you enough. For campaign attribution, look where the conversion happens: on glokki.com the sign-up links carry UTM tags, and the sign-up app is the place to count them. - Every last visitor. A same-origin route on a neutral path avoids most blocklists aimed at third-party analytics, but any client-side counting can be blocked. Expect a small undercount. Bots are filtered out in the CMS.
If you need funnels or product analytics, use a tool built for that, and ask for consent. For "which pages do people read and where do they come from", this is enough.
It counts cached pages
glokki.com pages are static and served from the CDN with ISR. Counting on the server would miss every cache hit. The beacon runs in the browser after the HTML arrives, so a page served from the edge counts the same as a fresh render.
It doesn't count you
Editors open a page dozens of times while working on it. Since
@glokki-cms/react 0.10, the beacon does nothing when the page is opened by
the CMS: inside the visual editor (?_editor=1), on the block-template
editor route, and in draft previews (?preview=true). Earlier versions
counted those views, and the referrer pointed at the CMS. If your numbers
look higher than your traffic, check the version first.
On glokki.com we went one step further. <PageAnalytics /> lives in the
component that renders public CMS pages, not in the root layout, so preview
and editor routes never include it.
Setup: two files
The route:
// app/_e/route.ts — use the folder name %5Fe: Next.js treats _e as private
import { createInsightsRoute } from "@glokki-cms/sdk"
export const { POST } = createInsightsRoute({
baseUrl: process.env.CMS_BASE_URL!,
tenantSlug: process.env.CMS_TENANT!,
apiKey: process.env.CMS_API_KEY!, // delivery:read, server-side only
})
The component, rendered once on public pages:
import { PageAnalytics } from "@glokki-cms/react"
// …inside your page or layout
<PageAnalytics />
If you mount the route somewhere other than /_e, pass the same path as
<PageAnalytics endpoint="/your-path" />. The
Page Analytics guide covers IP headers behind
Cloudflare or Fastly, older SDK versions and troubleshooting.
Create a free account and see your traffic without adding a banner.