Skip to main content

Products

Add the script to your website, connect revenue, set goals, and read visitors, sources and search keywords.

Analytics shows who visits the website of your business, where they come from, and which visits bring revenue. This page tells you how to add the script, name your visitors, track goals, connect revenue, read the dashboard and share it.

Before you begin

  • You need the Analytics product. An owner or admin gives products to people in Settings > People.
  • You need access to the code or the editor of your website, to add one script tag.
  • To connect revenue, an owner or admin connects a payment provider: Stripe, Lemon Squeezy, Polar or Paddle.

A workspace has one website in Analytics. Other domains of the same business, such as a checkout domain, count as that website.

Set up Analytics

Open Products > Analytics. Until the first visit, the page shows 3 steps, one at a time. The steps over the card show where you are. Select a step that is done to change it.

  1. Add site

    Type the root Domain, for example acme.com. Its subdomains count too. Setup fills in the website of your business, when you gave one. Pick the Time zone. The days of each report start at midnight there, and it is the time zone of the workspace too. Select Add website.

  2. Install script

    Select the tab of the place where your site runs: Script, Next.js, npm or WordPress. Each tab says where the code goes. Select Use no cookies for the version that sets no cookies. This also turns on the No cookies setting. Copy the code, and put the tag in the <head> of every page:

    html
    <script defer data-site="ts_YOUR_SITE_ID" data-domain="acme.com" src="https://troopy.ai/js/script.js"></script>

    Install with AI gives a prompt for an AI code editor, such as Cursor, Claude Code or Copilot. Select Copy the prompt, and paste it into the editor. The editor adds the script for you.

    The step shows Waiting for the first visit until the script sends its first event. The page checks every 5 seconds. Select I added the script to go on.

  3. Attribute revenue (optional)

    Pick your payment provider, and connect it, so that Troopy ties each payment to the visit that brought it. For another provider, pick Another provider (Payment API). Read Connect revenue. Select Continue, or Skip for now. You can do this step at any time.

Then the page waits for the first visit. Select Open and the name of your site to send one. At the first visit, the dashboard takes the place of the steps. To track goals, read Track goals.

The script

The script is small, and it sets no cookies of other sites. Troopy never keeps the IP address of a visitor. It finds the country, the region and the city with the database of DB-IP, and then it drops the address.

The script sets 3 first-party cookies on the root domain: the visitor (1 year), the session (30 minutes) and the count of sessions. Thus app.acme.com, blog.acme.com and acme.com share one visitor.

Options of the tag

AttributeWhat it does
data-siteThe id of your site. The tag needs it.
data-domainThe root domain of the site.
data-allowed-hostnamesOther domains of the site, apart by commas. A link to one of them carries the visitor over.
data-allow-localhost="true"Counts the visits of localhost, for a test.
data-allow-file-protocol="true"Counts the pages that open as file://.
data-debug="true"Counts a page inside an iframe.
data-auto-pageviews="false"Sends no pageview by itself. Your code calls troopy("pageview").
data-disable-payments="true"Reads no payment from the address of a success page.
data-disable-surveys="true"Shows no survey on the page.
data-disable-console="true"Writes no lines in the console of the browser.
data-api-urlSends the events to another address, such as your own proxy.
data-cookieless="true"Sets no cookies, as script.cookieless.js does. Use it behind a proxy of /js/script.js.

Single-page apps, hash routes and no cookies

  • The script counts a page that changes with no reload, by itself.
  • For hash routes, such as /#/pricing, load script.hash.js in the place of script.js.
  • For no cookies at all, load script.cookieless.js. script.hash.cookieless.js does both.
  • With no cookies, the script keeps the session in the tab only. The session ends when the tab closes, or after 30 minutes with no event.
  • Troopy makes the id of the visitor from the IP address, the browser and the site, with a random salt for each UTC day. Troopy deletes the salt a day later. Then nobody can find the visitors of that day again.
  • Thus each visitor counts one time a day. Troopy cannot tell a visitor who comes back from a new one.
  • With no cookies, the dashboard has no Visit count filter, no Journeys tab and no Visitors tab. A link to another domain of the site does not carry the visitor over.

The No cookies switch in Analytics settings > General > Privacy changes the tag that the page shows. Put the new tag on your site. The old tag still sets cookies. With the setting on, Troopy counts each visitor one time a day for every version of the script.

The npm package

