Skip to content

benvinegar/counterscale

Repository files navigation

Counterscale

ci status License codecov

Counterscale is a simple web analytics tracker and dashboard that you self-host on Cloudflare.

It's designed to be easy to deploy and maintain, and should cost you near-zero to operate – even at high levels of traffic (Cloudflare's free tier could hypothetically support up to 100k hits/day).

License

Counterscale is free, open source software made available under the MIT license. See: LICENSE.

Limitations

Counterscale is powered primarily by Cloudflare Workers and Workers Analytics Engine. As of February 2025, Workers Analytics Engine has maximum 90 days retention, which means Counterscale can only show the last 90 days of recorded data.

Installation

Requirements

  • macOS or Linux environment
  • Node v20 or above
  • An active Cloudflare account (either free or paid)

Cloudflare Preparation

If you don't have one already, create a Cloudflare account here and verify your email address.

  1. Go to your Cloudflare dashboard and, if you do not already have one, set up a Cloudflare Workers subdomain
  2. Enable Cloudflare Analytics Engine beta for your account (screenshot)
    1. If this is your first time using Workers, you have to create a Worker before you can enable the Analytics Engine. Navigate to Workers & Pages > Overview, click the "Create Worker" button (screenshot) to create a "Hello World" worker (it doesn't matter what you name this Worker as you can delete it later).
  3. Create a Cloudflare API token. This token needs Account.Account Analytics permissions at a minimum (screenshot).
    • WARNING: Keep this window open or copy your API token somewhere safe (e.g. a password manager), because if you close this window you will not be able to access this API token again and have to start over.

Deploy Counterscale

First, sign into Cloudflare and authorize the Cloudflare CLI (Wrangler) using:

npx wrangler login

Afterwards, run the Counterscale installer:

npx @counterscale/cli@latest install

Follow the prompts. You will be asked for the Cloudflare API token you created earlier.

Once the script has finished, the server application should be deployed. Visit https://{subdomain-emitted-during-deploy}.workers.dev to verify.

NOTE: If this is your first time deploying Counterscale, it may take take a few minutes before the Worker subdomain becomes live.

Start Recording Web Traffic from Your Website(s)

You can load the tracking code using one of two methods:

1. Script Loader (CDN)

When Counterscale is deployed, it makes tracker.js available at the URL you deployed to:

https://{subdomain-emitted-during-deploy}.workers.dev/tracker.js

To start reporting website traffic from your web property, copy/paste the following snippet into your website HTML:

<script
    id="counterscale-script"
    data-site-id="your-unique-site-id"
    src="https://{subdomain-emitted-during-deploy}.workers.dev/tracker.js"
    defer
></script>

2. Package/Module

The Counterscale tracker is published as an npm module:

npm install @counterscale/tracker

Initialize Counterscale with your site ID and the URL of your deployed reporting endpoint:

import * as Counterscale from "@counterscale/tracker";

Counterscale.init({
    siteId: "your-unique-site-id",
    reporterUrl: "https://{subdomain-emitted-during-deploy}.workers.dev/collect",
});

Troubleshooting

If the website is not immediately available (e.g. "Secure Connection Failed"), it could be because Cloudflare has not yet activated your subdomain (yoursubdomain.workers.dev). This process can take a minute; you can check in on the progress by visiting the newly created worker in your Cloudflare dashboard (Workers & Pages → counterscale).

Advanced

Manually Track Pageviews

When you initialize the Counterscale tracker, set autoTrackPageviews to false. Then, you can manually call Counterscale.trackPageview() when you want to record a pageview.

import * as Counterscale from "@counterscale/tracker";

Counterscale.init({
    siteId: "your-unique-site-id",
    reporterUrl: "https://{subdomain-emitted-during-deploy}.workers.dev/collect",
    autoTrackPageviews: false, // <- don't forget this
});

// ... when a pageview happens
Counterscale.trackPageview();

Custom Domains

The deployment URL can always be changed to go behind a custom domain you own. More here.

Development

See Contributing for information on how to get started.

Notes

Database

There is only one "database": the Cloudflare Analytics Engine dataset, which is communicated entirely over HTTP using Cloudflare's API.

Right now there is no local "test" database. This means in local development:

  • Writes will no-op (no hits will be recorded)
  • Reads will be read from the production Analaytics Engine dataset (local development shows production data)

Sampling

Cloudflare Analytics Engine uses sampling to make high volume data ingestion/querying affordable at scale (this is similar to most other analytics tools, see Google Analytics on Sampling). You can find out more how sampling works with CF AE here.