### Install @counterscale/tracker Source: https://github.com/benvinegar/counterscale/blob/main/packages/tracker/README.md Install the tracker library using npm. This is the first step before initializing the tracker in your project. ```bash npm install @counterscale/tracker ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/benvinegar/counterscale/blob/main/CONTRIBUTING.md Run this command to install all necessary project dependencies using pnpm. ```bash pnpm install ``` -------------------------------- ### Install Counterscale CLI Source: https://github.com/benvinegar/counterscale/blob/main/README.md Run the Counterscale installer script to deploy the server application. This script will prompt for necessary Cloudflare API tokens and configuration details. ```bash npx @counterscale/cli@latest install ``` -------------------------------- ### Install Playwright Browsers Source: https://github.com/benvinegar/counterscale/blob/main/CONTRIBUTING.md Navigate to the tracker package directory and install Playwright browsers. This is necessary for end-to-end testing. ```bash cd packages/tracker && pnpm playwright install ``` -------------------------------- ### Run Development Server (Cloudflare Miniflare) Source: https://github.com/benvinegar/counterscale/blob/main/CONTRIBUTING.md Starts the Cloudflare Miniflare server with a build of the Remix files. This more closely matches the production environment but does not auto-rebuild. ```bash pnpm turbo preview ``` -------------------------------- ### Run Development Server (Node.js) Source: https://github.com/benvinegar/counterscale/blob/main/CONTRIBUTING.md Starts the Vite development server in Node.js. This server supports hot-reloading for faster development cycles. ```bash pnpm turbo dev ``` -------------------------------- ### Browser Client Initialization Source: https://context7.com/benvinegar/counterscale/llms.txt Initializes the browser tracker with basic setup. Automatically tracks pageviews on navigation. ```APIDOC ## init(opts: ClientOpts): void — Initialize the browser tracker Creates a singleton client instance. Automatically begins tracking pageviews unless `autoTrackPageviews` is set to `false`. Subsequent calls to `init` are no-ops if the client already exists. ### Description Initializes the browser tracker with essential configuration like `siteId` and `reporterUrl`. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import * as Counterscale from "@counterscale/tracker"; Counterscale.init({ siteId: "my-blog", reporterUrl: "https://analytics.myworkers.dev/collect", }); if (Counterscale.isInitialized()) { console.log("Tracker is live"); const client = Counterscale.getInitializedClient(); } Counterscale.cleanup(); ``` ### Response None (void function) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Express.js Middleware Example Source: https://github.com/benvinegar/counterscale/blob/main/packages/tracker/SERVER.md Example of integrating Counterscale tracking into an Express.js application using middleware. ```APIDOC ```javascript import express from "express"; import * as Counterscale from "@counterscale/tracker/server"; const app = express(); // Initialize tracker Counterscale.init({ siteId: "your-site-id", reporterUrl: "https://your-analytics-domain.com/collect", }); // Track all requests app.use(async (req, res, next) => { try { await Counterscale.trackPageview({ url: req.originalUrl, hostname: req.get("Host"), referrer: req.get("Referer"), }); } catch (error) { // Tracking errors shouldn't break your app console.error("Tracking error:", error); } next(); }); ``` ``` -------------------------------- ### Install Counterscale CLI to Cloudflare Workers Source: https://context7.com/benvinegar/counterscale/llms.txt Use this command to deploy Counterscale to Cloudflare Workers. It guides you through authentication, `wrangler.json` setup, secret configuration, and deployment. Use `--advanced` for custom worker names and dataset names, and `--verbose` for detailed output. ```bash # Prerequisites: log in to Cloudflare CLI first npx wrangler login # Run the installer (latest release) npx @counterscale/cli@latest install # Advanced mode: customize worker name and dataset npx @counterscale/cli@latest install --advanced # Verbose mode: show internal deployment steps npx @counterscale/cli@latest install --verbose # Upgrade an existing deployment npx @counterscale/cli@latest install # → Re-deploys without prompting for API key if already set # → Data carries forward (Analytics Engine dataset unchanged) ``` -------------------------------- ### npx @counterscale/cli@latest install Source: https://context7.com/benvinegar/counterscale/llms.txt Deploys Counterscale to Cloudflare Workers using an interactive wizard. ```APIDOC ## npx @counterscale/cli@latest install ### Description Deploy to Cloudflare Workers. Interactive wizard that authenticates with Cloudflare, stages a `wrangler.json`, sets Worker secrets, and runs `wrangler deploy`. Supports `--advanced` to customize worker name and analytics dataset name; `--verbose` for detailed output. ### Method `install` ### Endpoint `npx @counterscale/cli@latest install` ### Parameters #### Path Parameters None #### Query Parameters - **--advanced** (flag) - Optional - Customize worker name and analytics dataset name. - **--verbose** (flag) - Optional - Show detailed output. ### Request Example ```bash npx @counterscale/cli@latest install npx @counterscale/cli@latest install --advanced npx @counterscale/cli@latest install --verbose ``` ### Response #### Success Response Deployment to Cloudflare Workers is successful. ``` -------------------------------- ### Standard ESLint Configuration Source: https://github.com/benvinegar/counterscale/blob/main/packages/eslint-config/README.md Use this for a straightforward setup of ESLint. It requires specifying the base directory and can be configured for React and TypeScript projects, along with custom global variables. ```javascript import { createConfig } from "@counterscale/eslint-config"; import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); export default createConfig({ baseDirectory: __dirname, ignores: [ "build/*", "node_modules", "dist/*", // Add any package-specific ignores ], // Configure based on package type includeReact: true, // Set to true for React packages includeTypeScript: true, // Set to true for TypeScript packages tsconfigRootDir: "./", project: "./tsconfig.json", // Path to your tsconfig.json additionalGlobals: { // Add any package-specific globals counterscale: true, }, }); ``` -------------------------------- ### Express.js Middleware for Tracking Source: https://github.com/benvinegar/counterscale/blob/main/packages/tracker/SERVER.md Integrate server-side tracking into an Express.js application using middleware. This example tracks all incoming requests, capturing URL, hostname, and referrer. ```javascript import express from "express"; import * as Counterscale from "@counterscale/tracker/server"; const app = express(); // Initialize tracker Counterscale.init({ siteId: "your-site-id", reporterUrl: "https://your-analytics-domain.com/collect", }); // Track all requests app.use(async (req, res, next) => { try { await Counterscale.trackPageview({ url: req.originalUrl, hostname: req.get("Host"), referrer: req.get("Referer"), }); } catch (error) { // Tracking errors shouldn't break your app console.error("Tracking error:", error); } next(); }); ``` -------------------------------- ### HTML Script Tag Embed Source: https://context7.com/benvinegar/counterscale/llms.txt Embeds the Counterscale tracker directly into an HTML page using a script tag for a zero-dependency setup. ```APIDOC ## HTML script tag embed — CDN / no-build setup The server serves `tracker.js` as a static asset. Embed it directly in HTML for zero-dependency tracking. The `data-site-id` attribute replaces the programmatic `siteId` option. ### Description Provides instructions for embedding the Counterscale tracker via a CDN script tag, simplifying integration without a build process. ### Parameters None ### Request Example ```html ``` ### Response None (This is an embeddable script) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Get Top Pages by Visitor Count Source: https://context7.com/benvinegar/counterscale/llms.txt Returns a list of pages ranked by visitor count, along with their respective visitor and view counts. Data is sorted in descending order of visitors. ```typescript const topPages = await ae.getCountByPath("my-blog", "30d", "UTC", {}, 1); // → [ // ["/", 1820, 4301], // ["/blog/post-1", 412, 890], // ["/about", 204, 320], // ] ``` -------------------------------- ### Embed Counterscale Tracking Script Source: https://github.com/benvinegar/counterscale/blob/main/README.md Include this HTML snippet in your website's code to start reporting traffic to your Counterscale deployment. Ensure the `data-site-id` is unique for each website and the `src` URL points to your deployed Counterscale worker. ```html ``` -------------------------------- ### Get Visitor Counts by Referrer, Country, Browser, and Device Type Source: https://context7.com/benvinegar/counterscale/llms.txt Use these functions to retrieve top N results for specific dimensions. They share a common signature and return arrays of dimension-visitor/view counts. ```typescript const referrers = await ae.getCountByReferrer("my-blog", "7d", "UTC", {}, 1); // → [["https://news.ycombinator.com", 510, 620], ["https://google.com", 300, 380]] ``` ```typescript // Country breakdown: [country, visitors][] const countries = await ae.getCountByCountry("my-blog", "7d"); // → [["US", 1200], ["GB", 340], ["DE", 210]] ``` ```typescript // Browser breakdown const browsers = await ae.getCountByBrowser("my-blog", "30d"); // → [["Chrome", 2100], ["Safari", 980], ["Firefox", 340]] ``` ```typescript // Device type const devices = await ae.getCountByDeviceType("my-blog", "30d"); // → [["desktop", 2800], ["mobile", 1400], ["tablet", 120]] ``` -------------------------------- ### Get Sites Ordered by Hits Source: https://context7.com/benvinegar/counterscale/llms.txt This function lists all site IDs tracked in the dataset, ordered by total hit count. It's useful for multi-site deployments and accepts an interval and an optional limit. ```typescript const sites = await ae.getSitesOrderedByHits("1d", 5); // → [ // ["marketing-site", 4800], // ["docs-site", 920], // ["blog", 540], // ] ``` -------------------------------- ### collectRequestHandler Source: https://context7.com/benvinegar/counterscale/llms.txt Ingests a pageview hit by processing query parameters from a GET request, resolving session state, parsing the user agent, and writing data to the Cloudflare Analytics Engine. It returns a 1x1 transparent GIF. ```APIDOC ## collectRequestHandler(request, env, extra) — Ingest a pageview hit ### Description The core data ingestion function. Reads query parameters from a pixel GET request, resolves cookieless session state from `If-Modified-Since` / `Last-Modified` headers (or an explicit `ht` hit-type param), parses the user agent, and writes a data point to the Cloudflare Analytics Engine binding (`WEB_COUNTER_AE`). Returns a 1x1 transparent GIF. ### Query String Parameters - **sid** (string) - Required - Site ID - **h** (string) - Optional - Hostname - **p** (string) - Optional - Path - **r** (string) - Optional - Referrer - **ht** (integer) - Optional - Hit type (1=new visit, 2=anti-bounce, 3=repeat hit) - **us** (string) - Optional - UTM Source - **um** (string) - Optional - UTM Medium - **uc** (string) - Optional - UTM Campaign - **ut** (string) - Optional - UTM Term - **uco** (string) - Optional - UTM Content ### Request Example (Tracker) ``` GET /collect?sid=my-blog&h=example.com&p=/post-1&r=https://google.com&us=organic Headers: If-Modified-Since: Mon, 13 Jan 2025 00:00:01 GMT ← session cookie substitute ``` ### Response Example ``` HTTP/2 200 Content-Type: image/gif Last-Modified: Mon, 13 Jan 2025 00:00:02 GMT ← increments hit count ``` ### Direct curl test (new visit, no prior session): ```bash curl -s -o /dev/null -D - \ "https://analytics.myworkers.dev/collect?sid=test-site&h=example.com&p=/test&r=" ``` ### Direct curl test response: ``` HTTP/2 200 content-type: image/gif last-modified: Mon, 13 Jan 2025 00:00:01 GMT tk: N ``` ``` -------------------------------- ### Track Server-Side Pageviews with Express Middleware Source: https://context7.com/benvinegar/counterscale/llms.txt Integrate this middleware into your Express application to automatically track pageviews for every incoming GET request. UTM parameters are extracted from the URL, but explicit parameters will override them. Errors are handled internally and do not throw exceptions. ```typescript import express from "express"; import * as Counterscale from "@counterscale/tracker/server"; const app = express(); Counterscale.init({ siteId: "my-ssr-app", reporterUrl: "https://analytics.myworkers.dev/collect", }); // Middleware: track every incoming GET request app.use(async (req, res, next) => { // Non-blocking — errors are swallowed internally void Counterscale.trackPageview({ url: req.originalUrl, // e.g. "/products/widget?utm_source=email" hostname: req.hostname, // required when url is relative referrer: req.get("Referer"), // optional // UTM params can be passed explicitly or extracted from url automatically utmSource: "email", utmMedium: "newsletter", utmCampaign: "spring-sale", utmTerm: "widget", utmContent: "header-cta", }); next(); }); // Expected: fires POST to /collect with all UTM + path data; never throws ``` -------------------------------- ### Ingest Pageview Hit with collectRequestHandler Source: https://context7.com/benvinegar/counterscale/llms.txt The core data ingestion function. Reads query parameters from a pixel GET request, resolves cookieless session state, parses the user agent, and writes a data point to the Cloudflare Analytics Engine binding. Returns a 1x1 transparent GIF. ```typescript // Query string parameters understood by /collect: // sid = site ID (required) // h = hostname // p = path // r = referrer // ht = hit type (1=new visit, 2=anti-bounce, 3=repeat hit) // us = utm_source // um = utm_medium // uc = utm_campaign // ut = utm_term // uco = utm_content // Example raw request (sent automatically by the tracker): // GET /collect?sid=my-blog&h=example.com&p=/post-1&r=https://google.com&us=organic // Headers: // If-Modified-Since: Mon, 13 Jan 2025 00:00:01 GMT ← session cookie substitute // Response: // 200 OK Content-Type: image/gif // Last-Modified: Mon, 13 Jan 2025 00:00:02 GMT ← increments hit count // Direct curl test (new visit, no prior session): curl -s -o /dev/null -D - \ "https://analytics.myworkers.dev/collect?sid=test-site&h=example.com&p=/test&r=" # HTTP/2 200 # content-type: image/gif # last-modified: Mon, 13 Jan 2025 00:00:01 GMT # tk: N ``` -------------------------------- ### Initialization Source: https://github.com/benvinegar/counterscale/blob/main/packages/tracker/SERVER.md Initializes the server-side tracker with essential configuration options. ```APIDOC ## init(options) Initialize the server-side tracker. ### Parameters #### Options - **siteId** (string, required): Your site ID - **reporterUrl** (string, required): The analytics collection endpoint - **reportOnLocalhost** (boolean, optional): Whether to track localhost requests - **timeout** (number, optional): Request timeout in milliseconds ### Request Example ```typescript import * as Counterscale from "@counterscale/tracker/server"; Counterscale.init({ siteId: "your-site-id", reporterUrl: "https://your-counterscale-domain.com/collect", reportOnLocalhost: false, // optional, defaults to false timeout: 2000, // optional, defaults to 1000ms }); ``` ``` -------------------------------- ### Initialize Counterscale Tracker (Client-Side) Source: https://github.com/benvinegar/counterscale/blob/main/README.md Initialize the Counterscale client with your site ID and reporter URL. This creates a global client instance. ```typescript import * as Counterscale from "@counterscale/tracker"; Counterscale.init({ siteId: "your-unique-site-id", reporterUrl: "https://{subdomain-emitted-during-deploy}.workers.dev/collect", }); ``` -------------------------------- ### Publish New Version Source: https://github.com/benvinegar/counterscale/blob/main/CONTRIBUTING.md Execute this script to publish a new version of the project. Replace `` with the desired version number. ```bash ./bump.sh ``` -------------------------------- ### Legacy CounterScale Initialization Source: https://github.com/benvinegar/counterscale/blob/main/packages/tracker/integration/01_legacyInit/index.html Use this method to queue commands before the CounterScale script is loaded. Ensure 'your-unique-site-id' is replaced with your actual site ID. ```javascript 01 Legacy Init (function () { window.counterscale = { q: [ ["set", "siteId", "your-unique-site-id"], ["trackPageview"], ], }; })(); ``` -------------------------------- ### Server-Side Tracker Initialization Source: https://context7.com/benvinegar/counterscale/llms.txt Initializes the server-side tracking singleton using the native `fetch` API. ```APIDOC ## init(opts: ServerClientOpts): void — Initialize server tracker Initializes the server-side singleton. The server module does not use DOM APIs; it uses the native `fetch` API (Node.js 18+). Tracking is fire-and-forget and will never throw. ### Description Initializes the server-side tracker, allowing for tracking from Node.js environments. It uses the native `fetch` API and is designed to be non-throwing. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import * as Counterscale from "@counterscale/tracker/server"; Counterscale.init({ siteId: "my-ssr-app", reporterUrl: "https://analytics.myworkers.dev/collect", reportOnLocalhost: false, // optional, default false timeout: 2000, // optional, default 1000 ms }); ``` ### Response None (void function) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Initialize and Track Pageview (Server-Side) Source: https://github.com/benvinegar/counterscale/blob/main/README.md Initialize the server-side tracker with configuration options and track a pageview event. Requires explicit URL and hostname. ```typescript import * as Counterscale from "@counterscale/tracker/server"; // Initialize the tracker Counterscale.init({ siteId: "your-unique-site-id", reporterUrl: "https://{subdomain-emitted-during-deploy}.workers.dev/collect", reportOnLocalhost: false, // optional, defaults to false timeout: 2000, // optional, defaults to 1000ms }); // Track a pageview await Counterscale.trackPageview({ url: "https://example.com/page", // or relative: '/page' hostname: "example.com", // required for relative URLs referrer: "https://google.com", utmSource: "social", utmMedium: "twitter", }); ``` -------------------------------- ### Initialize Server-Side Tracker Source: https://github.com/benvinegar/counterscale/blob/main/packages/tracker/SERVER.md Initialize the server-side tracker with your site ID and reporter URL. Optional parameters include `reportOnLocalhost` and `timeout`. ```typescript import * as Counterscale from "@counterscale/tracker/server"; // Initialize the tracker Counterscale.init({ siteId: "your-site-id", reporterUrl: "https://your-counterscale-domain.com/collect", reportOnLocalhost: false, // optional, defaults to false timeout: 2000, // optional, defaults to 1000ms }); ``` -------------------------------- ### Get Time-Series Analytics Data Source: https://context7.com/benvinegar/counterscale/llms.txt Returns time-series data for views, visitors, and bounces, grouped by a specified interval (DAY or HOUR). Data is sorted chronologically, with empty buckets filled in. ```typescript const start = new Date("2025-01-06T00:00:00"); const end = new Date("2025-01-13T00:00:00"); const series = await ae.getViewsGroupedByInterval( "my-blog", "DAY", // "DAY" | "HOUR" start, end, "UTC", {}, ); // → [ // ["2025-01-06 00:00:00", { views: 320, visitors: 210, bounces: 88 }], // ["2025-01-07 00:00:00", { views: 415, visitors: 274, bounces: 102 }], // ... // ] ``` -------------------------------- ### Get Aggregate Site Counts Source: https://context7.com/benvinegar/counterscale/llms.txt Retrieves total views, unique visitors, and net bounce count for a specified site ID over a named time interval. Supports optional timezone and filters. ```typescript const counts = await ae.getCounts( "my-blog", "7d", // "today" | "yesterday" | "1d" | "7d" | "30d" | "90d" "America/New_York", { path: "/blog" }, // optional SearchFilters ); // → { views: 14230, visitors: 3812, bounces: 1204 } const bounceRate = counts.visitors > 0 ? (counts.bounces / counts.visitors * 100).toFixed(1) + "%" : "n/a"; // → "31.6%" ``` -------------------------------- ### Initialize Counterscale Tracker Source: https://github.com/benvinegar/counterscale/blob/main/packages/tracker/README.md Initialize the Counterscale tracker with your site ID and deployment URL. This enables automatic page view tracking. ```typescript import * as Counterscale from "@counterscale/tracker"; Counterscale.init({ siteId: "your-unique-site-id", deploymentUrl: "https://{subdomain-emitted-during-deploy}.pages.dev/", }); ``` -------------------------------- ### Importing Server and Client Modules Source: https://github.com/benvinegar/counterscale/blob/main/packages/tracker/SERVER.md Demonstrates how to import the server-side module separately from the client-side module for distinct usage. ```typescript import * as Counterscale from "@counterscale/tracker"; // Client-side import * as CounterscaleServer from "@counterscale/tracker/server"; // Server-side ``` -------------------------------- ### Server-Side Tracker Methods Source: https://github.com/benvinegar/counterscale/blob/main/README.md Provides methods for checking initialization status, retrieving the initialized client, tracking pageviews, and cleaning up the client instance for the server-side tracker. ```APIDOC ## isInitialized() ### Description Checks if the tracker has been initialized. ### Method None (function call) ### Parameters None ### Response #### Success Response (boolean) - **true** if the tracker is initialized, **false** otherwise. ## getInitializedClient() ### Description Returns the initialized server client instance or undefined if not initialized. ### Method None (function call) ### Parameters None ### Response #### Success Response (ServerClient | undefined) - The initialized server client instance or undefined. ## trackPageview(opts) ### Description Tracks a pageview event. Requires explicit URL and hostname parameters. ### Method None (function call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **opts** (TrackPageviewOpts) - Required - Options for tracking a pageview. - **url** (string) - Required - The URL of the pageview. - **hostname** (string) - Required - The hostname for the pageview (required for relative URLs). - **referrer** (string) - Optional - The referrer URL. - **utmSource** (string) - Optional - The UTM source parameter. - **utmMedium** (string) - Optional - The UTM medium parameter. ### Request Example ```typescript await Counterscale.trackPageview({ url: "https://example.com/page", hostname: "example.com", referrer: "https://google.com", utmSource: "social", utmMedium: "twitter" }); ``` ### Response #### Success Response (Promise) This method returns a promise that resolves when the pageview event has been tracked. ## cleanup() ### Description Cleans up the server client instance. ### Method None (function call) ### Parameters None ### Response #### Success Response (void) This method does not return a value. ``` -------------------------------- ### Client-Side Tracker Methods Source: https://github.com/benvinegar/counterscale/blob/main/README.md Provides methods for checking initialization status, retrieving the initialized client, tracking pageviews, and cleaning up the client instance for the client-side tracker. ```APIDOC ## isInitialized() ### Description Checks if the Counterscale client has been initialized. ### Method None (function call) ### Parameters None ### Response #### Success Response (boolean) - **true** if client exists, **false** otherwise. ## getInitializedClient() ### Description Returns the initialized client instance or undefined if not initialized. ### Method None (function call) ### Parameters None ### Response #### Success Response (Client | undefined) - The initialized client instance or undefined. ## trackPageview(opts?) ### Description Tracks a pageview event. Requires client to be initialized first. Automatically detects URL and referrer if not provided. ### Method None (function call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **opts** (TrackPageviewOpts?) - Optional - Options for tracking a pageview. - **url** (string) - Optional - The URL of the pageview. Defaults to the current URL. - **referrer** (string) - Optional - The referrer URL. Defaults to the current referrer. ### Response #### Success Response (void) This method does not return a value. ## cleanup() ### Description Cleans up the client instance and removes event listeners. Sets global client to undefined. ### Method None (function call) ### Parameters None ### Response #### Success Response (void) This method does not return a value. ``` -------------------------------- ### Client-Side Tracker Initialization Source: https://github.com/benvinegar/counterscale/blob/main/README.md Initializes the Counterscale client for browser-based tracking. This method creates a global client instance if one does not already exist. ```APIDOC ## init(opts) ### Description Initializes the Counterscale client with site configuration. Creates a global client instance if one doesn't exist. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **opts** (ClientOpts) - Required - Client configuration options. - **siteId** (string) - Required - Your unique site ID. - **reporterUrl** (string) - Required - The URL of your deployed reporting endpoint. - **autoTrackPageviews** (boolean) - Optional - If true, automatically tracks pageviews. Defaults to true. ### Request Example ```typescript import * as Counterscale from "@counterscale/tracker"; Counterscale.init({ siteId: "your-unique-site-id", reporterUrl: "https://{subdomain-emitted-during-deploy}.workers.dev/collect", autoTrackPageviews: false }); ``` ### Response #### Success Response (void) This method does not return a value. ``` -------------------------------- ### Initialize Server-Side Tracker Source: https://context7.com/benvinegar/counterscale/llms.txt Initializes the server-side tracker singleton. Uses the native `fetch` API and does not rely on DOM APIs. Tracking is fire-and-forget and will not throw errors. `timeout` defaults to 1000 ms. ```typescript import * as Counterscale from "@counterscale/tracker/server"; Counterscale.init({ siteId: "my-ssr-app", reporterUrl: "https://analytics.myworkers.dev/collect", reportOnLocalhost: false, // optional, default false timeout: 2000, // optional, default 1000 ms }); ``` -------------------------------- ### Manage Counterscale Storage Source: https://github.com/benvinegar/counterscale/blob/main/README.md Manages long-term storage settings for your Counterscale deployment. Use enable to turn on storage and disable to turn it off. ```bash npx @counterscale/cli@latest storage [subcommand] ``` ```bash npx @counterscale/cli@latest storage enable ``` ```bash npx @counterscale/cli@latest storage disable ``` -------------------------------- ### Login to Cloudflare CLI Source: https://github.com/benvinegar/counterscale/blob/main/README.md Authorize the Cloudflare CLI (Wrangler) to interact with your Cloudflare account. This is a prerequisite for deploying Counterscale. ```bash npx wrangler login ``` -------------------------------- ### Advanced ESLint Configuration with Granular Control Source: https://github.com/benvinegar/counterscale/blob/main/packages/eslint-config/README.md Import individual configurations for fine-grained control over ESLint settings. This allows combining base, TypeScript, and React configurations, plus custom rules for specific file types. ```javascript import { createBaseConfig, createTypeScriptConfig, createReactConfig, } from "@counterscale/eslint-config"; import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); export default [ ...createBaseConfig({ baseDirectory: __dirname, ignores: ["build/*", "node_modules", "dist/*"], additionalGlobals: { counterscale: true }, }), ...createReactConfig({ baseDirectory: __dirname }), ...createTypeScriptConfig({ baseDirectory: __dirname, tsconfigRootDir: "./", project: "./tsconfig.json", }), // Add any package-specific rules { files: ["**/*.{ts,tsx}"], rules: { // Your custom rules here }, }, ]; ``` -------------------------------- ### Server-Side Tracker Initialization Source: https://github.com/benvinegar/counterscale/blob/main/README.md Initializes the Counterscale tracker for server-side analytics. Allows configuration of reporting options like `reportOnLocalhost` and `timeout`. ```APIDOC ## init(opts) ### Description Initializes the server-side tracker. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **opts** (ServerClientOpts) - Required - Server-side client configuration options. - **siteId** (string) - Required - Your unique site ID. - **reporterUrl** (string) - Required - The URL of your deployed reporting endpoint. - **reportOnLocalhost** (boolean) - Optional - Whether to report on localhost. Defaults to false. - **timeout** (number) - Optional - The timeout in milliseconds for reporting. Defaults to 1000ms. ### Request Example ```typescript import * as Counterscale from "@counterscale/tracker/server"; Counterscale.init({ siteId: "your-unique-site-id", reporterUrl: "https://{subdomain-emitted-during-deploy}.workers.dev/collect", reportOnLocalhost: false, timeout: 2000 }); ``` ### Response #### Success Response (void) This method does not return a value. ``` -------------------------------- ### Initialize Browser Tracker Source: https://context7.com/benvinegar/counterscale/llms.txt Initializes the browser tracker singleton. Automatically tracks pageviews unless disabled. Subsequent calls are no-ops. Use `getInitializedClient` to access the client instance. ```typescript import * as Counterscale from "@counterscale/tracker"; // Basic setup — auto-tracks every navigation automatically Counterscale.init({ siteId: "my-blog", reporterUrl: "https://analytics.myworkers.dev/collect", }); // Check initialization state if (Counterscale.isInitialized()) { console.log("Tracker is live"); const client = Counterscale.getInitializedClient(); // client.siteId === "my-blog" } // Teardown (e.g., in SPA unmount or test cleanup) Counterscale.cleanup(); ``` -------------------------------- ### npx @counterscale/cli@latest storage enable / disable Source: https://context7.com/benvinegar/counterscale/llms.txt Controls long-term R2 storage for daily Analytics Engine rollups. ```APIDOC ## npx @counterscale/cli@latest storage [enable|disable] ### Description Controls whether the scheduled cron (`0 2 * * *`) persists daily Analytics Engine rollups to the `counterscale-daily-rollups` R2 bucket as Apache Arrow files. ### Method `storage` with subcommands `enable`, `disable` ### Endpoint `npx @counterscale/cli@latest storage [enable|disable]` ### Parameters #### Path Parameters None #### Query Parameters None ### Request Example ```bash # Enable long-term storage npx @counterscale/cli@latest storage enable # Disable long-term storage npx @counterscale/cli@latest storage disable ``` ### Response #### Success Response Long-term storage setting is updated successfully. ``` -------------------------------- ### ServerTrackPageviewOpts Type Reference Source: https://context7.com/benvinegar/counterscale/llms.txt Defines the structure for options when tracking a server-side pageview. Ensure 'hostname' is provided for relative URLs. User-Agent, IP, and UTM parameters are optional but recommended for detailed tracking. ```typescript import type { ServerTrackPageviewOpts } from "@counterscale/tracker/server"; const opts: ServerTrackPageviewOpts = { url: "https://example.com/blog/post-1", // full URL or relative path hostname: "example.com", // required for relative URLs referrer: "https://news.ycombinator.com", // optional userAgent: req.get("User-Agent"), // optional; for server-proxied UA ip: req.ip, // optional utmSource: "hn", utmMedium: "social", utmCampaign: "launch", utmTerm: undefined, utmContent: undefined, }; ``` -------------------------------- ### Manage Counterscale Authentication Source: https://github.com/benvinegar/counterscale/blob/main/README.md Manages authentication settings for your Counterscale deployment. Available subcommands include enable, disable, and roll (for password updates). ```bash npx @counterscale/cli@latest auth [subcommand] ``` ```bash npx @counterscale/cli@latest auth enable ``` ```bash npx @counterscale/cli@latest auth disable ``` ```bash npx @counterscale/cli@latest auth roll ``` -------------------------------- ### Manual Pageview Tracking Source: https://context7.com/benvinegar/counterscale/llms.txt Initializes the browser tracker with `autoTrackPageviews` set to `false`, allowing for manual pageview tracking. ```APIDOC ## init(opts) with `autoTrackPageviews: false` — Manual pageview tracking Disables automatic navigation instrumentation. Call `trackPageview()` explicitly at the point you want to record a hit (e.g., after a route change resolves in a SPA). ### Description Configures the tracker to disable automatic pageview tracking, requiring explicit calls to `trackPageview()` for each event. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import * as Counterscale from "@counterscale/tracker"; Counterscale.init({ siteId: "my-spa", reporterUrl: "https://analytics.myworkers.dev/collect", autoTrackPageviews: false, // disable auto-tracking reportOnLocalhost: false, // default; suppress local dev hits }); function onRouteChange(path: string) { Counterscale.trackPageview({ url: path }); } onRouteChange("/products/widget-a"); // → fires GET https://analytics.myworkers.dev/collect?sid=my-spa&p=/products/widget-a&h=... ``` ### Response None (void function) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Upgrade Counterscale CLI Source: https://github.com/benvinegar/counterscale/blob/main/README.md Upgrade the Counterscale CLI to the latest version using npx. This command helps manage your deployment. ```bash npx @counterscale/cli@latest install # OR # npx @counterscale/cli@VERSION install ``` -------------------------------- ### Initialize Counterscale with UTM Tracking Source: https://github.com/benvinegar/counterscale/blob/main/packages/tracker/integration/04_utmTracking/index.html This snippet initializes the counterscale object with a site ID and triggers a page view event, which is essential for UTM parameter tracking. ```javascript (function () { window.counterscale = { q: [ ["set", "siteId", "utm-test-site-id"], ["trackPageview"], ], }; })(); ``` -------------------------------- ### trackPageview Source: https://context7.com/benvinegar/counterscale/llms.txt Records a pageview from server context. UTM parameters embedded in the URL are auto-extracted; explicitly passed UTM fields override them. ```APIDOC ## trackPageview(opts: ServerTrackPageviewOpts): Promise ### Description Records a pageview from server context. UTM parameters embedded in the URL are auto-extracted; explicitly passed UTM fields override them. ### Method `trackPageview` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **url** (string) - Required - The URL of the pageview. Can be a full URL or a relative path. - **hostname** (string) - Required for relative URLs - The hostname of the pageview. - **referrer** (string) - Optional - The referrer URL. - **userAgent** (string) - Optional - The User-Agent string. - **ip** (string) - Optional - The IP address of the client. - **utmSource** (string) - Optional - The UTM source parameter. - **utmMedium** (string) - Optional - The UTM medium parameter. - **utmCampaign** (string) - Optional - The UTM campaign parameter. - **utmTerm** (string) - Optional - The UTM term parameter. - **utmContent** (string) - Optional - The UTM content parameter. ### Request Example ```typescript Counterscale.trackPageview({ url: req.originalUrl, hostname: req.hostname, referrer: req.get("Referer"), utmSource: "email", utmMedium: "newsletter", utmCampaign: "spring-sale", utmTerm: "widget", utmContent: "header-cta", }); ``` ### Response #### Success Response (void) This method returns a Promise that resolves to void upon successful tracking. ``` -------------------------------- ### Instantiate AnalyticsEngineAPI Query Client Source: https://context7.com/benvinegar/counterscale/llms.txt Wraps Cloudflare's Analytics Engine SQL HTTP API. All query methods build SQL strings and POST them to the Cloudflare API endpoint. Requires Cloudflare Account ID and API Token. ```typescript import { AnalyticsEngineAPI } from "~/analytics/query"; const ae = new AnalyticsEngineAPI( process.env.CF_ACCOUNT_ID!, process.env.CF_BEARER_TOKEN!, ); ``` -------------------------------- ### Wrangler Configuration for Counterscale Source: https://context7.com/benvinegar/counterscale/llms.txt This JSON configuration sets up a Cloudflare Worker with bindings for Analytics Engine and R2 buckets, and defines a cron trigger for daily rollups. Ensure secrets are set via the CLI. ```json { "name": "counterscale", "main": "./workers/app.ts", "compatibility_flags": ["nodejs_compat_v2"], "compatibility_date": "2024-12-13", "assets": { "binding": "ASSETS", "directory": "./build/client" }, "analytics_engine_datasets": [ { "binding": "WEB_COUNTER_AE", "dataset": "metricsDataset" } ], "r2_buckets": [ { "bucket_name": "counterscale-daily-rollups", "preview_bucket_name": "counterscale-daily-rollups-dev", "binding": "DAILY_ROLLUPS" } ], "triggers": { "crons": ["0 2 * * *"] } } ``` -------------------------------- ### Initialize Counterscale Tracker with Manual Pageview Tracking Source: https://github.com/benvinegar/counterscale/blob/main/packages/tracker/README.md Initialize the Counterscale tracker with automatic page view tracking disabled. You will need to manually call `Counterscale.trackPageview()` when a page view occurs. ```typescript import * as Counterscale from "@counterscale/tracker"; Counterscale.init({ siteId: "your-unique-site-id", deploymentUrl: "https://{subdomain-emitted-during-deploy}.pages.dev/", autoTrackPageviews: false, // <- don't forget this }); // ... when a pageview happens Counterscale.trackPageview(); ``` -------------------------------- ### Manually Track Pageviews (Client-Side) Source: https://github.com/benvinegar/counterscale/blob/main/README.md Initialize the client-side tracker with auto-tracking disabled and then manually call `trackPageview()` when needed. This provides more control over when pageviews are recorded. ```typescript 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(); ``` -------------------------------- ### Manage Long-Term R2 Storage with Counterscale CLI Source: https://context7.com/benvinegar/counterscale/llms.txt Enable or disable the daily persistence of Analytics Engine rollups to an R2 bucket as Apache Arrow files. This is controlled by the `CF_STORAGE_ENABLED` Worker secret. The default cron schedule is `0 2 * * *`. ```bash # Enable long-term storage (default after install) npx @counterscale/cli@latest storage enable # → Sets CF_STORAGE_ENABLED=true on the Worker # Disable long-term storage npx @counterscale/cli@latest storage disable # → Sets CF_STORAGE_ENABLED=false; existing R2 data is preserved ``` -------------------------------- ### AnalyticsEngineAPI Source: https://context7.com/benvinegar/counterscale/llms.txt A client for querying Cloudflare's Analytics Engine SQL API. ```APIDOC ## AnalyticsEngineAPI — Query Class ### `new AnalyticsEngineAPI(cfAccountId, cfApiToken)` — Instantiate the query client Wraps Cloudflare's Analytics Engine SQL HTTP API. All query methods build SQL strings and POST them to `https://api.cloudflare.com/client/v4/accounts/{accountId}/analytics_engine/sql`. ### Parameters - **cfAccountId** (string) - Your Cloudflare Account ID. - **cfApiToken** (string) - Your Cloudflare API Token with Analytics Engine read access. ### Request Example ```typescript import { AnalyticsEngineAPI } from "~/analytics/query"; const ae = new AnalyticsEngineAPI( process.env.CF_ACCOUNT_ID!, process.env.CF_BEARER_TOKEN!, ); ``` ``` -------------------------------- ### Track a Pageview Server-Side Source: https://github.com/benvinegar/counterscale/blob/main/packages/tracker/SERVER.md Track a pageview event with URL, hostname, and referrer details. UTM parameters can be automatically extracted from the URL or passed explicitly. ```typescript // Track a pageview await Counterscale.trackPageview({ url: "https://example.com/page", // or relative: '/page' hostname: "example.com", // required for relative URLs referrer: "https://google.com", utmSource: "social", utmMedium: "twitter", }); ``` -------------------------------- ### Manage Dashboard Authentication with Counterscale CLI Source: https://context7.com/benvinegar/counterscale/llms.txt Control access to your Counterscale dashboard using Cloudflare Worker secrets. This command manages `CF_AUTH_ENABLED`, `CF_PASSWORD_HASH` (bcrypt), and `CF_JWT_SECRET`. Enabling prompts for a password, disabling makes the dashboard public, and rolling rotates the password hash. ```bash # Enable password protection (prompts for password → bcrypt hash stored as secret) npx @counterscale/cli@latest auth enable # → Sets CF_AUTH_ENABLED=true, CF_PASSWORD_HASH=, CF_JWT_SECRET= # Disable password protection (dashboard becomes public) npx @counterscale/cli@latest auth disable # → Sets CF_AUTH_ENABLED=false; hash + JWT secret remain intact # Rotate the dashboard password (prompts for new password) npx @counterscale/cli@latest auth roll # → Updates CF_PASSWORD_HASH; existing sessions remain valid until JWT expiry (30 days) ``` -------------------------------- ### npx @counterscale/cli@latest auth enable / disable / roll Source: https://context7.com/benvinegar/counterscale/llms.txt Manages dashboard authentication secrets for Cloudflare Workers. ```APIDOC ## npx @counterscale/cli@latest auth [enable|disable|roll] ### Description Manages the three Cloudflare Worker secrets that gate access to the dashboard: `CF_AUTH_ENABLED`, `CF_PASSWORD_HASH` (bcrypt), and `CF_JWT_SECRET`. ### Method `auth` with subcommands `enable`, `disable`, `roll` ### Endpoint `npx @counterscale/cli@latest auth [enable|disable|roll]` ### Parameters #### Path Parameters None #### Query Parameters None ### Request Example ```bash # Enable password protection npx @counterscale/cli@latest auth enable # Disable password protection npx @counterscale/cli@latest auth disable # Rotate the dashboard password npx @counterscale/cli@latest auth roll ``` ### Response #### Success Response Authentication secrets are updated successfully. ```