vasuki-traffic
v1.0.1
Published
Drop-in script that logs website visits (source, region, timestamp) into a Supabase table.
Maintainers
Readme
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-trackerhttps://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
<script src="https://unpkg.com/traffic-tracker"></script>
<script>
TrafficTracker.init("[email protected]"); // 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:
{
"id": "b3f1...uuid",
"domain": "yoursite.com",
"user_email": "[email protected]",
"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:
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_sourcequery 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, swapDEFAULT_GEO_ENDPOINTinindex.jsfor a paid geo-IP provider, or better: do geo lookup server-side from the request IP instead of client-side.
