{"_id":"@bloomscorp/ngx-google-tag-manager","_rev":"2-a52e719916f7da0a50c7c38f7bf19a56","name":"@bloomscorp/ngx-google-tag-manager","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@bloomscorp/ngx-google-tag-manager","version":"1.0.0","keywords":["angular","google-tag-manager","gtm","ssr","server-side-rendering","angular-ssr","nguniversal","analytics"],"author":{"name":"Bloomscorp"},"license":"MIT","_id":"@bloomscorp/ngx-google-tag-manager@1.0.0","maintainers":[{"name":"debacharya","email":"debabrata@bloomscorp.com"},{"name":"blacklist96","email":"ayankumarsaha96@gmail.com"},{"name":"deepdey20998","email":"deepdey20998@gmail.com"}],"homepage":"https://github.com/bloomscorp/ngx-google-tag-manager#readme","bugs":{"url":"https://github.com/bloomscorp/ngx-google-tag-manager/issues"},"dist":{"shasum":"d98c193fd00de03761c019514a1e544756f54029","tarball":"https://registry.npmjs.org/@bloomscorp/ngx-google-tag-manager/-/ngx-google-tag-manager-1.0.0.tgz","fileCount":19,"integrity":"sha512-ACKF35oYpQAeA40J5iaJ5c4PPT5yz76p+j/I7h+g5vJXi+5ytQMVZYBHOUmXk7+A6viGM6BGsdGHl4aUHPeQgA==","signatures":[{"sig":"MEUCIFxD25GE6COSVWR7KVye0eWufxIe4+K2bdtn22z2YS8iAiEAmF3iMhoAVfzd+5055MXfASdnjpOGb4JP3RnOEiwmiq8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":85109},"module":"fesm2022/bloomscorp-ngx-google-tag-manager.mjs","exports":{".":{"esm":"./esm2022/bloomscorp-ngx-google-tag-manager.mjs","types":"./index.d.ts","default":"./fesm2022/bloomscorp-ngx-google-tag-manager.mjs","esm2022":"./esm2022/bloomscorp-ngx-google-tag-manager.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"ba53f637c49c7bfcab351211d49b18ff21a958dc","typings":"index.d.ts","_npmUser":{"name":"debacharya","email":"debabrata@bloomscorp.com"},"repository":{"url":"git+https://github.com/bloomscorp/ngx-google-tag-manager.git","type":"git"},"_npmVersion":"10.9.0","description":"SSR-safe Google Tag Manager integration for Angular 18+ (and the latest Angular). Drop-in compatible with angular-google-tag-manager, but never touches the global window/document — works with both @nguniversal/express-engine (legacy SSR) and @angular/ssr ","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","dependencies":{"tslib":"^2.6.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ngx-google-tag-manager_1.0.0_1783389325105_0.21694301511664893","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@bloomscorp/ngx-google-tag-manager","version":"1.0.1","description":"SSR-safe Google Tag Manager integration for Angular 18+ (and the latest Angular). Drop-in compatible with angular-google-tag-manager, but never touches the global window/document — works with both @nguniversal/express-engine (legacy SSR) and @angular/ssr ","keywords":["angular","google-tag-manager","gtm","ssr","server-side-rendering","angular-ssr","nguniversal","analytics"],"author":{"name":"Bloomscorp"},"license":"MIT","homepage":"https://github.com/bloomscorp/ngx-google-tag-manager#readme","bugs":{"url":"https://github.com/bloomscorp/ngx-google-tag-manager/issues"},"repository":{"type":"git","url":"git+https://github.com/bloomscorp/ngx-google-tag-manager.git"},"peerDependencies":{"@angular/common":">=18.0.0","@angular/core":">=18.0.0"},"dependencies":{"tslib":"^2.6.0"},"publishConfig":{"access":"public"},"sideEffects":false,"module":"fesm2022/bloomscorp-ngx-google-tag-manager.mjs","typings":"index.d.ts","exports":{"./package.json":{"default":"./package.json"},".":{"types":"./index.d.ts","esm2022":"./esm2022/bloomscorp-ngx-google-tag-manager.mjs","esm":"./esm2022/bloomscorp-ngx-google-tag-manager.mjs","default":"./fesm2022/bloomscorp-ngx-google-tag-manager.mjs"}},"_id":"@bloomscorp/ngx-google-tag-manager@1.0.1","gitHead":"45aae6e4d93ce0a0e941d649213ffe75386c1cc1","_nodeVersion":"22.12.0","_npmVersion":"10.9.0","dist":{"integrity":"sha512-CP0xj0rfzkYY1kyBXyvGs+MqeIaOYxKdSCCN62l7XjHcVi70LZxrLgqJb+Ub0q37Nhp0gxoiXSxRsfXtDGKfrA==","shasum":"8307ea4f7f600939a0ad8f8553ae9c69b35ca33f","tarball":"https://registry.npmjs.org/@bloomscorp/ngx-google-tag-manager/-/ngx-google-tag-manager-1.0.1.tgz","fileCount":19,"unpackedSize":100625,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCqwuGQqGLYlsyLh5WAU1O4YvdKGSlhIJ5OPmH2R1Er6gIhAOrVsEo0U1HHUQiXON8Bqa9suHTACbcmBZkZh6Ybm674"}]},"_npmUser":{"name":"debacharya","email":"debabrata@bloomscorp.com"},"directories":{},"maintainers":[{"name":"debacharya","email":"debabrata@bloomscorp.com"},{"name":"blacklist96","email":"ayankumarsaha96@gmail.com"},{"name":"deepdey20998","email":"deepdey20998@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ngx-google-tag-manager_1.0.1_1784055528327_0.32694646693363594"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-07T01:55:24.946Z","modified":"2026-07-14T18:58:48.703Z","1.0.0":"2026-07-07T01:55:25.243Z","1.0.1":"2026-07-14T18:58:48.484Z"},"bugs":{"url":"https://github.com/bloomscorp/ngx-google-tag-manager/issues"},"author":{"name":"Bloomscorp"},"license":"MIT","homepage":"https://github.com/bloomscorp/ngx-google-tag-manager#readme","keywords":["angular","google-tag-manager","gtm","ssr","server-side-rendering","angular-ssr","nguniversal","analytics"],"repository":{"type":"git","url":"git+https://github.com/bloomscorp/ngx-google-tag-manager.git"},"description":"SSR-safe Google Tag Manager integration for Angular 18+ (and the latest Angular). Drop-in compatible with angular-google-tag-manager, but never touches the global window/document — works with both @nguniversal/express-engine (legacy SSR) and @angular/ssr ","maintainers":[{"name":"debacharya","email":"debabrata@bloomscorp.com"},{"name":"blacklist96","email":"ayankumarsaha96@gmail.com"},{"name":"deepdey20998","email":"deepdey20998@gmail.com"}],"readme":"# @bloomscorp/ngx-google-tag-manager\n\n[![npm version](https://img.shields.io/npm/v/@bloomscorp/ngx-google-tag-manager.svg)](https://www.npmjs.com/package/@bloomscorp/ngx-google-tag-manager)\n[![license](https://img.shields.io/npm/l/@bloomscorp/ngx-google-tag-manager.svg)](./LICENSE)\n[![Angular](https://img.shields.io/badge/Angular-%3E%3D18-DD0031?logo=angular&logoColor=white)](https://angular.dev)\n\n**SSR-safe Google Tag Manager integration for Angular 18+ (and the latest Angular).**\n\nA hardened, open-source fork of [`angular-google-tag-manager`](https://github.com/mzuccaroli/angular-google-tag-manager). It keeps the **exact same public API** (drop-in replacement) but fixes the one thing that breaks server-side rendering: the original reads the **global** `window` / `document`, which do not exist on the server.\n\n## Features\n\n- ✅ **SSR-safe** — never touches global `window` / `document`; renders server-side without `document is not defined`.\n- ✅ **Works with both SSR runtimes** — the legacy `@nguniversal/express-engine` **and** the modern `@angular/ssr`.\n- ✅ **Injects GTM into server-rendered HTML** — the loader is in the first byte the client receives, with duplicate-guarding on hydration.\n- ✅ **Angular 18 → latest** — peer range `>=18.0.0`.\n- ✅ **Drop-in** — identical exported symbols; migrate by changing the import path only.\n- ✅ **Standalone & NgModule** APIs, zero runtime dependencies beyond `tslib`.\n\n## Table of contents\n\n- [Why this fork exists — SSR safety](#why-this-fork-exists--ssr-safety)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Configuration](#configuration)\n- [Migrating from `angular-google-tag-manager`](#migrating-from-angular-google-tag-manager)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Why this fork exists — SSR safety\n\nThe original service does this:\n\n```ts\nprivate browserGlobals = {\n  windowRef() { return window; },     // ReferenceError on the server\n  documentRef() { return document; }, // ReferenceError on the server\n};\n```\n\nDuring SSR, `window` and `document` are not defined, so any code path that reaches them throws `window is not defined` / `document is not defined`.\n\nThis library instead:\n\n- **Injects the `DOCUMENT` token** from `@angular/common` rather than reading the global `document`. The `DOCUMENT` token is provided by **both** SSR runtimes:\n  - the **legacy** `@nguniversal/express-engine` (Angular ≤ 16), and\n  - the **modern** `@angular/ssr` (Angular 17+).\n- Derives the window from `DOCUMENT.defaultView` instead of the global `window` (no dependency on `PLATFORM_ID`).\n\n### Server-side injection (renders the GTM tag into SSR HTML)\n\nBecause it operates on the injected `DOCUMENT`, `addGtmToDom()` injects the GTM\n`<script>` on **both the server and the browser**. On a live-SSR route the loader is\nwritten straight into the server-rendered HTML, so GTM is present in the first byte the\nclient receives (per Google's \"as high in `<head>` as possible\" guidance) instead of\nwaiting for Angular to bootstrap.\n\nTwo SSR hazards are handled so this is safe:\n\n- **No duplicate on hydration** — if the loader was already rendered server-side,\n  the browser re-run sees the existing `#GTMscript` and resolves instead of injecting a\n  second copy.\n- **Promise resolves on the server** — the script `load` event only fires in a live\n  browser, so when there is no live window (`DOCUMENT.defaultView == null`) the promise\n  resolves as soon as the tag is inserted, rather than hanging forever.\n\n> ⚠️ **Server-rendered routes only.** If a route is served as a **prerendered/static**\n> file (e.g. via `express.static` before your SSR handler), Angular does not run on the\n> server for that request, so nothing — this library included — can inject the tag for\n> it. Such routes get the tag client-side on hydration.\n\n## Installation\n\n```bash\nnpm install @bloomscorp/ngx-google-tag-manager\n```\n\nPeer dependencies: `@angular/common >=18.0.0`, `@angular/core >=18.0.0`.\n\n## Usage\n\n### Standalone (recommended, Angular 18+)\n\n```ts\nimport { provideGoogleTagManager } from '@bloomscorp/ngx-google-tag-manager';\n\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    provideGoogleTagManager({ id: 'GTM-XXXXXXX' }),\n  ],\n};\n```\n\n### NgModule\n\n```ts\nimport { GoogleTagManagerModule } from '@bloomscorp/ngx-google-tag-manager';\n\n@NgModule({\n  imports: [\n    GoogleTagManagerModule.forRoot({ id: 'GTM-XXXXXXX' }),\n  ],\n})\nexport class AppModule {}\n```\n\n### Injecting GTM and pushing events\n\n```ts\nimport { GoogleTagManagerService } from '@bloomscorp/ngx-google-tag-manager';\n\nconstructor(private gtm: GoogleTagManagerService) {}\n\nngOnInit(): void {\n  // Injects the GTM script — into the server-rendered HTML on live-SSR routes,\n  // and in the browser. Safe to call from either environment; it de-dupes on hydration.\n  this.gtm.addGtmToDom();\n}\n\naddToCart(): void {\n  this.gtm.pushTag({ event: 'add_to_cart', /* ... */ });\n}\n```\n\n## Configuration\n\n```ts\ninterface GoogleTagManagerConfig {\n  id: string | null;\n  gtm_auth?: string;\n  gtm_preview?: string;\n  gtm_resource_path?: string;\n  gtm_csp_none?: string;            // CSP nonce\n  gtm_mode?: 'silent' | 'noisy';    // 'silent' = don't throw when id missing\n  [key: string]: string | null | undefined;\n}\n```\n\n### Public API\n\n| Symbol | Kind | Purpose |\n| --- | --- | --- |\n| `provideGoogleTagManager(config)` | function | Standalone provider (Angular 18+). |\n| `GoogleTagManagerModule.forRoot(config)` | NgModule | Classic module registration. |\n| `GoogleTagManagerService` | service | `addGtmToDom()`, `pushTag()`, `getDataLayer()`. |\n| `GoogleTagManagerConfiguration` | service | Dynamic config holder. |\n| `GoogleTagManagerConfigService` | token | DI token for the config. |\n| `GoogleTagManagerConfig` | interface | Config shape. |\n\n## Migrating from `angular-google-tag-manager`\n\nThe public API is identical, so only the import path changes:\n\n```diff\n- import { GoogleTagManagerService } from 'angular-google-tag-manager';\n+ import { GoogleTagManagerService } from '@bloomscorp/ngx-google-tag-manager';\n```\n\n```diff\n- import { GoogleTagManagerModule } from 'angular-google-tag-manager';\n+ import { GoogleTagManagerModule } from '@bloomscorp/ngx-google-tag-manager';\n```\n\nExported symbols (unchanged): `GoogleTagManagerService`, `GoogleTagManagerModule`, `provideGoogleTagManager`, `GoogleTagManagerConfig`, `GoogleTagManagerConfiguration`, `GoogleTagManagerConfigService`.\n\n## Contributing\n\nContributions are welcome! This is a standard Angular library workspace.\n\n```bash\n# clone & install\ngit clone https://github.com/bloomscorp/ngx-google-tag-manager.git\ncd ngx-google-tag-manager\nnpm install\n\n# build the library -> dist/ngx-google-tag-manager\nnpm run build\n\n# produce an installable tarball for local testing in another app\nnpm run pack:lib\n```\n\nThe library source lives in `projects/ngx-google-tag-manager/src/`. Please open an issue\nto discuss substantial changes before sending a PR, keep the public API drop-in compatible,\nand make sure the library still builds cleanly under SSR.\n\n### Publishing (maintainers)\n\n```bash\nnpm run build\nnpm publish dist/ngx-google-tag-manager   # publishConfig.access is already \"public\"\n```\n\n## License\n\n[MIT](./LICENSE) © Bloomscorp\n","readmeFilename":"README.md"}