Getting started
Introduction
PageView Tracker is a free, self-hosted analytics tool powered by Upstash Redis. Deploy it once, then embed the tracker on any website with two script tags - no clone or download needed.
- A tracking script to count visits on any website
- An embeddable banner showing online users and total visitors
- A stats dashboard with visitors, pageviews, and top pages (private access)
Quick start
Replace https://your-app.example.com with your deployed URL (e.g. https://tracker.josejavierdiazglez.com). For local development, use http://localhost:3000.
1. Tracking script (invisible)
Drop this in any HTML page to count visits:
<script
src="https://your-app.example.com/script"
data-site="example.com"
data-auto="true"
defer
></script>| Attribute | Required | Description |
|---|---|---|
data-site | Yes | Your site identifier (e.g. example.com) |
data-path | No* | Track a specific path only (precision mode) |
data-auto | No* | Set to "true" to track every page automatically |
data-debug | No | Enable console logging |
*Use either data-path (single page) or data-auto="true" (all pages).
2. Visitor banner (visible)
Add the live stats banner to your site. By default it shows only the counter - no external link:
<script
src="https://your-app.example.com/widget.js"
data-site="example.com"
data-lang="en"
defer
></script>Spanish version:
<script
src="https://your-app.example.com/widget.js"
data-site="example.com"
data-lang="es"
defer
></script>| Attribute | Required | Description |
|---|---|---|
data-site | Yes | Your site identifier |
data-lang | No | en (default) or es |
data-stats | No | Set to "true" to show a "see stats" link |
data-position | No | bottom (default) or top |
Default banner: 1 online · 42 visitors (online hidden when 0)
With data-stats="true": adds · see stats → linking to your dashboard
3. View stats
Open the dashboard at https://your-app.example.com/stats?site=example.com and enter your STATS_SECRET.
Only you can access the dashboard and detailed API. The widget banner still shows online and visitors publicly.
Use in another project
No clone needed. After deploying PageView Tracker once, paste these two lines in any website:
<script src="https://your-app.example.com/script" data-site="my-blog.com" data-auto="true" defer></script>
<script src="https://your-app.example.com/widget.js" data-site="my-blog.com" data-lang="es" defer></script>Each site uses a unique data-site identifier. Data is stored in your Upstash Redis.
To view full stats, go to /stats?site=your-site and sign in with your secret.
API endpoints
Public
Live counters (widget)
GET /api/v1/live?site=example.comResponse: { "online": 2, "visitors": 42 }
Track a visit
GET /api/v1/track?site=example.com&path=/Private (requires STATS_SECRET)
Use the Authorization: Bearer <STATS_SECRET> header or sign in at /stats.
Get page views
GET /api/v1/views?site=example.com&path=/Response: { "views": 123 }
Get stats
GET /api/v1/stats?site=example.com&type=overview
GET /api/v1/stats?site=example.com&type=timeseries
GET /api/v1/stats?site=example.com&type=pagesEnvironment variables
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
# Local: http://localhost:3000
# Production: https://tracker.josejavierdiazglez.com
NEXT_PUBLIC_APP_URL=http://localhost:3000
STATS_SECRET=your-long-secretSet NEXT_PUBLIC_APP_URL to your public URL in production. Scripts automatically use the correct API origin based on where they are served from.
Privacy
- No tracking cookies, no PII stored
- The script generates an anonymous ID (UUID) and stores it in the embedded site's
localStorage; only its SHA-256 hash (16 chars) is stored server-side - If
localStorageis unavailable, a hash of IP + User-Agent is used as fallback - Online = users with the page open (heartbeat every 30s; 2-minute active window)
- Visitors = unique people who have visited the site at least once
- 30-minute deduplication window per page
- Rate limited: 5 requests/min per IP
TABLE OF CONTENTS