# Installing web tracking

TractionScout Site Tracking collects page views and events from your own
website so Scout can see where visitors arrive, where they drop off, and
which pages lead to sign-ups or purchases. Everything is generated for your
project: the install code carries your project ID and a public ingest key
that only accepts browser analytics for that project.

Open **Configure → Data Sources** and choose **TractionScout Site Tracking**.
Select **Generate snippet** (later **Save setup**) to create the key and the
install code. A method picker shows the code for each platform, **Copy code**
copies the selected snippet, and **Rotate key** replaces the public key. The
same panel is also available on the **AI & Billing** tab.

## Before you paste anything: consent

The generated code starts with analytics consent set to denied. The tracker
records nothing until your site tells it that the visitor allowed analytics.
Connect your consent banner or manager using the **Consent integration**
example shown next to the install code:

```js
window.tractionscout("setConsent", {
  status: "granted",      // or "denied"
  analytics: true,        // the visitor's actual choice
  personalization: false,
  marketing: false,
  policy_version: ""
});
```

Call it once with the saved choice and again on every change. Withdrawal
stops collection and clears queued events. In the EU consent-required privacy
mode (**Configure → Privacy & tracking**) the tracker also runs cookieless and
disables outbound-link, form, download, and web-vitals collection.

## How verification works

The tracking source stays in the **planned** state after you generate the
code. It becomes **connected** the moment the first accepted event arrives,
whether from a browser page view or from a backend request. **Verify &
connect** refreshes that status and runs a diagnostic: TractionScout fetches
your website URL, checks that the script, the `window.tractionscout`
namespace, the `init` call, and your project ID are present in the HTML, and
records the HTTP status, content type, and any Content-Security-Policy header
it saw. The diagnostic panel explains what was found; it does not by itself
mark the source connected.

Localhost page views are ignored unless the tracked domain itself is local,
so verify from the published site.

## HTML

For static sites, custom HTML, Webflow, Framer, Shopify themes, Squarespace
code injection, or any CMS with a head-code field.

1. In the method picker choose **HTML** and select **Copy code**.
2. Open the site's global head, custom code, or theme layout editor.
3. Paste the snippet before the closing `</head>` tag on every page.
4. Publish, visit a tracked page, then select **Verify & connect**.

The snippet defines the `window.tractionscout` queue, calls `init` with your
project configuration, and loads `web.js` from your TractionScout host.

## WordPress

1. Install and activate a site-wide header snippet plugin such as WPCode
   (Insert Headers and Footers) or Header Footer Code Manager.
2. Create a new HTML/JavaScript snippet that runs site-wide in the
   head/header location.
3. Choose **WordPress** in the method picker, copy the code, paste it into
   the plugin, and save.
4. Clear any page cache and CDN cache, visit a public page, then select
   **Verify & connect**.

## Next.js

1. Choose **Next.js** in the method picker. The code is a
   `TractionScoutAnalytics` component built on `next/script` with two
   `afterInteractive` scripts: the inline `init` call and the tracker.
2. Create the component file or paste it into your shared layout.
3. Render `<TractionScoutAnalytics />` from `app/layout.tsx` or
   `pages/_app.tsx` so it loads once for the whole app.
4. Deploy, open the live site, then verify the first page view.

If you want requests to stay on your own domain, choose **Next.js proxy**
instead. That variant adds a route handler at
`app/api/tractionscout/[...path]/route.ts` that forwards to TractionScout
(dropping the `host` and `cookie` headers), and the component loads the
tracker from `/api/tractionscout/public/web.js`.

## Google Tag Manager

Prefer a direct head install when you control the site code; use this when
the site is managed through GTM.

1. Choose **Google Tag Manager** in the method picker and copy the code. It
   is a single script that runs `init` and injects the tracker script.
2. In GTM create a new **Custom HTML** tag and paste the snippet.
3. Set the trigger to **Initialization - All Pages**.
4. Publish the container, visit the site, then select **Verify & connect**.