For a React, Next.js or Vue app, you can install the troopy-analytics package in the place of the tag:

bash
npm install troopy-analytics
ts
import { initTroopy } from "troopy-analytics"; const troopy = initTroopy({ siteId: "ts_YOUR_SITE_ID", domain: "acme.com" });troopy.track("signup", { plan: "pro" });

The package loads the same script, so it counts the same things. It also has a part for React Native and Expo (troopy-analytics/react-native).

Leave your own visits out

Open your site, then run this line in the console of the browser:

js
localStorage.setItem("troopy_ignore", "true");

That browser then sends nothing. To count it again, run localStorage.removeItem("troopy_ignore").

Say who a visitor is

Until you say who a visitor is, Troopy gives the visitor a made-up name. After a person signs in to your product, call identify with the id of the user:

js
troopy("identify", {  user_id: user.id,  name: user.name,  email: user.email,  plan: "pro",});
  • user_id is required. name gives the visitor a name.
  • Each other key is a trait. Troopy keeps 10 traits at most, each of 255 characters at most.
  • The same user_id on two devices links the two devices.
  • Customers and Surveys read the same call. A survey shows only to a user that identify named.

Your server can do the same, with an API key that has the analytics:write scope: POST /api/v1/analytics/visitors/{visitor}/identify.

html
<script>  window.troopy =    window.troopy ||    function () {      (window.troopy.q = window.troopy.q || []).push(arguments);    };</script>

Track goals

A goal is something that a visitor does that matters to you. Send a goal in one of these ways:

html
<button data-troopy-goal="signup" data-troopy-goal-plan="pro">Sign up</button><section data-troopy-scroll="viewed_pricing">...</section>
js
troopy("signup", { plan: "pro" });
  • data-troopy-goal sends the goal at each click on the element. Each data-troopy-goal-* attribute is a parameter.
  • data-troopy-scroll sends the goal one time a page, when half of the element shows. Change the share with data-troopy-scroll-threshold, from 0 to 1.
  • With data-troopy-scroll-delay, the element must stay in view for that many milliseconds first.
  • A click on a link to another site counts as an exit link.
  • From your server, send POST /api/v1/analytics/goals with the id of the visitor. The key needs analytics:write.

A goal name has 64 characters at most: lowercase letters, digits, _, - and :. The script makes the letters lowercase, and makes each space an underscore. A goal has 10 parameters at most.

Troopy records some goals itself. You cannot send them: identify, payment, free_trial, trial_started, trial_converted, subscription_started, subscription_upgraded, subscription_downgraded, subscription_renewed, subscription_cancel_scheduled, subscription_reactivated and subscription_ended.

Read and change goals

The Goals card of the dashboard has 4 tabs:

TabWhat it shows
GoalsEach goal over the period, with its visitors and its conversion. Select a goal for its parameters.
FunnelsThe steps that visitors take in order, and how many get through each step. A funnel has 2 to 8 steps.
JourneysThe pages that led to a goal.
VisitorsEach visitor, with a profile and its events. A public link never shows this tab.

Under How it shows, a goal has a Label, a Colour and a Description. Hide it from the dashboard hides the goal, and its completions stay.

Connect revenue

Troopy reads payments from the connection of your workspace, the same one that your teammates read. Open Analytics settings > Revenue, or step 3 of the setup. Pick your provider. Owners and admins connect it there with a key, as in Settings > Apps.

Then tell the provider who paid. Do one of these:

ProviderHow to tie a payment to the visitor
StripeAdd troopy_visitor_id to the metadata of Checkout or a PaymentIntent.
Stripe Payment LinksSend buyers back to your site with ?session_id={CHECKOUT_SESSION_ID} in the success URL.
Lemon SqueezyAdd ?order_id=[order_id] to the redirect URL of the product. For checkouts from your server, use its recipe in Payment API.
PolarAdd troopy_visitor_id to the metadata of the checkout, or ?checkout_id={CHECKOUT_ID} to the success URL.
PaddleOpen the checkout of Paddle.js with customData: { troopy_visitor_id }.
Any providerOn your thank-you page, call troopy("payment", { email }) with the email of the buyer.

The value of troopy_visitor_id is the cookie of the same name. Troopy also ties a payment by the email or by the customer of the provider.

  • Troopy reads new payments every 5 minutes. The first read takes the last 30 days.
  • Select Sync now to read at once.
  • Owners and admins can read the history again from 90 days, 1 year or 2 years ago, with Read again.
  • A renewal counts on the visitor who first subscribed.
  • The name and the email of a payer name a visitor that identify did not name.
  • Troopy does not take refunds off the revenue.

