# traffic-tracker

Drop-in script that logs every website visit — source, referrer, region/country/city, and exact timestamp — straight into your Supabase `traffic_manager` table. Supabase credentials are hardcoded in the script, so integrators only ever pass an email (optional).

## 1. Publish / host it

Publish to npm (`npm publish` from this folder), then it's automatically available on CDNs:

- `https://unpkg.com/traffic-tracker`
- `https://cdn.jsdelivr.net/npm/traffic-tracker`

(Rename the package in `package.json` first if `traffic-tracker` is taken.)

You can also just self-host `index.js` on any static host if you don't want to publish to npm.

## 2. Add it to your site

```html
<script src="https://unpkg.com/traffic-tracker"></script>
<script>
  TrafficTracker.init("user@email.com"); // or just TrafficTracker.init() if you don't have an email
</script>
```

Put it right before `</body>`. On every page load it inserts one row like:

```json
{
  "id": "b3f1...uuid",
  "domain": "yoursite.com",
  "user_email": "user@email.com",
  "traffic_data": "[{\"source\":\"google.com\",\"referrer\":\"https://google.com/\",\"page\":\"https://yoursite.com/pricing\",\"timestamp\":\"2026-07-17T09:41:12.104Z\",\"region\":\"Delhi\",\"country\":\"India\",\"city\":\"New Delhi\",\"ip\":\"1.2.3.4\",\"userAgent\":\"Mozilla/5.0...\"}, {\"source\":\"direct\",\"...\":\"second visit appended here\"}]"
}
```

`traffic_data` is a JSON **array** stored as a string (your column is `character varying`) — one entry per visit from that domain+email pair. On read: `JSON.parse(row.traffic_data)` gives you the full visit history for that user.

## 3. Required Supabase setup (important!)

Behavior: **one row per (domain, user_email) pair**. Every visit is appended to that row's `traffic_data` array instead of creating a new row each time — so the script needs to `SELECT`, `INSERT`, and `UPDATE` on this table using the anon key. Run this once in the Supabase SQL editor:

```sql
alter table public.traffic_manager enable row level security;

create policy "Allow anon read"
on public.traffic_manager
for select
to anon
using (true);

create policy "Allow anon insert"
on public.traffic_manager
for insert
to anon
with check (true);

create policy "Allow anon update"
on public.traffic_manager
for update
to anon
using (true)
with check (true);
```

Without these policies, reads/inserts/updates will silently fail with a 401/403 (check your browser console — the script logs any failed request there).

## 4. How source/region detection works

- **Source**: reads `utm_source` query param if present, otherwise the referring domain, otherwise `"direct"`.
- **Region**: looked up client-side via `ipapi.co` (free, no key needed) using the visitor's IP. Falls back to `"unknown"` if the lookup fails or is rate-limited.
- **Timestamp**: `new Date().toISOString()` at the moment the script runs.

## Notes / things to be aware of

- The Supabase URL and anon key are hardcoded directly in `index.js`. This is fine *only* because the anon key is Supabase's public, client-safe key by design — real access control comes from the RLS policy above, not from hiding this key. Anyone can view it by reading the script source (same as any client-side analytics script).
- This is a **client-side** tracker — it runs in the visitor's browser, so it won't catch bots that don't execute JS, and it's blockable by ad-blockers/privacy extensions (same limitation as Google Analytics etc.).
- `ipapi.co`'s free tier has a request-per-minute cap. For high-traffic sites, swap `DEFAULT_GEO_ENDPOINT` in `index.js` for a paid geo-IP provider, or better: do geo lookup server-side from the request IP instead of client-side.