{"_id":"@admaxxer/pixel","_rev":"2-9e18c6f7b8dbad6fb9968d8147d15171","name":"@admaxxer/pixel","dist-tags":{"latest":"0.5.1"},"versions":{"0.5.0":{"name":"@admaxxer/pixel","version":"0.5.0","license":"MIT","_id":"@admaxxer/pixel@0.5.0","maintainers":[{"name":"admaxxer","email":"hello@admaxxer.com"}],"homepage":"https://github.com/fortuneflick/admaxxer-pixel#readme","bugs":{"url":"https://github.com/fortuneflick/admaxxer-pixel/issues"},"dist":{"shasum":"00b8c661c54f3961c23dea400fc4b9047da1ef21","tarball":"https://registry.npmjs.org/@admaxxer/pixel/-/pixel-0.5.0.tgz","fileCount":6,"integrity":"sha512-8mPyiUBHfTo1qGPBlQlL/52CDkQbTIdQ9X2Q5PDSR7MhYePSDM35eF7dG0cnt2P7+u1dDSe0PX3aKVSVabawmg==","signatures":[{"sig":"MEUCIQDAeN0ujFYgnAUVo6kIgsPcC3rOiGr2NJo4jFTxZZ2r+wIgL7fegVtJRy6eqGvBOqYH4efoi0M8IyMFDVNOls1Akro=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17703},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"caa67ad670519ee96ba60025b326d88086ed3cb9","private":false,"scripts":{"build":"tsup src/index.ts --format esm,cjs --dts"},"_npmUser":{"name":"admaxxer","email":"hello@admaxxer.com"},"repository":{"url":"git+https://github.com/fortuneflick/admaxxer-pixel.git","type":"git"},"_npmVersion":"11.8.0","description":"Admaxxer analytics SDK — SSR-safe initPixel + identify + track for framework apps (Next.js, Remix, SvelteKit, Nuxt, Vue, React).","directories":{},"_nodeVersion":"24.13.1","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8","typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/pixel_0.5.0_1780223172662_0.6940838968729686","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@admaxxer/pixel","version":"0.5.1","description":"Admaxxer analytics SDK — SSR-safe initPixel + identify + track for framework apps (Next.js, Remix, SvelteKit, Nuxt, Vue, React).","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./package.json":"./package.json"},"repository":{"type":"git","url":"git+https://github.com/fortuneflick/admaxxer-pixel.git"},"license":"MIT","private":false,"scripts":{"build":"tsup src/index.ts --format esm,cjs --dts"},"devDependencies":{"tsup":"^8","typescript":"^5"},"gitHead":"47618e4dfab03cefaa8066d41514241cb2f5918f","_id":"@admaxxer/pixel@0.5.1","bugs":{"url":"https://github.com/fortuneflick/admaxxer-pixel/issues"},"homepage":"https://github.com/fortuneflick/admaxxer-pixel#readme","_nodeVersion":"24.13.1","_npmVersion":"11.8.0","dist":{"integrity":"sha512-HC7RcuI+xX7E+O0XG8/CIzTk/yvFXp0bW4AiBT0HfmvinTaFOu4/MsZcTCdIDHxw+A6/gB6i6+3Sbwuv4rVnmQ==","shasum":"07d61e6f8e998495ae0221686c334c492e58f3d3","tarball":"https://registry.npmjs.org/@admaxxer/pixel/-/pixel-0.5.1.tgz","fileCount":6,"unpackedSize":17743,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCQRictI5ETwE+QHPu2CjG5Hq/N3kOhZsTmVN453eX5UQIgfQvugxfsD5ByMfYWtG0G15xfWjf993Zum9klpQxyqwQ="}]},"_npmUser":{"name":"admaxxer","email":"hello@admaxxer.com"},"directories":{},"maintainers":[{"name":"admaxxer","email":"hello@admaxxer.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pixel_0.5.1_1780223649304_0.04586216508342189"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-31T10:26:12.425Z","modified":"2026-05-31T10:34:09.549Z","0.5.0":"2026-05-31T10:26:12.788Z","0.5.1":"2026-05-31T10:34:09.469Z"},"bugs":{"url":"https://github.com/fortuneflick/admaxxer-pixel/issues"},"license":"MIT","homepage":"https://github.com/fortuneflick/admaxxer-pixel#readme","repository":{"type":"git","url":"git+https://github.com/fortuneflick/admaxxer-pixel.git"},"description":"Admaxxer analytics SDK — SSR-safe initPixel + identify + track for framework apps (Next.js, Remix, SvelteKit, Nuxt, Vue, React).","maintainers":[{"name":"admaxxer","email":"hello@admaxxer.com"}],"readme":"# @admaxxer/pixel\n\nThe official **SSR-safe** analytics SDK for the [Admaxxer](https://admaxxer.com)\npixel. Drop it into any framework — Next.js, Remix, SvelteKit, Nuxt, Vue, React,\nGatsby, SolidStart — and call `identify()` / `track()` anywhere, including from\nserver components or at module top-level, with **no `typeof window` guards**.\n\n> **Why an SDK and not just the `<script>` tag?** In an SSR framework, calling\n> `window.admaxxer.identify(...)` directly from a component crashes during\n> server render (`window is not defined`) and races the deferred script's load.\n> Every export here is SSR-safe: it no-ops when there's no `window`, and\n> **buffers** your calls until the hosted pixel has loaded, then replays them in\n> order.\n\n## Install\n\n```sh\nnpm install @admaxxer/pixel\n```\n\n## Quick start\n\n```ts\nimport { initPixel, identify, track } from '@admaxxer/pixel';\n\n// 1. Boot the pixel once (e.g. in your root layout / app entry).\ninitPixel({ websiteId: 'YOUR_WEBSITE_ID' });\n\n// 2. Identify the user when they sign up or on any authenticated page load.\nidentify(user.email);\n\n// 3. Fire funnel events at each step.\ntrack('trial_started', { plan: 'pro' });\n```\n\nFind your `websiteId` (an `admx_…` value) in your Admaxxer dashboard under\n**Pixel**.\n\n## The three exports (all SSR-safe)\n\n### `initPixel({ websiteId, endpoint? })`\n\nInjects the hosted pixel `<script>` into the current document. SSR-safe (no-ops\non the server) and idempotent (safe to call more than once — injection is\nguarded). Call it once, early in your app.\n\n```ts\nimport { initPixel } from '@admaxxer/pixel';\n\ninitPixel({ websiteId: 'YOUR_WEBSITE_ID' });\n```\n\nOptional `endpoint` lets you point at a first-party proxy or a non-default\nscript variant (e.g. `script.plus.js`, `script.cookieless.js`, `script.hash.js`).\nIt must be an `https://` URL and is a trusted-caller option — never pass user\ninput.\n\n```ts\ninitPixel({\n  websiteId: 'YOUR_WEBSITE_ID',\n  endpoint: 'https://your-domain.com/js/script.js',\n});\n```\n\n### `identify(idOrEmail, traits?)`\n\nLinks the anonymous visitor in the current browser to a known user — the stitch\nthat ties the original ad click to the paying customer, so future revenue is\nattributed to the channel that acquired them. Pass an email, or a stable user id\nplus traits. Idempotent — safe to call on every authenticated page load.\n\n```ts\nimport { identify } from '@admaxxer/pixel';\n\n// By email:\nidentify(user.email);\n\n// By stable id + traits:\nidentify(user.id, {\n  email: user.email,\n  plan: user.plan,\n  signed_up_at: user.createdAt,\n});\n```\n\n### `track(eventName, props?)`\n\nFires a custom funnel/goal event. Pass any plain-object props you want to\nsegment by later.\n\n```ts\nimport { track } from '@admaxxer/pixel';\n\ntrack('signup');\ntrack('trial_started', { plan: 'pro' });\ntrack('subscription_started', { plan: 'annual', mrr: 49 });\ntrack('activated', { milestone: 'first_project_created' });\n```\n\n> The default export is `initPixel` (back-compat with v0.4.x).\n\n## SaaS funnel example\n\nA complete SaaS funnel — install once, identify on signup, then fire an event at\neach stage. Every call below is SSR-safe, so this works unchanged whether it runs\non the server or the client:\n\n```ts\nimport { initPixel, identify, track } from '@admaxxer/pixel';\n\n// On app start:\ninitPixel({ websiteId: 'YOUR_WEBSITE_ID' });\n\n// On signup — the load-bearing call that attributes all future revenue:\nfunction onSignup(user) {\n  identify(user.id, { email: user.email, plan: user.plan });\n  track('signup');\n}\n\n// As the user moves through your funnel:\ntrack('trial_started', { plan: 'pro' });\ntrack('subscription_started', { plan: 'pro', mrr: 49 });\n```\n\n### Revenue / MRR comes from Stripe, not the pixel\n\nYou do **not** track subscription dollars with `track()`. Recurring revenue —\npaid conversions, MRR, and cancellations — flows in automatically once you\nconnect Stripe with a restricted key in your Admaxxer dashboard. The events\nabove are the **funnel + attribution** layer; Stripe is the **revenue** layer,\nand the two are stitched together by the `identify()` call. See the\n[SaaS analytics guide](https://admaxxer.com/documentation/saas-analytics) for\nthe full walkthrough.\n\n## Notes\n\n- **SSR-safe everywhere.** All three exports no-op during server render and\n  buffer until the pixel loads, then replay in order. No `typeof window` guards\n  needed.\n- **`initPixel` is idempotent** — repeat calls are no-ops (injection is guarded\n  by a `data-admaxxer-loaded` attribute on the injected `<script>`).\n- **Sandbox runtimes.** `initPixel` also no-ops in sandboxed JS runtimes that\n  expose a stub `document` without a real DOM (Cloudflare Workers, Vercel Edge,\n  Bun `--eval`). It fails closed rather than throwing into your request handler.\n- **First-party cookies.** Cookies set by the pixel are scoped to your own\n  origin (the page that loads the script), not to `admaxxer.com`.\n\n## Plain (non-framework) sites\n\nIf you're not using a bundler, you don't need this package — add the hosted\n`<script>` to your `<head>` and use the `window.admaxxer` global it installs. If\nyou ever call that global from code that might run during a server render,\nguard it:\n\n```js\nif (typeof window !== 'undefined') {\n  window.admaxxer.identify(user.email);\n  window.admaxxer('trial_started', { plan: 'pro' });\n}\n```\n\n## Version history\n\n- **0.5.0** — Added the SSR-safe `identify()` and `track()` exports alongside\n  `initPixel`. Calls are buffered until the pixel loads and replayed in order,\n  so you can call them anywhere in a framework app with no guards.\n- **0.4.0** — `initPixel` now silently no-ops in sandboxed JS runtimes that\n  expose a stub `document` without a real DOM (Cloudflare Workers, Vercel Edge,\n  Bun `--eval`), instead of throwing.\n- **0.3.0** — Fixed the hosted script URL the loader injects so events actually\n  send. Earlier versions shipped zero events; upgrade if you're below 0.3.0.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}