The Payment API

For another provider, or for your own webhook, send each payment from your server. Make an API key with the analytics:write scope in Settings > API keys. Each transactionId counts one time.

bash
curl -X POST https://troopy.ai/api/v1/analytics/payments \  -H "Authorization: Bearer $TROOPY_API_KEY" -H "Content-Type: application/json" \  -d '{"transactionId":"pay_4821","amount":29,"currency":"USD","visitor":"<troopy_visitor_id>","email":"ada@example.com"}'

Give amount in major units (29.99), or amountMinor in minor units (2999). DELETE /api/v1/analytics/payments takes off what the API recorded: one payment, all the payments of a visitor, or a time range. The Payment API tab has recipes for Dodo Payments and for the webhooks of Lemon Squeezy.

Read the dashboard

Everything that the dashboard shows comes from its address. Thus a copied link opens the same view.

PartWhat it shows
The totalsVisitors, Revenue, Conversion, Per visitor, Bounce rate, Session time and Online, with the change from the period before.
The main numberRevenue by default. Main KPI in the settings can make it MRR or a goal.
ROASShows when your tracked Meta campaigns spent money in the period.
SubscriptionsMRR, Subscribers, In trial, Churn and LTV, from your payment providers.
The chartVisitors as a line and revenue as bars. Notes adds a note to a day, and shows commits and mentions.
SourcesChannel, Referrer, Campaign, Keyword, Meta ads and Mentions.
PagesPage, Entry page, Exit link and Hostname.
LocationMap, Country, Region and City.
DevicesBrowser, OS and Device.
GoalsGoals, Funnels, Journeys and Visitors.
AI crawlersThe pages that AI crawlers read, when your server reports them.

Each card shows visitors. Select Visitors at the top of a card to show revenue in the place of visitors. Select a row to filter the whole dashboard by it.

  • The period menu picks the days. The arrows step to the period before or after.
  • Compare shows the numbers of the period before beside each total.
  • Filter adds a filter. Save as segment keeps the filters of the view under a name.
  • Online opens the globe of the visitors who are on the site now. The globe can replay the last 8 hours. Its first button picks the map: Dark, Light, Outdoors, Satellite, Night lights, Blue Marble, Bright, Atlas, Neon or Emerald.
  • Insights opens Revenue insights. They need 200 visitors and 5 attributed payments in the period.
KeyWhat it does
N, T, Y, HNow, Today, Yesterday, Last 24 hours
7, 3Last 7 days, Last 30 days
W, M, AThis week, This month, All time
CCompare with the period before
GThe globe
IRevenue insights
Left and right arrowsThe period before or after

The Keyword tab needs Google Search Console. The Meta ads tab needs Meta Ads. The Mentions tab shows the posts on X and Reddit that name your site.

Get past ad blockers

Some ad blockers stop scripts that load from an analytics domain. Serve the script from your own domain to get past them.

Serve the script from your domain

Pass 2 paths of your site on to Troopy, with the IP address of the visitor: /js/script.js and /api/events. Then load the script from your own domain. The script sends its events to the same domain by itself.

Analytics settings > General > Serve the script from your domain has a guide for 15 hosts: Next.js, Vercel, Netlify, Cloudflare, Nginx, Caddy, Express, PHP, Laravel, Flask, FastAPI, Astro, Vue, Firebase and DigitalOcean. For Next.js, add this to next.config.js:

ts
async rewrites() {  return [    { source: "/js/script.js", destination: "https://troopy.ai/js/script.js" },    { source: "/api/events", destination: "https://troopy.ai/api/events" },  ];}

Then load the script from your domain:

html
<script defer data-site="ts_YOUR_SITE_ID" src="/js/script.js"></script>

Use the managed proxy

The managed proxy needs no code on your server. Troopy serves the script from a subdomain of your site, and gets its certificate. Owners and admins set it up.

  1. Open Analytics settings > General > Managed proxy.
  2. Keep the subdomain that it offers, such as a.acme.com, or type another. Select Set up.
  3. At your DNS host, add the CNAME record that the card shows. Its target is proxy.troopy.ai.
  4. Turn off any proxy of your DNS host for that record. On Cloudflare, the cloud of the record must be grey.
  5. Select Check now. A DNS change can take an hour to show.
  6. When the status is Active, load the script from the subdomain, as the card shows.

