Statistics
CrawlProof statistics is a cookieless tracker for pageviews, AI referrals, AI crawler visits, routes, clicks, forms, scrolls, downloads, outbound links, and custom events. It works with plain HTML, React, Next.js, Vue, Nuxt, Svelte, SvelteKit, Astro, Remix, Shopify themes, Webflow embeds, and anything else that can load a browser script.
Install
Enable the tracker from your project Stats tab, then install the script on every page you want tracked. The project id in data-site is the only required identifier.
<script data-site="<your-project-id>" src="https://crawlproof.com/stats.js" async ></script>
Put the tag in your app shell, layout, root template, or site-wide footer. Do not add API keys, auth tokens, cookies, or user ids.
If your site uses a strict Content Security Policy, allow https://crawlproof.com in script-src and connect-src. The GitHub auto-installer patches common CSP files such as next.config.*, vercel.json, netlify.toml, and _headers when it opens the PR.
Framework installs
// Next.js / React
import Script from "next/script";
export default function Layout({ children }) {
return (
<>
{children}
<Script
data-site="<your-project-id>"
src="https://crawlproof.com/stats.js"
strategy="afterInteractive"
/>
</>
);
}<!-- Vue, Nuxt, Svelte, SvelteKit, Astro, Webflow, plain HTML --> <script data-site="<your-project-id>" src="https://crawlproof.com/stats.js" async ></script>
Automatic tracking
The tracker is plain browser JavaScript. It automatically sends anonymous HTTP requests for:
- Initial pageviews.
- SPA route changes via
history.pushState,history.replaceState, andpopstate. - Internal clicks, outbound clicks, and download clicks.
- Button clicks and elements marked with tracking attributes.
- Form submits.
- Scroll milestones at 25%, 50%, 75%, and 100%.
Each request includes the project id, event name, current URL, current page's document.referrer, viewport, language, timezone, anonymous tab-scoped visitor/session ids, and a small target label when available. The server reads User-Agent and Referer from the HTTP request.
Custom events
Use the global API after the script loads. This works from React, Vue, Svelte, or any browser code.
window.crawlproof?.track("signup");
window.crawlproof?.track("checkout_started", "pricing_button");
window.crawlproof?.track("purchase", "pro_plan");You can also mark elements declaratively:
<button data-cp-track="signup_clicked" data-cp-label="hero_cta"> Start free </button> <a data-cp-track="docs_opened" href="/docs"> Read docs </a>
Privacy model
- No cookies.
- No localStorage.
- Session ids use
sessionStoragewhen available and reset when the tab session ends. - No fingerprinting.
- No auth tokens or API keys in the browser.
- No user ids required.
- No raw visitor sessions stored for the default tracker.
CrawlProof stores daily aggregate rollups by source, event, page, referrer host, target label, and location. The network request is best-effort and never blocks the host page.
Location data
Location charts use the free MaxMind GeoLite2 City database on the server. The browser never sends an IP address, and CrawlProof does not store raw IPs. The API reads the request IP from trusted proxy headers, looks it up locally, and stores only daily aggregate fields: country, region, city, and timezone.
MAXMIND_LICENSE_KEY=<your-maxmind-license-key> MAXMIND_GEOLITE2_CITY_DB_PATH=data/GeoLite2-City.mmdb npm run download-geolite2
The .mmdb file is local-only and ignored by git. If the file is missing, tracking continues without location rollups.