All docs

Tracking script

Every platform uses the same tag. Setup → Install on your dashboard shows it with your real values filled in.

<script defer data-site="site_yourapp" src="https://YOUR-DATAPENNY-URL/js/script.js"></script>

Platform guides

Plain HTML

Put the tag in the <head> of each page.

Next.js

With the App Router it goes in app/layout.tsx, and with the Pages Router in pages/_document.tsx:

import Script from 'next/script';

<Script
  src="https://YOUR-DATAPENNY-URL/js/script.js"
  data-site="site_yourapp"
  strategy="afterInteractive"
/>

Vite, SvelteKit, Astro, Remix, Nuxt

It belongs in whichever file renders your <head>: index.html for Vite, src/app.html for SvelteKit, the base layout for Astro, app/root.tsx for Remix, and app.head in nuxt.config for Nuxt.

WordPress

The free WPCode plugin does the job. Open Code Snippets → Header & Footer, paste the tag into the Header box, then clear your page cache.

Shopify

Go to Online Store → Themes → Edit code, open layout/theme.liquid, and paste the tag just before the closing </head>.

Webflow

Add it under Site settings → Custom code → Head code. Webflow runs it on the live site only, so save and then publish.

Framer

Under Site Settings → General → Custom Code, paste it into End of <head> tag, then publish.

Wix, Squarespace, Ghost, Carrd, Bubble

Each of these has one place for code that runs across the whole site:

  • Ghost: Code injection → Site header
  • Squarespace: Developer tools → Code Injection → Header
  • Wix: Settings → Custom code, set to Head on all pages
  • Bubble: SEO / metatags → header scripts
  • Carrd: an Embed element set to Head

Attributes

Attribute What it does
data-site Required. Your site id. data-website-id works too.
data-domain Cookie root domain, so subdomains share one visitor. Worked out for you if left out.
data-api Sends events to another address, for a first-party proxy.
data-privacy cookie, cookieless or consent. Leave it out and the site’s setting decides, with no code change: the script learns it from the answer to its first event, and stores nothing until then.
data-dev Tracks on localhost, which is ignored by default. data-allow-localhost does the same.

JavaScript API

Need to call it before the script has finished loading? Put this small queue above the tag:

<script>window.datapenny = window.datapenny || function () { (window.datapenny.q = window.datapenny.q || []).push(arguments); };</script>
datapenny('goal', 'signup', { plan: 'pro' });
datapenny('signup', { plan: 'pro' });  // the same, shorter
datapenny('identify', { user_id: 'user_123', email: 'mira@example.com', name: 'Mira' });
datapenny('consent', true);       // on cookieless-until-consent sites
datapenny.visitorId();            // pass this to your checkout
datapenny.sessionId();

What it tracks without being asked

  • Pageviews, including pushState, replaceState and back-button navigation in single-page apps.
  • Reading time and scroll depth, sent when a visitor leaves the page.
  • Clicks on links to other sites.
  • Clicks on checkout links for Dodo Payments, Stripe, Lemon Squeezy, Polar and Creem, which also get tagged with the visitor id. Links opened with window.open count too.
  • The return from a checkout, from the id your provider adds to the thank-you page URL.

Leaving yourself out of the numbers

Under Setup → Your own visits:

  • Stop counting this browser opens yoursite.com/?dp_ignore=1 once and remembers it there. ?dp_ignore=0 counts it again.
  • List IP addresses or ranges, such as 10.0.0.0/8, for home, the office or the team. Add my current IP saves you looking yours up.
  • Don’t count browsers that use this dashboard leaves out anyone signed in here, on that browser and connection. It’s off by default, so the test visit you make after installing shows up.

Moving from DataFast

window.datafast() calls, data-fast-goal, data-fast-goal-* and data-fast-scroll attributes, the datafast_visitor_id cookie and checkout metadata all keep working, and so does data-website-id on the tag. On most sites you only swap the script’s src.