Troopy checks a proxy that waits every 5 minutes, for a week. After a week, the status is Did not work.

A public link shows the dashboard, read-only, to anyone who has the link. It shows nothing else of the workspace.

Owners and admins make the link:

  1. Open Analytics settings > General > Public link.
  2. Select Make a link.
  3. Copy the link, and send it.

New link makes a new link, and the old link stops at once. Turn off stops the link. Viewers and approvers do not see the link.

The public view never shows MRR, subscribers, the Visitors tab, hidden goals or notes. It does not show the Keyword, Meta ads or Mentions tabs, AI crawlers or Insights.

Analytics settings

Select Analytics settings at the top of the dashboard. The pages of the settings are in a column at the left. On a phone, they are one menu. Each page holds boxes: a title, what the box does, its fields, and its Save.

PageWhat it holds
GeneralThe script, the domain, other domains, the time zone, the main KPI, no cookies, the 2 proxies and the public link.
RevenueThe payment provider, the state of the last read of payments, and the Payment API.
ImportThe history of your site from a CSV export of Plausible, as a zip file.
ReportsA weekly report and an email for a spike of traffic.
AlertsAn email to the maker of the alert when a visitor completes a goal, a payment arrives or a free trial starts.
IntegrationsGoogle Search Console, the mentions on X and Reddit, the commits of a GitHub repo on the chart, and Meta Ads.
AI crawlersThe code that reports AI crawlers from your server, a bot token, and the crawlers to record.
ExclusionsThe IP addresses, pages, hostnames and countries that never count.
SecurityAttack mode.

On Exclusions, type a value and select Add. The X of a value removes it. /admin is that page, and /admin/* is each page under it. A country is its code of two letters, such as DE. Attack mode makes the checks stricter under a flood of fake visits.

The weekly report goes on Monday from 8:00, in the time zone of the workspace. A spike is an hour with 3 times the usual pageviews, and 50 at least. Both emails go to the owners and admins of the organization.

Who can do what

PersonWhat the person can do
Owner or adminAll of it. Only they connect payment providers, read the history again, make the public link, set up the managed proxy and make the bot token.
MemberRead the dashboard. Change the settings, goals, funnels, segments, notes and alerts.
Viewer or approverRead the dashboard and the settings, and change nothing.

The Growth analyst reads Analytics with read tools. No teammate changes it.

Limits

LimitValue
Websites in a workspace1
Events from one visitor address120 a minute, or 30 in attack mode
Events of one site6,000 a minute
Parameters of a goal, traits of identify10, each value of 255 characters at most
Steps of a funnel2 to 8
Saved segments50
Email alerts25 a site, and 60 emails an hour for each alert
Revenue insights200 visitors and 5 attributed payments in the period
The chance that a visitor pays1,000 visitors and 10 payments in the last 90 days
Words and X handles for mentions10 words of 4 to 15 characters, and 5 handles
An import from PlausibleA zip file of 20 MB at most

Problems

The script writes why it sent nothing in the console of the browser, on a line that starts with [Troopy].

MessageWhyWhat to do
data-site is missingThe tag has no site id.Copy the tag again from Analytics settings > General.
Troopy does not track localhostTroopy counts no local page.Add data-allow-localhost="true" for a test.
Troopy does not track pages inside an iframeThe page is in a frame.Add data-debug="true" to the tag.
a program controls this browserA test tool or a robot drives the browser.Open the site in a normal browser.
localStorage.troopy_ignore tells Troopy to ignore this browserYou left this browser out.Run localStorage.removeItem("troopy_ignore").
goal names are lowercase letters, digits, _ - :The goal name breaks the rule.Change the name.
"That doesn't look like a domain"The domain has a wrong form.Type the root domain only, such as acme.com.
"The Stripe key can't read ..."The key lacks a read that revenue needs.Replace the key with one from the link on its card.

The answer of /api/events is always 202. Its x-troopy-result header says what Troopy did with the event:

ResultWhy
okTroopy kept the event.
foreign_hostThe page is not on the domain of the site. Add the domain to Other domains.
excludedA rule of Exclusions left the event out.
botThe browser says that it is a robot.
rate_limitedThe address or the site sent too many events in a minute.
unknown_siteNo site has that id.
invalidThe event has a wrong form.
suspiciousAttack mode refused the event.