{"_id":"@alitycs/browser","name":"@alitycs/browser","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.3":{"name":"@alitycs/browser","version":"1.0.3","description":"Browser analytics SDK — auto-capture, beforeunload, snippet integration","main":"dist/index.js","module":"dist/index.esm.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.js","browser":"./dist/index.browser.js"},"./snippet":{"types":"./dist/browser.d.ts","default":"./dist/browser.min.js"},"./ga4":{"types":"./dist/ga4.d.ts","import":"./dist/ga4.esm.js","require":"./dist/ga4.js"},"./ga4/snippet":{"types":"./dist/ga4-browser.d.ts","default":"./dist/ga4.min.js"}},"sideEffects":["./dist/browser.min.js","./dist/ga4.min.js"],"scripts":{"build":"bun build src/index.ts --outfile=dist/index.esm.js --target=node --format=esm --external @alitycs/core","build:browser":"bun build src/index.ts --outfile=dist/index.browser.js --target=browser --format=esm --minify","build:browser-entry":"bun build src/browser.ts --outfile=dist/browser.min.js --target=browser --format=iife --minify --global=AlitycsSDK","build:ga4":"bun build src/ga4.ts --outfile=dist/ga4.esm.js --target=browser --format=esm --external @alitycs/core","build:ga4:cjs":"bun build src/ga4.ts --outfile=dist/ga4.js --target=node --format=cjs --external @alitycs/core","build:ga4:browser":"bun build src/ga4-browser.ts --outfile=dist/ga4.min.js --target=browser --format=iife --minify --global=AlitycsGA4Bundle","build:cjs":"bun build src/index.ts --outfile=dist/index.js --target=node --format=cjs --external @alitycs/core","build:types":"tsc -p tsconfig.build.json","build:all":"bun run build && bun run build:browser && bun run build:browser-entry && bun run build:ga4 && bun run build:ga4:cjs && bun run build:ga4:browser && bun run build:cjs && bun run build:types","test":"bun run build:ga4:browser && bun test","test:coverage":"bun run build:ga4:browser && bun test --coverage","test:unit":"bun test tests/unit","test:integration":"bun test tests/integration","dev":"bun run --hot src/index.ts","type-check":"tsc --noEmit","lint":"eslint src/**/*.ts tests/**/*.ts","lint:fix":"eslint src/**/*.ts tests/**/*.ts --fix","format":"prettier --write src/**/*.ts tests/**/*.ts","format:check":"prettier --check src/**/*.ts tests/**/*.ts"},"dependencies":{"@alitycs/core":"1.0.3"},"devDependencies":{"@eslint/js":"^10.0.1","@types/node":"^26.2.0","bun-types":"^1.3.10","eslint":"^10.8.1","globals":"^17.11.0","prettier":"^3.9.6","typescript-eslint":"^8.67.0","typescript":"^5.9.3"},"repository":{"type":"git","url":"git+https://github.com/alitycs/alitycs-sdk-js.git","directory":"sdks/browser"},"homepage":"https://github.com/alitycs/alitycs-sdk-js/tree/main/sdks/browser#readme","bugs":{"url":"https://github.com/alitycs/alitycs-sdk-js/issues"},"publishConfig":{"access":"public","provenance":true},"keywords":["analytics","tracking","browser","javascript","sdk","events","auto-capture"],"license":"MIT","engines":{"node":">=18.0.0","bun":">=1.0.0"},"_id":"@alitycs/browser@1.0.3","_integrity":"sha512-VZ+rEHPE8uKjwmqOMNx+kojuma93SsFIiQsBxhM12xopAqZ1GTlgOqi3ljYig8NKfI/gBK1mVlGEyQiTOo61dQ==","_resolved":"/Volumes/External/alitycs/.codex-tmp/npm-release-v1.0.3/alitycs-browser-1.0.3.tgz","_from":"file:/Volumes/External/alitycs/.codex-tmp/npm-release-v1.0.3/alitycs-browser-1.0.3.tgz","_nodeVersion":"24.14.0","_npmVersion":"11.18.0","dist":{"integrity":"sha512-VZ+rEHPE8uKjwmqOMNx+kojuma93SsFIiQsBxhM12xopAqZ1GTlgOqi3ljYig8NKfI/gBK1mVlGEyQiTOo61dQ==","shasum":"d4c6dc91cc2b1456a05f349e5c0b87ab6ceb4ad8","tarball":"https://registry.npmjs.org/@alitycs/browser/-/browser-1.0.3.tgz","fileCount":16,"unpackedSize":113470,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCzloN2z9sRDIrXZ7J5QigD2TR53VSJzdzxwc74hlClGwIgHcqkEUqPk9iGUxy9+ZbCasTOB1uSJUlZ8E+e6k3bYy4="}]},"_npmUser":{"name":"alitycs","email":"traivy.tech@gmail.com"},"directories":{},"maintainers":[{"name":"alitycs","email":"traivy.tech@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/browser_1.0.3_1788087409936_0.6175377617323894"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-30T10:56:49.800Z","1.0.3":"2026-08-30T10:56:50.082Z","modified":"2026-08-30T10:56:50.292Z"},"maintainers":[{"name":"alitycs","email":"traivy.tech@gmail.com"}],"description":"Browser analytics SDK — auto-capture, beforeunload, snippet integration","homepage":"https://github.com/alitycs/alitycs-sdk-js/tree/main/sdks/browser#readme","keywords":["analytics","tracking","browser","javascript","sdk","events","auto-capture"],"repository":{"type":"git","url":"git+https://github.com/alitycs/alitycs-sdk-js.git","directory":"sdks/browser"},"bugs":{"url":"https://github.com/alitycs/alitycs-sdk-js/issues"},"license":"MIT","readme":"# @alitycs/browser\n\nThe Alitycs browser SDK provides event tracking, page tracking, optional DOM auto-capture, and an opt-in GA4 compatibility bridge.\n\n## Installation\n\n```bash\nbun add @alitycs/browser\n# or: npm install @alitycs/browser\n```\n\nFor archive-based installation, install both `alitycs-core-1.0.3.tgz` and\n`alitycs-browser-1.0.3.tgz` from the matching\n[GitHub Release](https://github.com/alitycs/alitycs-sdk-js/releases). Browser applications must use\na publishable key; never embed a secret API key in client code.\n\n## Traffic page collection\n\nBrowser auto-capture is opt-in:\n\n```ts\nimport { init } from '@alitycs/browser';\n\nconst analytics = init({\n  apiKey: 'pk_live_replace_me',\n  autoCapture: true,\n});\n```\n\nWith `autoCapture: true`, the SDK emits one canonical `eventType: 'page'` event for the initial document and one for each `pushState`, `replaceState`, or `popstate` navigation. Each page event includes the full URL, hostname, path, title, and referrer; its context includes `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, and `utm_term`. A custom `page('Pricing')` name still has `eventType: 'page'`.\n\nQueued events use a bounded `fetch(..., { keepalive: true })` flush on `pagehide` and when the document becomes hidden. The publishable API key remains in the `Authorization` header. Call `shutdown()` only when permanently disposing the SDK; ordinary back/forward-cache navigation does not tear down auto-capture state.\n\n## GA4 compatibility bridge\n\nThe bridge observes the standard `dataLayer` used by `gtag.js` and Google Tag Manager, translates GA4 analytics commands to Alitycs, and leaves application call sites unchanged.\n\n### CDN setup\n\nMirror mode is the default. It sends translated events to Alitycs while leaving Google Analytics behavior intact:\n\n```html\n<script\n  async\n  src=\"https://cdn.alitycs.com/sdk@2/ga4.min.js\"\n  data-api-key=\"pk_live_replace_me\"\n  data-ga4-mode=\"mirror\"\n></script>\n```\n\nUse replace mode when Alitycs should be the analytics destination:\n\n```html\n<script\n  async\n  src=\"https://cdn.alitycs.com/sdk@2/ga4.min.js\"\n  data-api-key=\"pk_live_replace_me\"\n  data-ga4-mode=\"replace\"\n></script>\n```\n\nThe standalone bundle exposes:\n\n- `window.alitycs`: callable Alitycs API\n- `window.AlitycsSDK`: the `BrowserAlitycs` instance\n- `window.AlitycsGA4`: the installed bridge handle\n\nReplace mode creates `window.gtag` when it is absent. If existing application code can call `gtag()` before the async bridge loads, keep the usual queue bootstrap:\n\n```html\n<script>\n  window.dataLayer = window.dataLayer || [];\n  function gtag() {\n    dataLayer.push(arguments);\n  }\n</script>\n```\n\nSupported script attributes:\n\n| Attribute             | Default                          | Purpose                                              |\n| --------------------- | -------------------------------- | ---------------------------------------------------- |\n| `data-api-key`        | required                         | Alitycs API key                                      |\n| `data-endpoint`       | `https://api.alitycs.com/events` | Custom ingestion endpoint                            |\n| `data-debug`          | `false`                          | Bridge and SDK diagnostics                           |\n| `data-ga4-mode`       | `mirror`                         | `mirror` or `replace`                                |\n| `data-ga4-data-layer` | `dataLayer`                      | Custom data-layer name                               |\n| `data-ga4-pageviews`  | `true`                           | Set to `false` to disable bridge-generated pageviews |\n\n### Package setup\n\n```ts\nimport { BrowserAlitycs } from '@alitycs/browser';\nimport { installGa4Bridge } from '@alitycs/browser/ga4';\n\nconst sdk = BrowserAlitycs.init({ apiKey: 'pk_live_replace_me' });\nconst bridge = installGa4Bridge(sdk, {\n  mode: 'mirror',\n  capturePageViews: true,\n});\n\nbridge.getStats();\nbridge.uninstall();\n```\n\nInstalling the bridge twice on the same data layer returns the original handle. `uninstall()` restores the bridge-owned `dataLayer.push`, History API methods, listeners, and replace-mode `gtag` shim.\n\n### Translation behavior\n\n- Existing data-layer entries are processed once in FIFO order; future `push()` calls keep their native return value.\n- `gtag('event', name, params)` becomes `sdk.track(name, params)` with the exact GA event name.\n- `page_view` becomes `sdk.page('page_view', params)`. Initial and SPA pageviews are deduplicated by URL for one second.\n- Global `set`, per-measurement `config`, and persistent object-state parameters are merged with event parameters taking precedence.\n- `user_id` calls `identify()` once per distinct value.\n- Multiple GA destinations produce one Alitycs event. Google Ads/Floodlight-only destinations are ignored.\n- `js`, `consent`, `get`, and internal `gtm.*` commands do not create analytics events.\n- In replace mode, `event_callback` runs asynchronously once after the command is accepted. `get` returns locally cached values when available.\n\nEach translated event includes `alitycs_integration=ga4`, `ga4_bridge_mode`, and, when available, `ga4_target_id`. The bridge accepts up to 46 GA parameters so its metadata remains within the ingestion limit of 50 properties. Invalid, oversized, and excess parameters are dropped; `getStats().droppedInvalid` reports the number of dropped parameters.\n\n### Consent\n\nAnalytics storage is allowed until a GA consent command explicitly denies it. While `analytics_storage` is `denied`, analytics events and identity calls are dropped and are not buffered. A later grant does not replay them; when pageview capture is enabled, the bridge emits the current page once.\n\n### Mirror versus replace\n\nMirror mode is the migration-safe choice: Google continues handling the original data-layer command, including its callbacks, while Alitycs records a translated copy.\n\nReplace mode changes only the data destination used by code calling `gtag()` or `dataLayer.push()`. It does not block a Google script that is still loaded and does not disable GA tags inside GTM. Remove the Google loader or disable those tags to avoid continuing to send data to Google. In debug mode the bridge warns when it detects an active Google loader or tag manager.\n\nThe bridge intentionally does not reproduce GA Enhanced Measurement beyond pageviews, import historical GA data, synthesize Google client/session identifiers, or provide a GTM community template.\n\n## License\n\n[MIT](LICENSE)\n","readmeFilename":"README.md","_rev":"1-ff2420600fd569b193279460e346d0dc"}