Skip to content

philippdubach/cloudcounter

Repository files navigation

CloudCounter

License: EUPL Cloudflare Pages TypeScript Node.js 18+

A standalone port of GoatCounter to run entirely on Cloudflare's edge infrastructure.

CloudCounter brings GoatCounter's privacy-focused analytics to Cloudflare Pages + D1, requiring no external servers or databases. Deploy once and track pageviews across your sites with a single JavaScript snippet.

Features

  • Pageview tracking with session deduplication
  • Top pages, referrers, browsers, operating systems, locations
  • Screen size breakdown
  • Event tracking support
  • Privacy-first: no cookies, session hash only
  • Server-rendered dashboard
  • Data retention policies

Screenshots

Dashboard with bar chart

Dashboard with line chart

Additional screenshots available in the media folder.

Prerequisites

  • Node.js 18+
  • Wrangler CLI
  • Cloudflare account with Pages and D1 access

Quick Start

1. Clone and install

git clone https://github.com/philippdubach/cloudcounter.git
cd cloudcounter
npm install

2. Create Cloudflare resources

# Create D1 database
wrangler d1 create cloudcounter

# Create KV namespace for sessions
wrangler kv namespace create SESSIONS

3. Update wrangler.toml

Edit wrangler.toml and add your database_id and KV namespace id:

[[d1_databases]]
binding = "DB"
database_name = "cloudcounter"
database_id = "YOUR_DATABASE_ID_HERE"

[[kv_namespaces]]
binding = "SESSIONS"
id = "YOUR_KV_NAMESPACE_ID_HERE"

4. Initialize database

wrangler d1 execute cloudcounter --file=./migrations/0001_init.sql

5. Set dashboard password

wrangler secret put DASHBOARD_PASSWORD

6. Deploy

wrangler pages deploy public

7. Add tracking script to your site

<script async src="https://your-analytics.pages.dev/count.js"></script>

Local Development

# Start local dev server
npm run dev

# Apply migrations to local D1
npm run db:migrate:local

Configuration

Environment Variables

Variable Description Default
SITE_NAME Dashboard title "My Analytics"
DATA_RETENTION_DAYS Days to keep data (0 = unlimited) "0"

Secrets

Secret Description
DASHBOARD_PASSWORD Password for dashboard access

Tracking Script

Basic usage

The script auto-tracks pageviews on load:

<script async src="https://your-analytics.pages.dev/count.js"></script>

Manual tracking

// Custom pageview
cloudcounter.count({ path: '/custom-path', title: 'Custom Title' });

// Event tracking
cloudcounter.count({ path: 'button-click', title: 'Sign Up Button', event: true });

Click tracking

Add data-cloudcounter-click attribute to elements:

<button data-cloudcounter-click="signup-btn">Sign Up</button>

Disable tracking

cloudcounter.skip();   // Disable for this session
cloudcounter.enable(); // Re-enable

API

Track pageview

GET/POST /api/count?p=/path&t=Title&r=referrer
Parameter Description Required
p Page path Yes
t Page title No
r Referrer URL No
e Event flag (1 or true) No
s Screen width No

Returns: 1x1 transparent GIF

Architecture

cloudcounter/
├── functions/           # Cloudflare Pages Functions
│   ├── _middleware.ts   # Auth guard
│   ├── _worker.ts       # Cron handler
│   ├── api/count.ts     # Hit tracking endpoint
│   ├── index.ts         # Dashboard
│   ├── login.ts         # Login page
│   └── logout.ts        # Logout
├── src/
│   ├── lib/             # Core utilities
│   └── stats/           # Query functions
├── public/
│   ├── count.js         # Tracking script
│   ├── dashboard.js     # Dashboard charts
│   └── dashboard.css    # Dashboard styles
└── migrations/          # D1 schema

Database Schema

Table Description
paths Normalized page paths
refs Referrer URLs
browsers Browser names
systems Operating systems
hits Raw pageview data
hit_counts Hourly aggregates
hit_stats Daily aggregates
browser_stats Browser breakdown
system_stats OS breakdown
location_stats Country breakdown
size_stats Screen size breakdown

Cron Jobs

Daily at 3 AM UTC:

  • Apply data retention policy
  • Vacuum unused referrers
  • Clean orphaned dimension records

Credits

This project is a port of GoatCounter by Martin Tournoij.

License

Licensed under the EUPL.

About

Privacy-focused web analytics running on Cloudflare Pages + D1. A serverless port of GoatCounter.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors