Get started

Install with an AI agent

Copy-paste prompts and an Agent Skill that let Claude Code, Cursor, Codex or a WordPress or Shopify MCP agent install Calmstats, add events and track scrolling.

Let your coding agent do the install. Copy a prompt below into Claude Code, Cursor, Codex, Copilot or any other agent, or add the Calmstats skill to your project once and just ask for what you want, such as "track signups" or "track scrolling on the pricing page".

Every prompt includes your script tag and the rules the agent needs: one script only, no extra packages, and how events and section views work. Each prompt ends by telling you what changed and how to verify it.

Signed in? Pick a website in the header and every prompt and the skill use its ID. You'll also find these prompts with your ID filled in under Settings → Tracking.

Prompts

Install the script

Works in Next.js (App Router or Pages Router), React, Vue, Svelte, Astro and plain HTML. The agent finds your layout and adds the tag once.

Prompt
Add Calmstats analytics to this project.

This is the tag to load on every page:

<script defer
  data-website-id="YOUR-SITE-ID"
  src="https://calmstats.com/script.js"></script>

- In Next.js, add it once to the root layout (app/layout.tsx, or pages/_app.tsx with the Pages Router) with next/script, strategy="afterInteractive", keeping the src and data-website-id attributes.
- In other frameworks and plain HTML, put it in the <head> of the shared layout or index.html.
- Calmstats needs exactly one script tag, loaded on every page. Before adding it, search the project for "script.js" and "data-website-id": if a Calmstats tag is already there, keep that one and only fix it.
- Pageviews, single-page app route changes, referrers, UTM campaigns, devices and scroll depth are tracked automatically. Do not add router listeners, manual pageview calls, or any other package.
- Visits are only counted from the website's own domain, so localhost and preview deployments send nothing. That is expected, not a broken install.
- Framework guides: https://calmstats.com/docs/install-nextjs.md, https://calmstats.com/docs/install-react.md, https://calmstats.com/docs/install-script.md.

When you're done, tell me which files or settings you changed, and remind me to deploy, then open Calmstats → Settings → Tracking and click "Verify installation". New events show up as suggestions when I create a goal or funnel.

Track custom events

Replace the line in brackets with the events you want, in plain words.

Prompt
Track these Calmstats custom events in this project:

- [describe each event, for example: "signup_completed when the signup form succeeds", "pricing_click on each plan button with the plan name"]

How Calmstats events work:

- No-code clicks: add data-calmstats-event="event_name" to a button or link. Other data-calmstats-* attributes on the same element are sent as properties (data-calmstats-plan="pro" sends { plan: "pro" }).
- Forms: put data-calmstats-event on the <form>; the event is sent on submit, not on clicks inside it.
- From code: call window.calmstats?.track("event_name", { key: "value" }) after the action succeeds. Use optional chaining so nothing breaks if the script is blocked.
- Event names: snake_case names for what happened, such as signup_completed or pricing_click, up to 100 characters. Use one name per action across the site. Property values are strings, numbers or booleans.
- Never send personal data such as emails, names or phone numbers as event names or properties.
- Prefer the data attributes for plain clicks and forms; use track() when the event depends on a result, such as a signup that succeeded on the server.
- The Calmstats script must already be on the page. If it isn't, add it first with this tag:

<script defer
  data-website-id="YOUR-SITE-ID"
  src="https://calmstats.com/script.js"></script>

If track() can run before the deferred script loads (for example on page load), add this optional queue just before the main tag:

<script>window.calmstats=window.calmstats||{q:[]};["track","goal","identify"].forEach(function(m){window.calmstats[m]=window.calmstats[m]||function(){window.calmstats.q.push([m].concat([].slice.call(arguments)))}});</script>

Examples:

<button data-calmstats-event="pricing_click" data-calmstats-plan="pro">
  Start free trial
</button>

<form data-calmstats-event="signup_completed">
  ...
</form>

calmstats.track('signup_completed', { plan: 'pro' });

Reference: https://calmstats.com/docs/custom-events.md

When you're done, tell me which files or settings you changed, and remind me to deploy, then open Calmstats → Settings → Tracking and click "Verify installation". New events show up as suggestions when I create a goal or funnel.

Track scrolling on a page

Scroll depth is already on for every page. This prompt adds section views, such as "saw the pricing table", to the sections you name.

Prompt
Track how visitors scroll on [page path, for example /pricing] with Calmstats.

Send a section view for each of these sections: [list them, for example: the pricing table as viewed_pricing, the testimonials as read_testimonials]

How Calmstats scroll tracking works:

- Scroll depth per page is automatic. Do not write scroll listeners. To turn it off, add data-scroll-depth="false" to the script tag.
- Section views: add data-calmstats-scroll="event_name" to a section, and the event is sent the first time that element is seen on a page. Optional data-calmstats-scroll-threshold (0.1 to 1, default 0.5, how much must be visible) and data-calmstats-scroll-delay (milliseconds it must stay in view).
- Sections rendered later and client-side route changes are handled. Section views are custom events, usable in goals and funnels.
- The Calmstats script must already be on the page. If it isn't, add it first with this tag:

<script defer
  data-website-id="YOUR-SITE-ID"
  src="https://calmstats.com/script.js"></script>

Examples:

<section data-calmstats-scroll="viewed_pricing">
  ...
</section>

<div data-calmstats-scroll="read_testimonials"
     data-calmstats-scroll-threshold="0.7"
     data-calmstats-scroll-delay="2000">
  ...
</div>

Reference: https://calmstats.com/docs/scroll-tracking.md

When you're done, tell me which files or settings you changed, and remind me to deploy, then open Calmstats → Settings → Tracking and click "Verify installation". New events show up as suggestions when I create a goal or funnel.

WordPress, Shopify and site builders

For an agent connected to your site through its MCP server or admin API, such as a WordPress, Shopify or Webflow MCP server. It picks the right place for the script on each platform and tells you the settings path when it can't make the change itself.

Prompt
Use the tools you have for my site (WordPress, Shopify, Webflow or another site builder, through its MCP server or admin API) to add Calmstats analytics.

This is the tag to load in the <head> of every page:

<script defer
  data-website-id="YOUR-SITE-ID"
  src="https://calmstats.com/script.js"></script>

- Calmstats needs exactly one script tag, loaded on every page. Before adding it, search the project for "script.js" and "data-website-id": if a Calmstats tag is already there, keep that one and only fix it.
- Pageviews, single-page app route changes, referrers, UTM campaigns, devices and scroll depth are tracked automatically. Do not add router listeners, manual pageview calls, or any other package.
- WordPress: add it with a header code plugin such as WPCode if your tools can change its settings, otherwise with a wp_head action in a child theme's functions.php or a small must-use plugin. Never paste it into post or page content, and never edit a parent theme. Guide: https://calmstats.com/docs/install-wordpress.md
- Shopify: connecting the store in Calmstats → Settings → Revenue installs the script and imports orders, so check whether it's connected before touching the theme. Without the connection, add the tag before </head> in layout/theme.liquid of the live theme. Purchases are tracked from orders, not with events. Guide: https://calmstats.com/docs/install-shopify.md
- Webflow: add it as site-wide head code (custom code) and publish the site. Guide: https://calmstats.com/docs/install-webflow.md
- Framer, Wix, Squarespace and builders your tools can't edit: give me the exact settings path to paste it into myself. Framer guide: https://calmstats.com/docs/install-framer.md
- Events (optional): add data-calmstats-event="event_name" as a custom attribute on buttons, links or forms, with data-calmstats-* properties. When the builder can't set attributes, add a small footer script that calls window.calmstats?.track("event_name") on click of a CSS selector.
- Section views (optional): add data-calmstats-scroll="event_name" as a custom attribute on a section. Scroll depth needs nothing.
- Change only what this needs, and don't publish other unpublished edits without asking me.

When you're done, tell me which files or settings you changed, and remind me to deploy, then open Calmstats → Settings → Tracking and click "Verify installation". New events show up as suggestions when I create a goal or funnel.

Add the Calmstats skill

The skill is one SKILL.md file in the open Agent Skills format. With it in your project, your agent knows how to install Calmstats, add custom events and track scrolling whenever you ask, with no prompt to paste.

For Claude Code, run this in your project:

Terminal
mkdir -p .claude/skills/calmstats && curl -fsSL https://calmstats.com/skill.md -o .claude/skills/calmstats/SKILL.md

For other agents that support skills, save the same file in their skills folder, for example .agents/skills/calmstats/SKILL.md. For an agent without skills, save it anywhere in the repo and mention it in your AGENTS.md or rules file.

The downloaded file asks your agent to find the website ID in your code or ask you for it. To get a copy with your ID already filled in, copy it from the block below while signed in:

SKILL.md
---
name: calmstats
description: Install Calmstats web analytics and add custom events or scroll tracking. Use when asked to add analytics or the Calmstats script, track a click, signup, form submit or other event, or track scrolling or section views on a page, in a codebase or through a WordPress, Shopify or Webflow MCP server.
---

# Calmstats analytics

Calmstats is cookieless web analytics with revenue attribution. Everything below uses one script tag; there is no npm package and nothing else to install.

## Install the script

If data-website-id below is still a placeholder rather than a UUID, reuse the data-website-id of a Calmstats tag already in the project, otherwise ask the user for it (Calmstats → Settings → Tracking). Never invent one.

```html
<script defer
  data-website-id="YOUR-SITE-ID"
  src="https://calmstats.com/script.js"></script>
```

- Calmstats needs exactly one script tag, loaded on every page. Before adding it, search the project for "script.js" and "data-website-id": if a Calmstats tag is already there, keep that one and only fix it.
- Pageviews, single-page app route changes, referrers, UTM campaigns, devices and scroll depth are tracked automatically. Do not add router listeners, manual pageview calls, or any other package.
- Visits are only counted from the website's own domain, so localhost and preview deployments send nothing. That is expected, not a broken install.

### Next.js (App Router)

Add it once to the root layout. With the Pages Router, put the same `<Script>` in `pages/_app.tsx`.

```tsx
import Script from 'next/script';

// in app/layout.tsx, inside <body>, after {children}
<Script
  src="https://calmstats.com/script.js"
  data-website-id="YOUR-SITE-ID"
  strategy="afterInteractive"
/>
```

### Other frameworks and plain HTML

Put the tag in the `<head>` of the shared layout or `index.html` (Vite, React, Vue, Svelte, Astro, Remix, Nuxt, SvelteKit, Laravel, Rails, Django templates and so on).

### Script options

Optional attributes on the tag: `data-exclude="/app/**"` stops tracking on matching paths (`*` is one segment, `**` is anything), `data-respect-dnt="true"` skips Do Not Track browsers, `data-spa-tracking="false"` turns off route-change pageviews, `data-scroll-depth="false"` turns off scroll depth. Reference: https://calmstats.com/docs/script-options.md

## Custom events

- No-code clicks: add data-calmstats-event="event_name" to a button or link. Other data-calmstats-* attributes on the same element are sent as properties (data-calmstats-plan="pro" sends { plan: "pro" }).
- Forms: put data-calmstats-event on the <form>; the event is sent on submit, not on clicks inside it.
- From code: call window.calmstats?.track("event_name", { key: "value" }) after the action succeeds. Use optional chaining so nothing breaks if the script is blocked.
- Event names: snake_case names for what happened, such as signup_completed or pricing_click, up to 100 characters. Use one name per action across the site. Property values are strings, numbers or booleans.
- Never send personal data such as emails, names or phone numbers as event names or properties.
- Prefer the data attributes for plain clicks and forms; use track() when the event depends on a result, such as a signup that succeeded on the server.

```html
<button data-calmstats-event="pricing_click" data-calmstats-plan="pro">
  Start free trial
</button>

<form data-calmstats-event="signup_completed">
  ...
</form>
```

```js
window.calmstats?.track('signup_completed', { plan: 'pro' });
```

In TypeScript, declare the global once (for example in `types/calmstats.d.ts`):

```ts
type CalmstatsProps = Record<string, string | number | boolean>;

declare global {
  interface Window {
    calmstats?: {
      track: (event: string, props?: CalmstatsProps) => void;
      getVisitorId: () => string;
    };
  }
}

export {};
```

If `track()` can run before the deferred script has loaded (for example during page load), add this optional queue just before the main tag. Calls made while the page loads are sent once Calmstats loads:

```html
<script>window.calmstats=window.calmstats||{q:[]};["track","goal","identify"].forEach(function(m){window.calmstats[m]=window.calmstats[m]||function(){window.calmstats.q.push([m].concat([].slice.call(arguments)))}});</script>
```

Reference: https://calmstats.com/docs/custom-events.md

## Scroll tracking

- Scroll depth per page is automatic. Do not write scroll listeners. To turn it off, add data-scroll-depth="false" to the script tag.
- Section views: add data-calmstats-scroll="event_name" to a section, and the event is sent the first time that element is seen on a page. Optional data-calmstats-scroll-threshold (0.1 to 1, default 0.5, how much must be visible) and data-calmstats-scroll-delay (milliseconds it must stay in view).
- Sections rendered later and client-side route changes are handled. Section views are custom events, usable in goals and funnels.

```html
<section data-calmstats-scroll="viewed_pricing">
  ...
</section>

<div data-calmstats-scroll="read_testimonials"
     data-calmstats-scroll-threshold="0.7"
     data-calmstats-scroll-delay="2000">
  ...
</div>
```

In React and other JSX, data attributes go on the element as written: `<section data-calmstats-scroll="viewed_pricing">`.

Reference: https://calmstats.com/docs/scroll-tracking.md

## Sites managed through an MCP server or admin API

- WordPress: use a header code plugin such as WPCode if the tools can change its settings, otherwise a wp_head action in a child theme's functions.php or a must-use plugin. Never paste the tag into post or page content or edit a parent theme. https://calmstats.com/docs/install-wordpress.md
- Shopify: connecting the store in Calmstats → Settings → Revenue installs the script and imports orders. Without it, add the tag before </head> in layout/theme.liquid of the live theme. Purchases come from orders; don't add purchase events. https://calmstats.com/docs/install-shopify.md
- Webflow: add the tag as site-wide head code and publish. Events and section views are custom attributes on elements. https://calmstats.com/docs/install-webflow.md
- Builders the tools cannot edit (Framer, Wix, Squarespace): tell the user the settings path to paste the tag into.
- When a builder cannot set data attributes, add a small footer script that calls window.calmstats?.track("event_name") on click of a CSS selector.
- Change only what the task needs, and ask before publishing other unpublished edits.

## Finish

Tell the user which files or settings changed. Remind them that visits only count on the live domain: deploy, then click "Verify installation" in Calmstats → Settings → Tracking. New event names show up as suggestions when they create a goal or funnel step.

All docs as Markdown: https://calmstats.com/docs.md

After the agent is done

Visits are only counted on your website's own domain, so localhost and preview deployments send nothing. Deploy, then click Verify installation in Settings → Tracking. New event names appear as suggestions when you create a goal or funnel step.

Want the agent to read the docs itself? Point it at /docs.md, every page in one Markdown file.