“Pasted the array.js snippet into my SSR renderer; analytics live with zero build wiring”
I added PostHog to my static site the lazy way, and it just worked. There's no framework here doing the heavy lifting — my pages are server-rendered to plain HTML and baked into a dist folder at build time, so I had nowhere to drop a typical SDK. Instead I copied PostHog's array.js bootstrap snippet straight from their setup and pasted it into an analyticsHtml() helper in my render.ts. That helper reads a NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN env var, feeds it into window.posthog.init alongside the api_host, and returns the whole thing as an inline script string. I wired the helper into all four of my server-rendered page templates so every route emits the same loader. Then I ran the build. The snippet injected into all four pages straight from the baked HTML, and because posthog.init runs client-side, the analytics came up the moment a browser loaded a page — no server runtime involved at all. What sold me on the 4 was what I did NOT have to do. I never ran an install: there's no posthog dependency in my package.json, I verified that after the fact. No bundler entry, no plugin, no transform step, no async import to babysit. The array.js loader is self-contained — it stubs out the posthog object, queues calls, and pulls the real script from the assets host itself, so it doesn't care that my build has zero JS module wiring for it. For a baked-HTML site that's exactly the escape hatch you want; most analytics docs assume a bundler and quietly fail you when you don't have one. The capture worked on the first deploy with no follow-up debugging. The one real tradeoff, and why I held back the fifth star, is that this is a copy-paste string, not a typed module. Because the loader lives as raw script text inside my renderer, there's no compile-time safety on anything I send through it — if I fat-finger an event name in a capture call, nothing catches it. TypeScript can't see into a string, so a typo just silently produces a different event in the dashboard and I'd only find it later by noticing the data looked wrong. With the official typed SDK I'd at least get autocomplete and a red squiggle on a bad event name. So it's a clean trade: I saved all the build-config friction and got analytics shipped in one commit, but I gave up the type checking I'd lean on for anything beyond a handful of events. For a small SSR site where the event surface is tiny, that's the right call, and the snippet path is genuinely the fastest way I've integrated a product analytics tool. I'd reach for the typed module the day my event taxonomy gets big enough that a silent typo would actually cost me.
- No comments yet.