{"id":13453377,"url":"https://github.com/benvinegar/counterscale","last_synced_at":"2025-05-14T00:07:27.756Z","repository":{"id":217371431,"uuid":"734549972","full_name":"benvinegar/counterscale","owner":"benvinegar","description":"Scalable web analytics you run yourself on Cloudflare","archived":false,"fork":false,"pushed_at":"2025-04-09T18:54:19.000Z","size":2211,"stargazers_count":1694,"open_issues_count":28,"forks_count":71,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-19T02:13:26.609Z","etag":null,"topics":["analytics","cloudflare-analytics","cloudflare-workers","google-analytics","website-stats"],"latest_commit_sha":null,"homepage":"https://counterscale.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benvinegar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-12-22T01:25:05.000Z","updated_at":"2025-04-17T16:22:56.000Z","dependencies_parsed_at":"2024-04-05T03:31:18.841Z","dependency_job_id":"b7b37820-93d8-48cf-9abf-5d9cfb2b536a","html_url":"https://github.com/benvinegar/counterscale","commit_stats":null,"previous_names":["benvinegar/counterscale"],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benvinegar%2Fcounterscale","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benvinegar%2Fcounterscale/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benvinegar%2Fcounterscale/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benvinegar%2Fcounterscale/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benvinegar","download_url":"https://codeload.github.com/benvinegar/counterscale/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254043766,"owners_count":22005013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","cloudflare-analytics","cloudflare-workers","google-analytics","website-stats"],"created_at":"2024-07-31T08:00:38.993Z","updated_at":"2025-05-14T00:07:27.750Z","avatar_url":"https://github.com/benvinegar.png","language":"TypeScript","funding_links":[],"categories":["网站分析","TypeScript","📊 网站分析","Infrastructure \u0026 Operations"],"sub_categories":["Monitoring \u0026 Observability"],"readme":"# Counterscale\n\n![](/packages/server/public/counterscale-logo-300x300.webp)\n\n![ci status](https://github.com/benvinegar/counterscale/actions/workflows/ci.yaml/badge.svg)\n[![License](https://img.shields.io/github/license/benvinegar/counterscale)](https://github.com/benvinegar/counterscale/blob/master/LICENSE)\n[![codecov](https://codecov.io/gh/benvinegar/counterscale/graph/badge.svg?token=NUHURNB682)](https://codecov.io/gh/benvinegar/counterscale)\n\nCounterscale is a simple web analytics tracker and dashboard that you self-host on Cloudflare.\n\nIt'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](https://developers.cloudflare.com/workers/platform/pricing/#workers) could hypothetically support up to 100k hits/day).\n\n## License\n\nCounterscale is free, open source software made available under the MIT license. See: [LICENSE](LICENSE).\n\n## Limitations\n\nCounterscale is powered primarily by Cloudflare Workers and [Workers Analytics Engine](https://developers.cloudflare.com/analytics/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.\n\n## Installation\n\n### Requirements\n\n* macOS or Linux environment\n* Node v20 or above\n* An active [Cloudflare](https://cloudflare.com) account (either free or paid)\n\n### Cloudflare Preparation\n\nIf you don't have one already, [create a Cloudflare account here](https://dash.cloudflare.com/sign-up) and verify your email address.\n\n1. Go to your Cloudflare dashboard and, if you do not already have one, set up a [Cloudflare Workers subdomain](https://developers.cloudflare.com/workers/configuration/routing/workers-dev/)\n1. Enable [Cloudflare Analytics Engine beta](https://developers.cloudflare.com/analytics/analytics-engine/get-started/) for your account ([screenshot](https://github.com/benvinegar/counterscale/assets/4562878/ad1b5712-2344-4489-a684-685b876635d1))\n    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 \u0026 Pages \u003e Overview, click the \"Create Worker\" button ([screenshot](./docs/create-worker.png)) to create a \"Hello World\" worker (it doesn't matter what you name this Worker as you can delete it later).\n1. Create a [Cloudflare API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/). This token needs `Account.Account Analytics` permissions at a minimum ([screenshot](./docs/api-token.png)).\n    - _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._\n\n### Deploy Counterscale\n\nFirst, sign into Cloudflare and authorize the Cloudflare CLI (Wrangler) using:\n\n```bash\nnpx wrangler login\n```\n\nAfterwards, run the Counterscale installer:\n\n```bash\nnpx @counterscale/cli@latest install\n```\n\nFollow the prompts. You will be asked for the Cloudflare API token you created earlier.\n\nOnce the script has finished, the server application should be deployed. Visit `https://{subdomain-emitted-during-deploy}.workers.dev` to verify.\n\nNOTE: _If this is your first time deploying Counterscale, it may take take a few minutes before the Worker subdomain becomes live._\n\n### Start Recording Web Traffic from Your Website(s)\n\nYou can load the tracking code using one of two methods:\n\n#### 1. Script Loader (CDN)\n\nWhen Counterscale is deployed, it makes `tracker.js` available at the URL you deployed to:\n\n```\nhttps://{subdomain-emitted-during-deploy}.workers.dev/tracker.js\n```\n\nTo start reporting website traffic from your web property, copy/paste the following snippet into your website HTML:\n\n```html\n\u003cscript\n    id=\"counterscale-script\"\n    data-site-id=\"your-unique-site-id\"\n    src=\"https://{subdomain-emitted-during-deploy}.workers.dev/tracker.js\"\n    defer\n\u003e\u003c/script\u003e\n```\n\n#### 2. Package/Module\n\nThe Counterscale tracker is published as an npm module:\n\n```bash\nnpm install @counterscale/tracker\n```\n\nInitialize Counterscale with your site ID and the URL of your deployed reporting endpoint:\n\n```typescript\nimport * as Counterscale from \"@counterscale/tracker\";\n\nCounterscale.init({\n    siteId: \"your-unique-site-id\",\n    reporterUrl: \"https://{subdomain-emitted-during-deploy}.workers.dev/collect\",\n});\n```\n\n## Upgrading\n\nFor most releases, upgrading is as simple as re-running the CLI installer:\n\n```bash\nnpx @counterscale/cli@latest install\n\n# OR\n# npx @counterscale/cli@VERSION install\n```\n\nYou won't have to enter a new API key, and your data will carry forrward.\n\n\nCounterscale uses [semantic versioning](https://semver.org/). If upgrading to a major version (e.g. 2.x, 3.x, 4.x), there may be extra steps. Please consult the [release notes](https://github.com/benvinegar/counterscale/releases).\n\n## Troubleshooting\n\nIf 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 \u0026 Pages → counterscale).\n\n## Advanced\n\n### Manually Track Pageviews\n\nWhen you initialize the Counterscale tracker, set `autoTrackPageviews` to `false`. Then, you can manually call `Counterscale.trackPageview()` when you want to record a pageview.\n\n```typescript\nimport * as Counterscale from \"@counterscale/tracker\";\n\nCounterscale.init({\n    siteId: \"your-unique-site-id\",\n    reporterUrl: \"https://{subdomain-emitted-during-deploy}.workers.dev/collect\",\n    autoTrackPageviews: false, // \u003c- don't forget this\n});\n\n// ... when a pageview happens\nCounterscale.trackPageview();\n```\n\n### Custom Domains\n\nThe deployment URL can always be changed to go behind a custom domain you own. [More here](https://developers.cloudflare.com/workers/configuration/routing/custom-domains/).\n\n## Development\n\nSee [Contributing](CONTRIBUTING.md) for information on how to get started.\n\n## Notes\n\n### Database\n\nThere is only one \"database\": the Cloudflare Analytics Engine dataset, which is communicated entirely over HTTP using Cloudflare's API.\n\nRight now there is no local \"test\" database. This means in local development:\n\n- Writes will no-op (no hits will be recorded)\n- Reads will be read from the production Analaytics Engine dataset (local development shows production data)\n\n### Sampling\n\nCloudflare 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](https://support.google.com/analytics/answer/2637192?hl=en#zippy=%2Cin-this-article)). You can find out more how [sampling works with CF AE here](https://developers.cloudflare.com/analytics/analytics-engine/sampling/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenvinegar%2Fcounterscale","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenvinegar%2Fcounterscale","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenvinegar%2Fcounterscale/lists"}