Skip to content

Tag analytics events with is_bot (54 pages) + fix a SyntaxError in the homepage snippet - #3

Merged
kindrat86 merged 1 commit into
mainfrom
analytics/is-bot-flag
Aug 4, 2026
Merged

Tag analytics events with is_bot (54 pages) + fix a SyntaxError in the homepage snippet#3
kindrat86 merged 1 commit into
mainfrom
analytics/is-bot-flag

Conversation

@kindrat86

Copy link
Copy Markdown
Owner

Why

voicelogpro.com captured no bot signal at all, so traffic reports could not separate crawlers from customers.

posthog-js's built-in blocklist is narrower than it looks. It covers major search crawlers plus headlesschrome and cypress — but not curl, python-requests, ClaudeBot, CCBot, Applebot, Amazonbot, facebookexternalhit, Slackbot, Twitterbot, or generic bot/spider. Those are all captured today and counted as human. So the flag has real signal with no change to what gets captured.

Why before_send and not posthog.register()

This is a snippet-based static site: posthog.init is inlined into every page, and the shared /ux.js is defer — it runs after the inline snippet already fired $pageview. There is no single shared file to hook.

before_send is installed at init time and runs for every event, so it also covers the automatic $pageview fired inside init(). A register() call placed after init would miss exactly that event — the most important one. The verdict is cached on window, so the UA list is scanned once per page, not once per event.

Safety

The inserted code is a single self-contained expression inside the options object. An earlier version declared the detector as a statement before posthog.init(...); that silently breaks pages where init sits in a statement position (if(cond)posthog.init(...)) — the declaration becomes the if-body and the call loses its guard. My syntax guard caught that before anything was written.

Every rewritten page's inline script was extracted and checked with node --check against its own pre-edit baseline, so the gate is "did this sweep regress a page that previously parsed", not an absolute pass/fail: 0 regressions.

Deliberately biased toward false negatives — mislabelling a real visitor as a bot hides a lead, which costs more than an over-counted pageview. electron is excluded from the UA list for that reason.

Property name and boolean type match sanctionsai.dev and hirenika.com, so WHERE is_bot = false works portfolio-wide. No backfill is possible — queries spanning the cutover need is_bot != true.

🤖 Generated with Claude Code


⚠️ Second change: the homepage snippet did not parse

index.html shipped e.__SV=!0}(document,...missing the closing paren that matches e.__SV||(. That inline script threw SyntaxError: Unexpected token '}', so its posthog.init never ran.

Restoring the single ) makes it parse (verified with node --check). This was found while sweeping; carshake has the same defect on 121 pages and is being fixed separately.

…snippet

Two changes, both in the inline PostHog snippet.

1. is_bot flag (54 pages)

voicelogpro.com captured no bot signal, so traffic reports could not
separate crawlers from customers. posthog-js only blocks a narrow
default list (major search crawlers, headlesschrome, cypress); curl,
python-requests, ClaudeBot, CCBot, Applebot, facebookexternalhit,
Slackbot and generic bot/spider agents are all captured today and
counted as human.

Implemented as `before_send`, which is installed at init time and runs
for EVERY event -- including the automatic $pageview fired inside
init(). A posthog.register() call placed after init would miss exactly
that event. The verdict is cached on window, so the UA list is scanned
once per page rather than once per event. The inserted code is a single
self-contained expression inside the options object, so it is safe even
where init sits in a statement position.

2. Homepage snippet did not parse

index.html shipped `e.__SV=!0}(document,...` -- missing the closing
paren that matches `e.__SV||(`. That inline script threw
`SyntaxError: Unexpected token '}'`, so its posthog.init never ran.
Restoring the single `)` makes it parse; verified with `node --check`.
The same defect exists on carshake and was found while sweeping.

Every rewritten page's inline script was syntax-checked against its own
pre-edit baseline: 0 regressions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
voicelogpro Ready Ready Preview Aug 4, 2026 4:22pm
voicelogpro-integration Ready Ready Preview Aug 4, 2026 4:22pm
voicelogpro-mirror-v2 Ready Ready Preview Aug 4, 2026 4:22pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants