Features · Analytics

Traffic, without a tracker.

Views, top pages and top sources for each app, counted on Tofu’s own endpoint. No cookie, no third-party script, no stored IP address — and no analytics account to open.

Read the docsAgent setup

What your agent calls

  • siteAnalytics
  • setSiteAutoInject
claude · ~/corner-bakeryexample

Count visits to corner-bakery.

tofu · siteAnalytics

site key tfsk_…a41c issued · snippet ready

Update(app/layout.tsx)

1 line added · collect.js, no cookie

tofu · ingest ~/corner-bakery

code updated · settings kept

tofu · deploy

ready · HTTP 200 · publicly reachable

One line, or none

One line, or none at all.

Each app has one site key and one line. The key names your app and the addresses allowed to report for it: your Tofu address and the domains you connected, along with any other address on Tofu’s own domains.

In a framework app, your agent adds the line to your layout and deploys. For a prebuilt static site, one switch has Tofu add it at deploy time — to the copy being published, never to your stored files — and the Analytics page says whenever it did not.

app/layout.tsxone line
<head>
  <script defer
    src="https://trytofu.ai/collect.js"
    data-site="tfsk_…"></script>
</head>
Copy it from the Analytics page, or let your agent add it. The key is public by design: it is in your page’s source anyway.
Counted without a tracker

Your visitors’ privacy, by construction.

Both ends are Tofu’s: a small script from its own domain, and its own endpoint. Nothing about a visitor leaves Tofu’s infrastructure.

  • Cookies

    0

    Nothing stored in the browser

    So there is nothing to clear, and no banner to show for one.

  • Third-party scripts

    0

    One script, from Tofu’s own domain

    Posting to Tofu’s own endpoint. No vendor on your page.

  • IP addresses stored

    0

    Used in memory, never kept

    Unique visitors, where counted, come from a digest that changes every day, so no one is followed from one day to the next.

  • Days kept

    90

    Then deleted, by a daily job

    Never kept past 365 days, and deleting the app deletes its traffic with it.

Do Not Track and GPC, honoured twice

Checked in the browser and again on the server: with either signal on, the view is not recorded at all.

Paths, not full addresses

Query strings and fragments are dropped first, and id-shaped segments become :id, so a search term or a reset token in a URL is never stored.

Not tied to anyone’s account

A view is never linked to a signed-in user, and the site key names your app without being able to read or change anything.

What you see

Your numbers, in your dashboard and your agent.

ReportedWhat it is
ViewsEvery counted page load, per UTC day, with quiet days kept rather than dropped.
Top 10 pathsPaths only, with id-shaped segments folded into :id.
Top 10 sourcesThe referring site’s hostname, never its path.
VisitorsA count only where Tofu’s visitor salt is configured; otherwise shown as —, never a guess.

Read it on the Analytics page, or ask your agent: siteAnalytics takes any window from 1 to 90 days. A number that cannot be read comes back as unavailable, never as a zero.

claude · ~/corner-bakerysample week

How many people saw the order page this week?

tofu · siteAnalytics days: 7

1,284 views · 7 days

top paths · /order 412 · / 388

top sources · google.com 214 · instagram.com 96

The order page had 412 views this week — counted as views, not people. Most visits came from Google.

By design.

  • One view per page load. In-app navigation in a single-page app is not a new view, so such an app under-counts.

  • Crawlers count like people. Bots are not classified: a crawler that sends no Do Not Track signal is a view.

  • No export and no webhook. Read the numbers in your dashboard or through your agent; there is no CSV and no webhook.

  • A collector with brakes. Views over the collector's per-minute ceilings are dropped, so a flood or a very large spike can under-count — and your page is never slowed down.

  • Automatic adding is for prebuilt static sites. A framework app, Next.js included, carries the line in its own layout; the switch adds nothing to it, and the Analytics page says so.

  • No engagement or Web Vitals. Bounce, time on page and loading metrics are not measured.

Paste one message. Online in 10 minutes.

Your app, its database, your domain and your sign-in — from the agent you already use.

Start free