## Cloudflare Worker

For sites already served behind Cloudflare. The Worker proxies the tracker
and the event endpoint under your own domain.

1. Choose **Cloudflare Worker**. The code has two parts: the Worker source
   and the site snippet to install after the Worker is live.
2. Create a Worker with the first part and add a route for
   `/tractionscout/*` on the tracked domain. The Worker forwards requests to
   your TractionScout host and removes the `cookie` header.
3. Deploy the Worker, then paste the second part before `</head>` on the
   site. It loads the tracker from `/tractionscout/public/web.js`.
4. Visit the live site and verify the first event. An **NGINX proxy**
   method with the same shape exists for servers you control.

## Server-side events

Choose **Backend observations** when a backend or worker should send events
directly. This method is a plain HTTP contract; you need no library.

1. Send `POST` requests to the project ingest URL shown in the snippet
   (`/tractionscout/public/projects/<project id>/ingest` on your
   TractionScout host) with `Content-Type: application/json` and the header
   `X-TractionScout-Key: <public ingest key>`.
2. Use the body shape from the generated `curl` example: `schema_version`
   `tractionscout.events.v1`, a `batch_id`, `sent_at`, and an `events` list.
   Each event has a `type`, a `consent` object with the visitor's actual
   choice, and a `payload` with `name`, `source_event_id`, `url`, and
   optional `metrics`.
3. Use stable `source_event_id` values so retries do not double count.
4. The example defaults consent to denied. Send `analytics: true` only when
   the visitor granted it; consent-required mode rejects events without it.

The first accepted backend event verifies the source just like a browser
event. Purchases and other financial outcomes that should qualify for
revenue attribution are not sent this way; they use the trusted server key
described next.

## Go SDK

A Go client for the trusted server endpoints exists and is used internally. It
authenticates with a separate server key that must never reach the browser.
TractionScout is not open source yet, so the package is not publicly
importable. During the alpha we hand it to testers on request as a source
archive with a short README; the public module path arrives with the open
source release. Until then, the server-side events contract above works from
any language with an HTTP client, and there is no Python or Node.js SDK.

1. Ask for the SDK archive through your onboarding contact, or use the HTTP
   contract.
2. Open the **Trusted Growth SDK** panel under the site tracking setup and
   create a trusted server key. Provide it to your service through an
   environment variable.
3. Create a client with your TractionScout base URL (HTTPS), project ID, and
   the server key, then call `Track` with one or more events. The client
   sends the `X-TractionScout-Server-Key` header for you. Accepted events
   through this path also mark the tracking source connected.

## Troubleshooting

**Cache plugins and CDNs.** The verification diagnostic reads the live HTML
of your website URL. If it reports that the script or `init` call is
missing after you pasted the code, purge the page cache and CDN cache and
run **Verify & connect** again.

**Ad blockers.** Some blockers stop third-party analytics scripts. The
first-party methods (Next.js proxy, Cloudflare Worker, NGINX proxy) serve
the tracker and event endpoint from your own domain; they never bypass
consent.

**Do Not Track and localhost.** The generated configuration sets
`respectDoNotTrack` to true, so browsers sending `DNT: 1` are not tracked.
Page views on `localhost` are ignored unless the tracked domain is local.
Test from another browser profile without DNT on the published site.

**Content Security Policy.** The diagnostic records the CSP header it saw.
If your policy restricts `script-src` or `connect-src`, allow your
TractionScout host for both, or use a first-party proxy method so the
script and event requests share your site's origin.

**Nothing arrives although the page loads the script.** Check that your
consent integration calls `setConsent` with `analytics: true` after the
visitor's choice; with the default denied state the tracker sends nothing.

See [Connecting your data sources](/docs/integrations.html) for the other
connectors and [Getting started](/docs/getting-started.html) for turning
the first data into a reviewable action.
