DataDad.

Per-user analytics for platforms

Give each profile, store or page on your platform its own statistics. Name the tenant on the script tag, count link clicks, and read each tenant's numbers.

Updated

A platform, such as a link-in-bio site or a store builder, has many users, and each user has their own page. DataDad counts each page as a tenant. One script tag on all pages collects the data. Your server reads each tenant's numbers through the stats API and shows them to its owner. The numbers of two tenants never mix.

Analytics for Platforms is turned on for each account. To turn it on, send a message from the Help page.

Add your platform

  1. In DataDad, select Add, then Platform.
  2. Enter your platform's domain and choose what a user's page is called, such as Profile or Store.
  3. Add the script tag to your pages (see below), then select I've installed it.
  4. Open one user's page on your live site. The setup shows the first visit with its tenant.
  5. Create an API key. The setup shows a sample response for the tenant it saw.

You need no API call to create a tenant. A tenant exists from its first page view.

Name the tenant on each page

Add the script to each user's page and set data-tenant to the page's ID:

<script defer src="https://c.data.dad/s.js"
  data-site="site_…"
  data-tenant="p_123"
  data-outbound></script>
<script defer src="https://c.data.dad/s.js" data-site="site_…"
  data-tenant="{{ $profile->id }}" data-outbound></script>
<script defer src="https://c.data.dad/s.js" data-site="site_…"
  data-tenant="<%= @profile.id %>" data-outbound></script>
"use client";
import Script from "next/script";
import { usePathname } from "next/navigation";
import { useLayoutEffect } from "react";

// data-manual: the script does not count route changes itself.
// Render once on each page: tenant={profile.id}, or no tenant.
export function DataDad({ tenant }) {
  const pathname = usePathname();
  useLayoutEffect(() => {
    const tag = document.querySelector("script[data-site]");
    if (tenant) tag?.setAttribute("data-tenant", tenant);
    else tag?.removeAttribute("data-tenant");
    window.datadad?.page();
  }, [tenant, pathname]);
  return <Script src="https://c.data.dad/s.js" data-site="site_…"
    data-tenant={tenant} data-outbound data-manual />;
}
import Script from "next/script";
import { useRouter } from "next/router";
import { useLayoutEffect } from "react";

// data-manual: the script does not count route changes itself.
// Render once on each page: tenant={profile.id}, or no tenant.
export function DataDad({ tenant }) {
  const { asPath } = useRouter();
  useLayoutEffect(() => {
    const tag = document.querySelector("script[data-site]");
    if (tenant) tag?.setAttribute("data-tenant", tenant);
    else tag?.removeAttribute("data-tenant");
    window.datadad?.page();
  }, [tenant, asPath]);
  return <Script src="https://c.data.dad/s.js" data-site="site_…"
    data-tenant={tenant} data-outbound data-manual />;
}
<script defer src="https://c.data.dad/s.js" data-site="site_…"
  data-tenant="{{ profile.id }}" data-outbound></script>

With data-outbound on the script tag, a click on a link to another site counts as a link click. The API shows clicks per link with by=link.

To keep a link's count when its address changes, give the link a name with data-dd-link:

<a href="https://open.spotify.com/artist/1" data-dd-link="lnk_42">My music</a>

A link with data-dd-link counts even when it points to your own domain, for example to a redirect such as /go/42. The address is stored without its query string.

Show the numbers to your users

Your server calls the API with the tenant, and your page shows the result. For example, a stats page for a profile owner:

// Server route for the signed-in owner's stats page.
const params = new URLSearchParams({ tenant: profile.id, range: '30d' });
const headers = { Authorization: `Bearer ${process.env.DATADAD_API_KEY}` };
const [summary, links] = await Promise.all([
  fetch(`https://data.dad/api/v1/stats/summary?${params}`, { headers }).then(r => r.json()),
  fetch(`https://data.dad/api/v1/stats/breakdown?${params}&by=link&limit=20`, { headers }).then(r => r.json()),
]);

Check on your server that the signed-in user owns the profile before you send its ID to the API. The key can read every tenant of the app.

How tenants are counted

See your tenants in DataDad

On the app's dashboard, select Profiles (or the name you chose). The list shows your tenants ranked by visitors. Select a tenant to see its report: the same numbers the API returns.