{"_id":"@adkit/google-ads-tracking","_rev":"3-beb815b024d672721686e6ae90d9de4f","name":"@adkit/google-ads-tracking","dist-tags":{"latest":"1.1.2"},"versions":{"1.1.0":{"name":"@adkit/google-ads-tracking","version":"1.1.0","keywords":["google-ads","conversion-tracking","google-ads-conversion-tracking","gtag","gtagjs","google-tag","tracking","analytics","typescript","javascript"],"author":"","license":"MIT","_id":"@adkit/google-ads-tracking@1.1.0","maintainers":[{"name":"jeannen","email":"nicolas@jeannen.com"}],"homepage":"https://adkit.so","bugs":{"url":"https://github.com/adkit/ads-tracking/issues"},"dist":{"shasum":"0c180f33bd81b74e743b4b679e8b52a57684cb59","tarball":"https://registry.npmjs.org/@adkit/google-ads-tracking/-/google-ads-tracking-1.1.0.tgz","fileCount":6,"integrity":"sha512-XxCedQMlIYkx9YYbXybXJxSt62dLq/9Qtm0LuMxRt5I1OCYH/bwvzdlJfgseNYuOrMX/G30KLywHdM0z+cIR6g==","signatures":[{"sig":"MEQCIGRKhH+GESA3xO2zmAgEkteQNPSLuLc/Ng8uCgytQxrZAiAKUwWmrqTlzbjTfJTavRqJbkWYX2P4FuNtsTLjK0J3hA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27005},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs"}},"scripts":{"test":"vitest run","build":"unbuild","prepack":"npm run build","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"jeannen","email":"nicolas@jeannen.com"},"repository":{"url":"git+https://github.com/adkit/ads-tracking.git","type":"git","directory":"packages/google-ads-tracking"},"_npmVersion":"11.4.2","description":"Google Ads conversion tracking for JavaScript and TypeScript. Zero-dependency gtag.js wrapper with eager, lazy, and manual script loading.","directories":{},"_nodeVersion":"23.7.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^24.0.0","vitest":"^3.2.7","unbuild":"^3.6.1","typescript":"^5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/google-ads-tracking_1.1.0_1785327293757_0.039562737359636335","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@adkit/google-ads-tracking","version":"1.1.1","keywords":["google-ads","conversion-tracking","google-ads-conversion-tracking","gtag","gtagjs","google-tag","tracking","analytics","typescript","javascript"],"author":"","license":"MIT","_id":"@adkit/google-ads-tracking@1.1.1","maintainers":[{"name":"jeannen","email":"nicolas@jeannen.com"}],"homepage":"https://adkit.so","bugs":{"url":"https://github.com/adkit/ads-tracking/issues"},"dist":{"shasum":"7a73fce1cff0bf5f18f083327314102fa55a9830","tarball":"https://registry.npmjs.org/@adkit/google-ads-tracking/-/google-ads-tracking-1.1.1.tgz","fileCount":6,"integrity":"sha512-xofuQ42fM0OIJM18Zmckf1nl7sqieRwdpeyGMd7r7QeMWtXhvFd66BBHhVAfeentvK9nwdaY8zFpajhh36ESNA==","signatures":[{"sig":"MEYCIQDoSrPcGCxUxIF4QPx+rNS5hVZwFpQy2Paw9CydXpnwUAIhALCi3pgLWr0IqccudoGM/O/wJfXpCo2RGTQy17NI4HII","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27008},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs"}},"gitHead":"29c938569d7399ae6110f022e737c4aeaaa3fcae","scripts":{"test":"vitest run","build":"unbuild","prepack":"npm run build","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"jeannen","email":"nicolas@jeannen.com"},"repository":{"url":"git+https://github.com/adkit/ads-tracking.git","type":"git","directory":"packages/js/google-ads-tracking"},"_npmVersion":"11.4.2","description":"Google Ads conversion tracking for JavaScript and TypeScript. Zero-dependency gtag.js wrapper with eager, lazy, and manual script loading.","directories":{},"_nodeVersion":"23.7.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^24.0.0","vitest":"^3.2.7","unbuild":"^3.6.1","typescript":"^5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/google-ads-tracking_1.1.1_1785328798647_0.4957881197264056","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@adkit/google-ads-tracking","version":"1.1.2","description":"Google Ads conversion tracking for JavaScript and TypeScript. Zero-dependency gtag.js wrapper with eager, lazy, and manual script loading.","homepage":"https://adkit.so","repository":{"type":"git","url":"git+https://github.com/adkit/conversion-tracking.git","directory":"packages/js/google-ads-tracking"},"type":"module","main":"./dist/index.mjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.mjs","types":"./dist/index.d.ts"}},"scripts":{"build":"unbuild","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","prepack":"npm run build"},"keywords":["google-ads","conversion-tracking","google-ads-conversion-tracking","gtag","gtagjs","google-tag","tracking","analytics","typescript","javascript"],"author":"","license":"MIT","publishConfig":{"access":"public"},"devDependencies":{"jsdom":"^24.0.0","typescript":"^5.9.3","unbuild":"^3.6.1","vitest":"^3.2.7"},"_id":"@adkit/google-ads-tracking@1.1.2","gitHead":"9088428717b71e58ed944f993ca21544bd7af84b","bugs":{"url":"https://github.com/adkit/conversion-tracking/issues"},"_nodeVersion":"23.7.0","_npmVersion":"11.4.2","dist":{"integrity":"sha512-Wfdgx0P6NVh9AJ7wa4++aKk10oqzA0B+xVC5Dp8GNK3iqZsiKCH5Wxn36buB8423NTc7tczNEpLuR0yuFG1s7Q==","shasum":"6cdba8bd975b282778ef0c8a9f9530ed9330b95c","tarball":"https://registry.npmjs.org/@adkit/google-ads-tracking/-/google-ads-tracking-1.1.2.tgz","fileCount":6,"unpackedSize":27311,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDSWdveMJnndEhligoA8OgpifiVEN0LjuSoTse94ZY6WwIhAMV7Lwrb44X/59T312/rspbINZitucTDNuQIrxAX2cr2"}]},"_npmUser":{"name":"jeannen","email":"nicolas@jeannen.com"},"directories":{},"maintainers":[{"name":"jeannen","email":"nicolas@jeannen.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/google-ads-tracking_1.1.2_1785384173076_0.11233459707632254"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-29T12:14:53.621Z","modified":"2026-07-30T04:02:53.373Z","1.1.0":"2026-07-29T12:14:53.910Z","1.1.1":"2026-07-29T12:39:58.788Z","1.1.2":"2026-07-30T04:02:53.232Z"},"bugs":{"url":"https://github.com/adkit/conversion-tracking/issues"},"license":"MIT","homepage":"https://adkit.so","keywords":["google-ads","conversion-tracking","google-ads-conversion-tracking","gtag","gtagjs","google-tag","tracking","analytics","typescript","javascript"],"repository":{"type":"git","url":"git+https://github.com/adkit/conversion-tracking.git","directory":"packages/js/google-ads-tracking"},"description":"Google Ads conversion tracking for JavaScript and TypeScript. Zero-dependency gtag.js wrapper with eager, lazy, and manual script loading.","maintainers":[{"name":"jeannen","email":"nicolas@jeannen.com"}],"readme":"# Google Ads Conversion Tracking for JavaScript & TypeScript\n\nTrack Google Ads conversions from any JavaScript or TypeScript app. A zero-dependency gtag.js wrapper, 1.2 KB gzipped, with eager, lazy, and manual script loading. Conversions fired before gtag.js loads are queued, not lost.\n\n[![npm version](https://img.shields.io/npm/v/@adkit/google-ads-tracking.svg)](https://www.npmjs.com/package/@adkit/google-ads-tracking)\n[![npm downloads](https://img.shields.io/npm/dm/@adkit/google-ads-tracking.svg)](https://www.npmjs.com/package/@adkit/google-ads-tracking)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nWorks with React, Next.js, Vue, Nuxt, Svelte, and plain JavaScript. Written in TypeScript, ships its own type definitions.\n\n## Install\n\n```bash\nnpm install @adkit/google-ads-tracking\n```\n\n## Quick start\n\n```typescript\nimport GOOGLE from '@adkit/google-ads-tracking';\n\n// 1. Initialize once, in your app entry point\nGOOGLE.init({ tagId: 'AW-XXXXXXXXXX' });\n\n// 2. Track a conversion anywhere in your app\nGOOGLE.trackConversion('AW-XXXXXXXXXX/CONVERSION_LABEL', {\n    value: 29.99,\n    currency: 'USD',\n});\n```\n\n`init()` installs Google's command queue and loads gtag.js from googletagmanager.com. `trackConversion()` sends a conversion event to Google Ads with an optional value, currency, and transaction ID.\n\n## Why not paste the gtag snippet?\n\nGoogle's copy-paste snippet works, but it gives you a blocking script in `<head>`, no types, and no control over when gtag.js loads. This wrapper fixes the parts that hurt in a real app:\n\n- **No lost conversions.** The command queue is installed synchronously during `init()`, in every loading mode. Conversions tracked before gtag.js arrives sit in the queue and are sent once it loads.\n- **Control when the script loads.** Load gtag.js immediately, after the page is idle, or only when you decide. See [script loading modes](#script-loading-modes).\n- **Typed API.** `GoogleTrackingConfig` and `ConversionParams` are exported, so wrong parameters fail at compile time instead of silently dropping data.\n- **Safe defaults.** Tracking is off on localhost by default, and `init()` is a no-op during server-side rendering, so it won't crash SSR frameworks.\n- **Debug mode.** Color-coded console logs show every init and conversion call during development.\n- **Small.** 1.2 KB gzipped, zero dependencies.\n\n## Script loading modes\n\n`loadMode` controls when the external gtag.js script is requested. The command queue is installed immediately in all three modes, so `trackConversion()` works the same everywhere.\n\n| Mode     | When gtag.js loads                                          | Use when                                             |\n| -------- | ----------------------------------------------------------- | ---------------------------------------------------- |\n| `eager`  | During `init()` (default)                                   | You want conversions reported as early as possible   |\n| `lazy`   | After the page `load` event, at the next idle moment        | You're protecting Core Web Vitals / page speed       |\n| `manual` | Only when you call `load()`                                 | You gate tracking behind cookie consent or a router  |\n\n```typescript\nGOOGLE.init({\n    tagId: 'AW-XXXXXXXXXX',\n    loadMode: 'manual',\n});\n\n// Queued in order, sent once gtag.js loads\nGOOGLE.trackConversion('AW-XXXXXXXXXX/CONVERSION_LABEL');\n\n// Safe to call more than once; the script is only requested once\nGOOGLE.load();\n```\n\nIn `lazy` mode the script waits for the page `load` event, then uses `requestIdleCallback` (with a 2 second timeout, falling back to `setTimeout` in browsers without idle callbacks). If the script fails to load, queued conversions are kept and `load()` can be called again.\n\n## Configuration\n\n| Option            | Type                            | Default   | Description                                                        |\n| ----------------- | ------------------------------- | --------- | ------------------------------------------------------------------ |\n| `tagId`           | `string \\| string[]`            | required  | Google tag ID, or several (e.g. `'AW-XXXXXXXXXX'`)                 |\n| `loadMode`        | `'eager' \\| 'lazy' \\| 'manual'` | `'eager'` | When to load the external gtag.js script                           |\n| `debug`           | `boolean`                       | `false`   | Log every init and conversion call to the console                  |\n| `enableLocalhost` | `boolean`                       | `false`   | Track on localhost (off by default so dev traffic stays out)       |\n\nMultiple Google Ads accounts:\n\n```typescript\nGOOGLE.init({ tagId: ['AW-FIRST_TAG', 'AW-SECOND_TAG'] });\n```\n\nEvery tag ID receives a `config` command. Conversions route by the `send_to` value you pass to `trackConversion()`.\n\n## Tracking conversions\n\n`trackConversion(conversionId, params?)` takes the full conversion ID (`AW-XXXXXXXXXX/CONVERSION_LABEL`, from your Google Ads conversion action) and optional parameters:\n\n| Parameter        | Type     | Description                                        | Example          |\n| ---------------- | -------- | -------------------------------------------------- | ---------------- |\n| `value`          | `number` | Monetary value of the conversion                   | `99.99`          |\n| `currency`       | `string` | ISO 4217 currency code                             | `'USD'`, `'EUR'` |\n| `transaction_id` | `string` | Unique ID so Google deduplicates repeat conversions | `'ORDER_12345'`  |\n\nCustom parameters pass through unchanged.\n\n```typescript\n// E-commerce purchase\nGOOGLE.trackConversion('AW-XXXXX/purchase_label', {\n    value: 149.99,\n    currency: 'USD',\n    transaction_id: 'order_abc123',\n});\n\n// Lead form submission (no value)\nGOOGLE.trackConversion('AW-XXXXX/lead_label');\n\n// Sign-up with a custom parameter\nGOOGLE.trackConversion('AW-XXXXX/signup_label', {\n    value: 10,\n    currency: 'USD',\n    new_customer: true,\n});\n```\n\n## Usage with React and Next.js\n\nInitialize once in your entry point, then call `trackConversion()` from event handlers.\n\n**React (Vite / CRA)**, in `main.tsx`:\n\n```typescript\nimport GOOGLE from '@adkit/google-ads-tracking';\n\nGOOGLE.init({ tagId: 'AW-XXXXXXXXXX', loadMode: 'lazy' });\n```\n\n**Next.js (App Router)**, in a client component mounted from your root layout:\n\n```typescript\n'use client';\nimport { useEffect } from 'react';\nimport GOOGLE from '@adkit/google-ads-tracking';\n\nexport function GoogleAdsTracking() {\n    useEffect(() => {\n        GOOGLE.init({ tagId: 'AW-XXXXXXXXXX', loadMode: 'lazy' });\n    }, []);\n    return null;\n}\n```\n\n`init()` checks for `window` and does nothing on the server, so importing it in SSR code is safe.\n\n## Usage with Vue and Nuxt\n\n**Vue**, in `main.ts`:\n\n```typescript\nimport GOOGLE from '@adkit/google-ads-tracking';\n\nGOOGLE.init({ tagId: 'AW-XXXXXXXXXX', loadMode: 'lazy' });\n```\n\n**Nuxt**, in a client-only plugin (`plugins/google-ads.client.ts`):\n\n```typescript\nimport GOOGLE from '@adkit/google-ads-tracking';\n\nexport default defineNuxtPlugin(() => {\n    GOOGLE.init({ tagId: 'AW-XXXXXXXXXX', loadMode: 'lazy' });\n});\n```\n\n## API reference\n\n| Method                               | Returns                        | What it does                                                          |\n| ------------------------------------ | ------------------------------ | --------------------------------------------------------------------- |\n| `init(config)`                       | `void`                         | Installs the gtag command queue, then loads gtag.js per `loadMode`    |\n| `trackConversion(id, params?)`       | `void`                         | Sends a Google Ads conversion event                                   |\n| `load()`                             | `void`                         | Requests gtag.js (for `manual` mode; safe to call repeatedly)         |\n| `isLoaded()`                         | `boolean`                      | `true` once the gtag command queue is installed                       |\n| `getConfig()`                        | `GoogleTrackingConfig \\| null` | The active configuration                                              |\n\nThe default export `GOOGLE` is a shared singleton. For separate instances (e.g. different tags per app section), use the factory:\n\n```typescript\nimport { createGoogleTracking } from '@adkit/google-ads-tracking';\n\nconst tracker = createGoogleTracking();\ntracker.init({ tagId: 'AW-XXXXXXXXXX' });\n```\n\n## TypeScript\n\nType definitions are bundled, no `@types` package needed.\n\n```typescript\nimport type { GoogleTrackingConfig, ConversionParams, GoogleTrackingLoadMode } from '@adkit/google-ads-tracking';\n```\n\n## Debug mode\n\nPass `debug: true` to `init()` to log every step with color-coded `[Google Tracking]` console messages: initialization, script loading, each conversion with its parameters, and warnings when a conversion is dropped.\n\n```typescript\nGOOGLE.init({\n    tagId: 'AW-XXXXXXXXXX',\n    debug: true,\n    enableLocalhost: true, // also track during local development\n});\n```\n\n## Migrating from @adkit.so/google-tracking\n\nThis package replaces [`@adkit.so/google-tracking`](https://www.npmjs.com/package/@adkit.so/google-tracking). The API is unchanged; `loadMode` is new.\n\n```bash\nnpm uninstall @adkit.so/google-tracking\nnpm install @adkit/google-ads-tracking\n```\n\nThen update the import:\n\n```diff\n- import GOOGLE from '@adkit.so/google-tracking';\n+ import GOOGLE from '@adkit/google-ads-tracking';\n```\n\nThe old package keeps working but won't receive new features.\n\n## FAQ\n\n### Do I need Google Tag Manager?\n\nNo. This library loads gtag.js directly, which is Google's recommended path for Google Ads conversion tracking without a tag management layer. If you already run GTM and fire conversions there, you don't need this package.\n\n### Can I track a conversion before gtag.js has loaded?\n\nYes. `init()` installs Google's command queue synchronously, so conversions are buffered in `window.dataLayer` in call order and sent when gtag.js processes the queue. This is what makes `lazy` and `manual` modes safe.\n\n### Why aren't my conversions showing in Google Ads?\n\nCommon causes, in order:\n\n1. Tracking is disabled on localhost by default. Set `enableLocalhost: true` to test locally.\n2. Wrong ID format. `init()` takes the tag ID (`AW-XXXXXXXXXX`), `trackConversion()` takes tag ID plus label (`AW-XXXXXXXXXX/CONVERSION_LABEL`).\n3. Google Ads reporting lags. Conversions can take up to 24 hours to appear.\n4. Ad blockers block googletagmanager.com. Test in a clean profile.\n5. The conversion action isn't set up or is inactive in Google Ads.\n\nTurn on `debug: true` and check the console, then verify the tag with [Google Tag Assistant](https://tagassistant.google.com/).\n\n### Does it work with server-side rendering?\n\nYes. `init()` returns early when `window` is undefined, so it's safe to import and call in Next.js, Nuxt, or any SSR framework. Tracking only runs in the browser.\n\n### How do I wait for cookie consent?\n\nUse `loadMode: 'manual'` and call `load()` after the user accepts. Conversions tracked in the meantime are queued locally. Note that queued commands live in `window.dataLayer`, so if your consent policy requires that nothing is prepared before opt-in, call `init()` itself after consent.\n\n### Does it slow down my page?\n\ngtag.js is always loaded `async`, and the wrapper itself is 1.2 KB gzipped. With `loadMode: 'lazy'` the script isn't even requested until after the page `load` event, keeping it out of your Core Web Vitals window.\n\n## Google Ads documentation\n\n- [Set up conversion tracking for your website](https://support.google.com/google-ads/answer/1722054)\n- [The Google tag for Google Ads conversion tracking](https://support.google.com/google-ads/answer/7548399)\n- [gtag.js API reference](https://developers.google.com/tag-platform/gtagjs/reference)\n- [Google Tag Assistant](https://tagassistant.google.com/)\n\n## Related packages\n\nThe Meta (Facebook) Pixel family uses the same wrapper approach:\n\n- [`@adkit/meta-pixel`](https://www.npmjs.com/package/@adkit/meta-pixel): JavaScript and TypeScript\n- [`@adkit/meta-pixel-react`](https://www.npmjs.com/package/@adkit/meta-pixel-react): React\n- [`@adkit/meta-pixel-next`](https://www.npmjs.com/package/@adkit/meta-pixel-next): Next.js\n- [`@adkit/meta-pixel-nuxt`](https://www.npmjs.com/package/@adkit/meta-pixel-nuxt): Nuxt\n\n## License\n\n[MIT](./LICENSE)\n\n---\n\nBuilt by [AdKit](https://adkit.so), the ad management platform for developers and small teams.\n","readmeFilename":"README.md"}