@owlmeans/web-gtm 0.1.18-rc.34 → 0.1.18-rc.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
6
6
  your project's skill store (`.agents/skills/`):
7
7
 
8
8
  ```sh
9
- npx @owlmeans/agent-skills@^0.1.18-rc.48
9
+ npx @owlmeans/agent-skills@^0.1.18-rc.49
10
10
  ```
11
11
 
12
12
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/web-gtm",
4
- "version": "0.1.18-rc.34",
5
- "generatedAt": "2026-10-05T08:32:19.091Z",
4
+ "version": "0.1.18-rc.35",
5
+ "generatedAt": "2026-10-05T21:03:06.368Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: web-gtm
3
- description: How to use @owlmeans/web-gtm — the Google tag head snippet for every Google id (Tag Manager GTM-, GA4 G-, Google tag GT-, Ads AW-, Floodlight DC-) that declares Consent Mode defaults before any loader runs, the id validator, the CSP host lists, the cookie-policy disclosure for a tag, the noscript frame, and the script-side loader for a host that cannot edit its own HTML. Auto-invoked when adding a Google tag or tag manager to a page, importing googleTagHeadScript, isGoogleTagId, GOOGLE_TAG_CSP_SOURCES, googleTagServices, gtmHeadScript, gtmNoscriptFrame or loadGtm, or debugging why a tag ignores a stored consent decision or is blocked by CSP.
3
+ description: How to use @owlmeans/web-gtm — the Google tag head snippet for every Google id (Tag Manager GTM-, GA4 G-, Google tag GT-, Ads AW-, Floodlight DC-) that declares Consent Mode defaults before any loader runs, the id validator, the CSP host lists, the cookie-policy disclosure for a tag, the noscript frame, and the script-side loader for a host that cannot edit its own HTML. Auto-invoked when adding a Google tag or tag manager to a page, importing googleTagHelper (googleTagHeadScript, isGoogleTagId, googleTagServices, gtmHeadScript, gtmNoscriptFrame, loadGtm) or GOOGLE_TAG_CSP_SOURCES, or debugging why a tag ignores a stored consent decision or is blocked by CSP.
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,11 +8,11 @@ user-invocable: false
8
8
  # @owlmeans/web-gtm
9
9
 
10
10
  **Layer:** Web
11
- **Install:** `"@owlmeans/web-gtm": "^0.1.18-rc.34"` in `dependencies`
11
+ **Install:** `"@owlmeans/web-gtm": "^0.1.18-rc.35"` in `dependencies`
12
12
 
13
13
  The tag half of the consent set. It emits **strings and data**, not components, and it holds no
14
14
  state — the decision lives in `@owlmeans/consent`, which this package reads through
15
- `consentBootstrapScript` and `consentStore`.
15
+ `consentModeHelper.consentBootstrapScript` and `consentStore`.
16
16
 
17
17
  ## The one idea: order
18
18
 
@@ -27,31 +27,31 @@ inline script. Everything else in this package exists to serve that.
27
27
 
28
28
  ## Loading mode: gated by default
29
29
 
30
- `googleTagHeadScript`, `gtmHeadScript` and `loadGtm` all take an optional `mode:
30
+ `googleTagHelper.googleTagHeadScript`, `.gtmHeadScript` and `.loadGtm` all take an optional `mode:
31
31
  'basic' | 'advanced'`, defaulting to `GOOGLE_TAG_DEFAULT_MODE` — currently `'basic'`, one named
32
32
  constant so flipping the platform default later is a one-line change:
33
33
 
34
34
  | `mode` | What runs, and when |
35
35
  |---|---|
36
- | `'basic'` (default) | The bootstrap and the ads-redaction flags still run unconditionally — Consent Mode's own denied-by-default signals are declared either way. The LOADER itself — `gtm.js`, or `gtag/js` + `js` + `config` — is wrapped in `@owlmeans/consent`'s `consentGateScript`: it runs immediately if the visitor's stored record already `trackingGranted`, and otherwise waits for a later `CONSENT_EVENT` (from `applyConsent`, i.e. an in-page consent decision) that does. Nothing — not even Google's own IP receipt — reaches the tag before a signal-bearing category (`analytics` or `marketing` by default; a `required` or signal-less category never counts) is granted. |
36
+ | `'basic'` (default) | The bootstrap and the ads-redaction flags still run unconditionally — Consent Mode's own denied-by-default signals are declared either way. The LOADER itself — `gtm.js`, or `gtag/js` + `js` + `config` — is wrapped in `@owlmeans/consent`'s `consentModeHelper.consentGateScript`: it runs immediately if the visitor's stored record already `.trackingGranted`, and otherwise waits for a later `CONSENT_EVENT` (from `.applyConsent`, i.e. an in-page consent decision) that does. Nothing — not even Google's own IP receipt — reaches the tag before a signal-bearing category (`analytics` or `marketing` by default; a `required` or signal-less category never counts) is granted. |
37
37
  | `'advanced'` | The original, only behavior before this mode existed: the loader runs immediately, Consent Mode signals denied by default, so the tag itself starts receiving traffic cookielessly from first paint. This is Google's own recommended default for its conversion modeling, and remains available for a site that has decided that tradeoff is acceptable. |
38
38
 
39
39
  Read `'basic'`'s default as the EU/DE worst-case reading of ePrivacy Art. 5(3): no third party
40
40
  receives a connection before consent.
41
41
 
42
- `gtmNoscriptFrame` returns `''` in `'basic'` mode rather than an iframe — a browser with JavaScript
42
+ `googleTagHelper.gtmNoscriptFrame` returns `''` in `'basic'` mode rather than an iframe — a browser with JavaScript
43
43
  disabled cannot have granted anything, so an unauthenticated `<noscript>` frame would defeat the
44
44
  whole point of gating. It keeps emitting the iframe in `'advanced'` mode, unchanged.
45
45
 
46
- `loadGtm` gates the same way at the DOM level: it still calls `consentStore.init(opts)` first, but
47
- only appends the container's `<script>` element once `trackingGranted(consentStore.get().record,
46
+ `googleTagHelper.loadGtm` gates the same way at the DOM level: it still calls `consentStore.init(opts)` first, but
47
+ only appends the container's `<script>` element once `consentModeHelper.trackingGranted(consentStore.get().record,
48
48
  opts.categories)` is true — immediately if already granted, or via a one-shot `consentStore.subscribe`
49
49
  that unsubscribes itself on the first update where it becomes true. The anti-double-load guard (the
50
50
  element's own id) is unchanged.
51
51
 
52
52
  None of this is new state: it is one more consumer of `@owlmeans/consent`'s existing surface —
53
- `trackingGranted(record, categories)` (whether a stored/applied record grants a signal-bearing,
54
- non-required category) and `consentGateScript(loaderExpr, opts)` (the inline script implementing the
53
+ `consentModeHelper.trackingGranted(record, categories)` (whether a stored/applied record grants a signal-bearing,
54
+ non-required category) and `.consentGateScript(loaderExpr, opts)` (the inline script implementing the
55
55
  "run now or wait for `CONSENT_EVENT`" branch). Both live in `@owlmeans/consent`, not here, because a
56
56
  target project's own custom loader can reuse the same gate without depending on this package.
57
57
 
@@ -59,21 +59,21 @@ target project's own custom loader can reuse the same gate without depending on
59
59
 
60
60
  | Export | Description |
61
61
  |--------|-------------|
62
- | `googleTagHeadScript(opts)` | The inline `<head>` script for any Google id: consent bootstrap, ads redaction, then the loader the prefix calls for — gated behind `consentGateScript` in `opts.mode`'s default, `'basic'`. **The default for new code** |
63
- | `isGoogleTagId(id)` / `googleTagKind(id)` | Whether an id is loadable, and whether it takes `gtm` (container) or `gtag` (gtag.js); `null` for anything else |
62
+ | `googleTagHelper.googleTagHeadScript(opts)` | The inline `<head>` script for any Google id: consent bootstrap, ads redaction, then the loader the prefix calls for — gated behind `consentModeHelper.consentGateScript` in `opts.mode`'s default, `'basic'`. **The default for new code** |
63
+ | `googleTagHelper.isGoogleTagId(id)` / `.googleTagKind(id)` | Whether an id is loadable, and whether it takes `gtm` (container) or `gtag` (gtag.js); `null` for anything else |
64
64
  | `GoogleTagOptions` / `GoogleTagKind` | `ConsentOptions` plus `id`, optional `dataLayerName` and `mode`; `'gtm' \| 'gtag'` |
65
65
  | `GoogleTagMode` / `GOOGLE_TAG_DEFAULT_MODE` | `'basic' \| 'advanced'`; the platform default, `'basic'` — see **Loading mode** below |
66
66
  | `GOOGLE_TAG_CSP_SOURCES` | The hosts GA4, Tag Manager and Google Ads need in `script-src`, `connect-src` and `img-src` (7, frozen) |
67
67
  | `GOOGLE_TAG_FRAME_SOURCES` | The hosts they frame, for `frame-src`: `https://www.googletagmanager.com`, `https://td.doubleclick.net` |
68
- | `googleTagServices(id)` | The `ConsentService[]` a cookie policy discloses for that tag — pass to `CookiePolicy`'s `services` |
69
- | `gtmHeadScript(opts)` | The container-only snippet: consent defaults, stored decision, then `gtm.js` — gated the same way as `googleTagHeadScript` |
70
- | `gtmNoscriptFrame(opts)` | The hidden `<noscript>` iframe, for the top of `<body>` — `''` in `'basic'` mode |
71
- | `loadGtm(opts)` | Script-side container load, for a host that cannot emit into its own head — gated the same way |
68
+ | `googleTagHelper.googleTagServices(id)` | The `ConsentService[]` a cookie policy discloses for that tag — pass to `CookiePolicy`'s `services` |
69
+ | `googleTagHelper.gtmHeadScript(opts)` | The container-only snippet: consent defaults, stored decision, then `gtm.js` — gated the same way as `.googleTagHeadScript` |
70
+ | `googleTagHelper.gtmNoscriptFrame(opts)` | The hidden `<noscript>` iframe, for the top of `<body>` — `''` in `'basic'` mode |
71
+ | `googleTagHelper.loadGtm(opts)` | Script-side container load, for a host that cannot emit into its own head — gated the same way |
72
72
  | `GtmOptions` | `ConsentOptions` plus `id` (e.g. `GTM-XXXXXXX`), optional `dataLayerName` and `mode` |
73
73
 
74
74
  ## Ids
75
75
 
76
- `isGoogleTagId` accepts exactly `GTM-` + 4–12, or `G-` / `GT-` / `AW-` / `DC-` + 4–16, upper-case
76
+ `googleTagHelper.isGoogleTagId` accepts exactly `GTM-` + 4–12, or `G-` / `GT-` / `AW-` / `DC-` + 4–16, upper-case
77
77
  letters and digits. It is strict on purpose: the id is typed into a settings form and ends up in
78
78
  an inline script and a script URL, and a value it accepts cannot carry a quote, a tag or a second
79
79
  query parameter — so **validate with it where the id is stored**, not only where it is emitted.
@@ -85,9 +85,9 @@ Lower case is rejected rather than folded; normalise in the form if you want to
85
85
  | `GTM-` | `gtm` | `gtm.js` — Google's container IIFE |
86
86
  | `G-` GA4, `GT-` Google tag, `AW-` Google Ads, `DC-` Floodlight | `gtag` | `gtag/js`, then `js` and `config` |
87
87
 
88
- ## `googleTagHeadScript` — what it emits
88
+ ## `googleTagHelper.googleTagHeadScript` — what it emits
89
89
 
90
- 1. `consentBootstrapScript(opts)` — `consent/default` (everything denied except
90
+ 1. `consentModeHelper.consentBootstrapScript(opts)` — `consent/default` (everything denied except
91
91
  `security_storage`) and, for a returning visitor, `consent/update` from the stored record.
92
92
  2. `set ads_data_redaction true` and `set url_passthrough false` — both have to precede the tag's
93
93
  `config`. Redaction strips ad-click ids and goes cookieless while `ad_storage` is denied.
@@ -96,36 +96,36 @@ Lower case is rejected rather than folded; normalise in the form if you want to
96
96
  element created from the inline script — one inline script rather than Google's two elements,
97
97
  so a build stamps one thing. The element carries id `owl-gtag-<id>`, so running the snippet
98
98
  twice configures the tag once instead of double-counting page views. In `mode`'s default,
99
- `'basic'`, this whole step 3 is what `consentGateScript` withholds — steps 1 and 2 always run;
99
+ `'basic'`, this whole step 3 is what `consentModeHelper.consentGateScript` withholds — steps 1 and 2 always run;
100
100
  pass `mode: 'advanced'` to run step 3 unconditionally too, as before this mode existed.
101
101
 
102
102
  An **invalid id yields the consent bootstrap alone, regardless of `mode`** — a mistyped tag must
103
- never cost a page its consent defaults. So a host may stamp `googleTagHeadScript({ id: configured
104
- })` unconditionally, or stamp `consentBootstrapScript()` when no tag is configured; both are
103
+ never cost a page its consent defaults. So a host may stamp `googleTagHelper.googleTagHeadScript({ id: configured
104
+ })` unconditionally, or stamp `consentModeHelper.consentBootstrapScript()` when no tag is configured; both are
105
105
  correct.
106
106
 
107
107
  **The output is safe to place inline in HTML as-is.** JSON encoding keeps configured values inside
108
108
  their string literals, but the HTML parser ends a script element at the first `</script` wherever
109
109
  it sits, so every `</` and `<!--` in the output is backslash-escaped (`<\/`, `<\!--` — JavaScript
110
- reads them unchanged). `gtmHeadScript` predates this and does not escape; prefer
111
- `googleTagHeadScript` wherever category keys or a storage key come from configuration.
110
+ reads them unchanged). `googleTagHelper.gtmHeadScript` predates this and does not escape; prefer
111
+ `.googleTagHeadScript` wherever category keys or a storage key come from configuration.
112
112
 
113
113
  ## Stamping it
114
114
 
115
115
  ```typescript
116
- import { googleTagHeadScript } from '@owlmeans/web-gtm'
116
+ import { googleTagHelper } from '@owlmeans/web-gtm'
117
117
 
118
- const head = googleTagHeadScript({ id: 'G-XXXXXXXXXX' }) // inline <script> content, first in <head>
118
+ const head = googleTagHelper.googleTagHeadScript({ id: 'G-XXXXXXXXXX' }) // inline <script> content, first in <head>
119
119
  ```
120
120
 
121
121
  The snippet is stamped **from HTML**, never from the application bundle:
122
122
 
123
123
  - a Vite app — a `transformIndexHtml` plugin substituting a marker, so the snippet cannot drift
124
124
  from the package;
125
- - an Astro site — `owlHeadScripts()` from `@owlmeans/astro`, `set:html` in the base layout;
125
+ - an Astro site — `astroHelper.owlHeadScripts()` from `@owlmeans/astro`, `set:html` in the base layout;
126
126
  - a **generated Viable app** — its Rollup build writes `index.html` and puts
127
- `googleTagHeadScript({ id })` in the `<head>` when the project owner has set a Google tag
128
- (`BRANDING_GOOGLE_TAG`), and `consentBootstrapScript()` otherwise. The tag is attached in
127
+ `googleTagHelper.googleTagHeadScript({ id })` in the `<head>` when the project owner has set a Google tag
128
+ (`BRANDING_GOOGLE_TAG`), and `consentModeHelper.consentBootstrapScript()` otherwise. The tag is attached in
129
129
  **preview and production** alike; the consent default is first in both.
130
130
 
131
131
  The snippet **reads the stored decision**, so the same `ConsentOptions` (categories, `storageKey`)
@@ -134,15 +134,15 @@ component disagree about what was asked.
134
134
 
135
135
  **Cross-domain consent needs nothing new here.** `GtmOptions`/`GoogleTagOptions` both extend
136
136
  `ConsentOptions`, so `linker` (see the `consent` skill's plugin-seam section) passed to either head
137
- script reaches `consentBootstrapScript` unchanged, which embeds the adopt-and-strip fragment right
137
+ script reaches `consentModeHelper.consentBootstrapScript` unchanged, which embeds the adopt-and-strip fragment right
138
138
  after `consent/default` when it is set:
139
139
 
140
140
  ```typescript
141
- googleTagHeadScript({ id: 'GTM-XXXXXXX', linker: { domains: ['owlmeans.com', 'owlmeans.pl'] } })
141
+ googleTagHelper.googleTagHeadScript({ id: 'GTM-XXXXXXX', linker: { domains: ['owlmeans.com', 'owlmeans.pl'] } })
142
142
  ```
143
143
 
144
144
  An app that does not stamp a tag at all still gets the fragment from a bare
145
- `consentBootstrapScript({ linker: { domains } })`.
145
+ `consentModeHelper.consentBootstrapScript({ linker: { domains } })`.
146
146
 
147
147
  ## Content Security Policy
148
148
 
@@ -174,7 +174,7 @@ consent is granted (`/web-log`).
174
174
 
175
175
  ## Disclosing it
176
176
 
177
- `googleTagServices(id)` returns what the cookie policy lists under each category, read off the
177
+ `googleTagHelper.googleTagServices(id)` returns what the cookie policy lists under each category, read off the
178
178
  prefix — the page knows nothing more:
179
179
 
180
180
  | Id | Entries |
@@ -193,32 +193,32 @@ cookie page does so when a Google tag is set. The strings are English data, not
193
193
  - **Consent Mode speaks on `window.dataLayer`.** The bootstrap and the dialog's later
194
194
  `consent/update` both push there, so a tag given another `dataLayerName` never hears a consent
195
195
  command. Leave `dataLayerName` unset on any consent-gated page; it exists for a page running a
196
- second, separately-consented container. `googleTagHeadScript` falls back to `dataLayer` when the
196
+ second, separately-consented container. `googleTagHelper.googleTagHeadScript` falls back to `dataLayer` when the
197
197
  name is not a plain identifier.
198
- - **Ids and queue names are injected as data, never interpolated raw.** `gtmHeadScript` and
199
- `googleTagHeadScript` JSON-encode them; `gtmNoscriptFrame` URL-encodes the id so it cannot break
198
+ - **Ids and queue names are injected as data, never interpolated raw.** `googleTagHelper.gtmHeadScript` and
199
+ `.googleTagHeadScript` JSON-encode them; `.gtmNoscriptFrame` URL-encodes the id so it cannot break
200
200
  out of the attribute. Never build either string by hand.
201
- - **`loadGtm` is the fallback, not the default.** It is for a single-page app whose HTML is not
201
+ - **`googleTagHelper.loadGtm` is the fallback, not the default.** It is for a single-page app whose HTML is not
202
202
  yours to edit. It still pushes the defaults first (through `consentStore.init`) and refuses to
203
203
  load a second time — it marks its own `<script>` element with an id derived from the container —
204
204
  but it runs after the bundle, which is exactly the window the head snippet closes. In `'basic'`
205
- mode it additionally withholds the element itself until `trackingGranted`, same as the head
205
+ mode it additionally withholds the element itself until `consentModeHelper.trackingGranted`, same as the head
206
206
  snippets.
207
207
  - **The default flipped to `'basic'`.** Code written before this mode existed called
208
- `googleTagHeadScript({ id })` / `gtmHeadScript({ id })` expecting the tag to load unconditionally.
208
+ `googleTagHelper.googleTagHeadScript({ id })` / `.gtmHeadScript({ id })` expecting the tag to load unconditionally.
209
209
  It now gates by default; pass `mode: 'advanced'` explicitly to keep the old behavior for a site
210
210
  that has made that call deliberately.
211
211
  - **A second `consent/default` after a tag has loaded can WIDEN what was already narrowed**, so the
212
212
  bootstrap is idempotent through a window flag. A page may therefore carry the call twice — once
213
213
  inline, once from the bundle that mounts the dialog — without harm. Do not defeat the flag.
214
- - `loadGtm` returns immediately when there is no `document`, so it is safe to call from code that
214
+ - `googleTagHelper.loadGtm` returns immediately when there is no `document`, so it is safe to call from code that
215
215
  also runs during server rendering.
216
216
 
217
217
  ## Depends On
218
218
 
219
- - `@owlmeans/consent` — `consentBootstrapScript`, `consentStore`, `ConsentOptions`,
219
+ - `@owlmeans/consent` — `consentModeHelper.consentBootstrapScript`, `consentStore`, `ConsentOptions`,
220
220
  `ConsentService`, the category keys and the Consent Mode signal mapping, plus (for the `'basic'`
221
- gated mode) `consentGateScript` and `trackingGranted`
221
+ gated mode) `.consentGateScript` and `.trackingGranted`
222
222
 
223
223
  ## Related
224
224
 
@@ -226,4 +226,4 @@ cookie page does so when a Google tag is set. The strings are English data, not
226
226
  ordering rule this package implements
227
227
  - `web-consent` — the dialog and the cookie-policy page (`services`) that produce and disclose the
228
228
  decision
229
- - `astro` — `owlHeadScripts()`, which composes the head strings for an Astro layout
229
+ - `astro` — `astroHelper.owlHeadScripts()`, which composes the head strings for an Astro layout
package/build/index.d.ts CHANGED
@@ -1,81 +1,5 @@
1
- import { type ConsentService } from '@owlmeans/consent';
2
- import type { GoogleTagKind, GoogleTagOptions, GtmOptions } from './types.js';
3
- /**
4
- * The inline `<head>` snippet, consent first and the container second.
5
- *
6
- * The ORDER is the whole point of this package. Google Tag Manager decides what a tag may do from
7
- * the consent state present when the container loads, and a React bundle cannot get there first —
8
- * by the time an island mounts, the container has been running for hundreds of milliseconds. A
9
- * site whose defaults arrive after `gtm.js` is not configured differently; it is unconfigured for
10
- * the window that matters, and nothing in the page reports it.
11
- *
12
- * Emit this into the document head, above everything else, as an inline script.
13
- *
14
- * In `GOOGLE_TAG_DEFAULT_MODE` (`'basic'`) the container is not requested at all until a
15
- * signal-bearing category is granted — {@link consentGateScript} wraps it, reading any stored
16
- * decision immediately and otherwise waiting for `@owlmeans/consent`'s `CONSENT_EVENT`. Pass
17
- * `mode: 'advanced'` for the original, unconditional load.
18
- */
19
- export declare const gtmHeadScript: (opts: GtmOptions) => string;
20
- /**
21
- * The `<noscript>` iframe, for the body.
22
- *
23
- * In `'basic'` mode this is an empty string: the whole point of gating is that an unauthenticated
24
- * `<noscript>` iframe would defeat it — a browser with JavaScript disabled cannot have granted
25
- * anything, so there is nothing lawful left to render. `'advanced'` keeps the frame.
26
- */
27
- export declare const gtmNoscriptFrame: (opts: GtmOptions) => string;
28
- /**
29
- * Load the container from script, for a host that cannot emit into its own head.
30
- *
31
- * The head snippet is strictly better and should be preferred; this exists for a single-page app
32
- * whose HTML is not ours to edit. It still pushes the defaults first, and it still refuses to load
33
- * a second time.
34
- *
35
- * In `'basic'` mode the container element is not appended until `trackingGranted` is true: either
36
- * the stored record already grants it, or — since this runs after the bundle mounted, past the
37
- * window the head snippet exists to close — a subscription to `consentStore` catches the first
38
- * update where it becomes true and unsubscribes. `'advanced'` appends it immediately, as before.
39
- */
40
- export declare const loadGtm: (opts: GtmOptions) => void;
41
- /** Whether `id` is a Tag Manager container or Google tag id this package can load. */
42
- export declare const isGoogleTagId: (id: string) => boolean;
43
- /** The loader `id` takes, or `null` when it is not a loadable id at all. */
44
- export declare const googleTagKind: (id: string) => GoogleTagKind | null;
45
- /**
46
- * The one inline `<head>` script for a Google tag of any kind: the consent bootstrap FIRST, then
47
- * ads redaction, then the loader the id's prefix calls for — the Tag Manager container for `GTM-`,
48
- * gtag.js with `js` and `config` for `G-`, `GT-`, `AW-` and `DC-`.
49
- *
50
- * The order is the rule {@link gtmHeadScript} exists for, and it holds for gtag.js just the same:
51
- * a tag decides what it may do from the consent state present when it loads. The bootstrap
52
- * declares everything denied and applies any stored decision in the same turn, so a returning
53
- * visitor's tag starts granted and a new visitor's starts cookieless.
54
- *
55
- * An id that is not a loadable id ({@link isGoogleTagId}) yields the consent bootstrap alone — a
56
- * page must never lose its consent defaults because someone mistyped a tag. The result is safe to
57
- * place inline in HTML as-is: `</` and `<!--` inside any configured value are escaped.
58
- *
59
- * In `GOOGLE_TAG_DEFAULT_MODE` (`'basic'`) the loader itself — the last piece — is wrapped in
60
- * `consentGateScript`: it runs immediately for a returning visitor whose stored record already
61
- * grants a signal-bearing category, and otherwise waits for `@owlmeans/consent`'s `CONSENT_EVENT`
62
- * before ever requesting the tag. The bootstrap and the redaction flags are unaffected and still
63
- * run unconditionally — Consent Mode's OWN denied-by-default signals are declared either way, so a
64
- * tag that later does load still starts from `ad_storage`/`analytics_storage` denied. Pass
65
- * `mode: 'advanced'` for the original, unconditional load.
66
- */
67
- export declare const googleTagHeadScript: (opts: GoogleTagOptions) => string;
68
- /**
69
- * What a Google tag discloses on the cookie policy, for `CookiePolicy`'s `services`.
70
- *
71
- * Read off the id's prefix, because that is all the page knows: `G-` is Google Analytics 4
72
- * (`_ga`, and `_ga_<id without G->` which carries the session), `AW-` Google Ads, `DC-` Floodlight.
73
- * A `GTM-` container and a `GT-` Google tag route to whatever their owner configured at Google,
74
- * so both are disclosed as an analytics AND an advertising entry, worded as configured there —
75
- * the policy may not claim less than the tag can do. An invalid id discloses nothing, matching
76
- * {@link googleTagHeadScript}, which loads nothing for it.
77
- */
78
- export declare const googleTagServices: (id: string) => ConsentService[];
1
+ export type * from './tag/types.js';
2
+ export * from './tag.js';
79
3
  export type { GoogleTagKind, GoogleTagMode, GoogleTagOptions, GtmOptions } from './types.js';
80
4
  export { GOOGLE_TAG_CSP_SOURCES, GOOGLE_TAG_DEFAULT_MODE, GOOGLE_TAG_FRAME_SOURCES } from './consts.js';
81
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkH,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGvK,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAY7E;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa,SAAU,UAAU,KAAG,MAShD,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,SAAU,UAAU,KAAG,MAOnD,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO,SAAU,UAAU,KAAG,IA0C1C,CAAA;AAED,sFAAsF;AACtF,eAAO,MAAM,aAAa,OAAQ,MAAM,KAAG,OACO,CAAA;AAElD,4EAA4E;AAC5E,eAAO,MAAM,aAAa,OAAQ,MAAM,KAAG,aAAa,GAAG,IACS,CAAA;AAsDpE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,mBAAmB,SAAU,gBAAgB,KAAG,MAe5D,CAAA;AAYD;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,OAAQ,MAAM,KAAG,cAAc,EA8C5D,CAAA;AAED,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5F,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,gBAAgB,CAAA;AACnC,cAAc,UAAU,CAAA;AACxB,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5F,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA"}
package/build/index.js CHANGED
@@ -1,226 +1,3 @@
1
- import { CONSENT_ANALYTICS, CONSENT_MARKETING, consentBootstrapScript, consentGateScript, consentStore, trackingGranted } from '@owlmeans/consent';
2
- import { GOOGLE, GOOGLE_PRIVACY, GOOGLE_TAG_ID, JS_IDENTIFIER, UNTIL_ANALYTICS, UNTIL_MARKETING } from './consts.local.js';
3
- import { GOOGLE_TAG_DEFAULT_MODE } from './consts.js';
4
- /** Google's own container IIFE, the id and queue name injected as JSON data. */
5
- const gtmContainerScript = (layer, id) => `(function(w,d,s,l,i){w[l]=w[l]||[];` +
6
- `w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});` +
7
- `var f=d.getElementsByTagName(s)[0],j=d.createElement(s),` +
8
- `dl=l!='dataLayer'?'&l='+l:'';j.async=true;` +
9
- `j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;` +
10
- `f.parentNode.insertBefore(j,f)})` +
11
- `(window,document,'script',${JSON.stringify(layer)},${JSON.stringify(id)})`;
12
- /**
13
- * The inline `<head>` snippet, consent first and the container second.
14
- *
15
- * The ORDER is the whole point of this package. Google Tag Manager decides what a tag may do from
16
- * the consent state present when the container loads, and a React bundle cannot get there first —
17
- * by the time an island mounts, the container has been running for hundreds of milliseconds. A
18
- * site whose defaults arrive after `gtm.js` is not configured differently; it is unconfigured for
19
- * the window that matters, and nothing in the page reports it.
20
- *
21
- * Emit this into the document head, above everything else, as an inline script.
22
- *
23
- * In `GOOGLE_TAG_DEFAULT_MODE` (`'basic'`) the container is not requested at all until a
24
- * signal-bearing category is granted — {@link consentGateScript} wraps it, reading any stored
25
- * decision immediately and otherwise waiting for `@owlmeans/consent`'s `CONSENT_EVENT`. Pass
26
- * `mode: 'advanced'` for the original, unconditional load.
27
- */
28
- export const gtmHeadScript = (opts) => {
29
- const bootstrap = consentBootstrapScript(opts);
30
- const loader = gtmContainerScript(opts.dataLayerName ?? 'dataLayer', opts.id);
31
- if ((opts.mode ?? GOOGLE_TAG_DEFAULT_MODE) === 'basic') {
32
- return `${bootstrap};${consentGateScript(loader, opts)}`;
33
- }
34
- return `${bootstrap};${loader}`;
35
- };
36
- /**
37
- * The `<noscript>` iframe, for the body.
38
- *
39
- * In `'basic'` mode this is an empty string: the whole point of gating is that an unauthenticated
40
- * `<noscript>` iframe would defeat it — a browser with JavaScript disabled cannot have granted
41
- * anything, so there is nothing lawful left to render. `'advanced'` keeps the frame.
42
- */
43
- export const gtmNoscriptFrame = (opts) => {
44
- if ((opts.mode ?? GOOGLE_TAG_DEFAULT_MODE) === 'basic') {
45
- return '';
46
- }
47
- return `<iframe src="https://www.googletagmanager.com/ns.html?id=${encodeURIComponent(opts.id)}"` +
48
- ` height="0" width="0" style="display:none;visibility:hidden"></iframe>`;
49
- };
50
- /**
51
- * Load the container from script, for a host that cannot emit into its own head.
52
- *
53
- * The head snippet is strictly better and should be preferred; this exists for a single-page app
54
- * whose HTML is not ours to edit. It still pushes the defaults first, and it still refuses to load
55
- * a second time.
56
- *
57
- * In `'basic'` mode the container element is not appended until `trackingGranted` is true: either
58
- * the stored record already grants it, or — since this runs after the bundle mounted, past the
59
- * window the head snippet exists to close — a subscription to `consentStore` catches the first
60
- * update where it becomes true and unsubscribes. `'advanced'` appends it immediately, as before.
61
- */
62
- export const loadGtm = (opts) => {
63
- if (typeof document === 'undefined') {
64
- return;
65
- }
66
- const marker = `owl-gtm-${opts.id}`;
67
- if (document.getElementById(marker) != null) {
68
- return;
69
- }
70
- // Defaults before the container, every time — the same rule the head snippet exists to keep.
71
- consentStore.init(opts);
72
- const inject = () => {
73
- if (document.getElementById(marker) != null) {
74
- return;
75
- }
76
- const layer = opts.dataLayerName ?? 'dataLayer';
77
- const script = document.createElement('script');
78
- script.id = marker;
79
- script.async = true;
80
- script.src = `https://www.googletagmanager.com/gtm.js?id=${encodeURIComponent(opts.id)}`
81
- + (layer !== 'dataLayer' ? `&l=${encodeURIComponent(layer)}` : '');
82
- document.head.appendChild(script);
83
- };
84
- if ((opts.mode ?? GOOGLE_TAG_DEFAULT_MODE) !== 'basic') {
85
- inject();
86
- return;
87
- }
88
- if (trackingGranted(consentStore.get().record, opts.categories)) {
89
- inject();
90
- return;
91
- }
92
- const unsubscribe = consentStore.subscribe(state => {
93
- if (trackingGranted(state.record, opts.categories)) {
94
- unsubscribe();
95
- inject();
96
- }
97
- });
98
- };
99
- /** Whether `id` is a Tag Manager container or Google tag id this package can load. */
100
- export const isGoogleTagId = (id) => typeof id === 'string' && GOOGLE_TAG_ID.test(id);
101
- /** The loader `id` takes, or `null` when it is not a loadable id at all. */
102
- export const googleTagKind = (id) => !isGoogleTagId(id) ? null : id.startsWith('GTM-') ? 'gtm' : 'gtag';
103
- const layerOf = (opts) => opts.dataLayerName != null && JS_IDENTIFIER.test(opts.dataLayerName)
104
- ? opts.dataLayerName
105
- : 'dataLayer';
106
- /**
107
- * Make a generated script safe to place between `<script>` and `</script>`.
108
- *
109
- * JSON encoding keeps a value inside its string literal, but the HTML parser does not read
110
- * JavaScript: it ends the element at the first `</script` it meets, wherever it sits, and a
111
- * `<!--` can switch it into a state where the real closing tag is swallowed. Both sequences can
112
- * only appear inside the JSON-encoded values here — category keys, a storage key, a queue name —
113
- * so each gets a backslash that JavaScript reads as nothing (`\/` is `/`, `\!` is `!`).
114
- */
115
- const inlineSafe = (script) => script.replace(/<\//g, '<\\/').replace(/<!--/g, '<\\!--');
116
- /**
117
- * Ads data redaction on, URL passthrough off — before any loader runs.
118
- *
119
- * `ads_data_redaction` makes an Ads or Floodlight tag strip ad-click identifiers and send its
120
- * requests through a cookieless domain while `ad_storage` is denied. `url_passthrough` is set to
121
- * its default explicitly so that nothing configured later on the page can switch on decorating
122
- * links with click ids for a visitor who refused marketing storage. Google reads both only when
123
- * they are set ahead of the tag's `config`.
124
- */
125
- const redactionScript = (layer) => `(function(w,l){w[l]=w[l]||[];function g(){w[l].push(arguments)}` +
126
- `g('set','ads_data_redaction',true);g('set','url_passthrough',false)})` +
127
- `(window,${JSON.stringify(layer)})`;
128
- /**
129
- * Google's gtag.js snippet as one inline script: the queue function, `js` and `config`, then the
130
- * library requested from here rather than from a second `<script src>` element.
131
- *
132
- * One inline script instead of Google's two elements because the document it lands in is served
133
- * with a hash-based CSP and stamped by a build that writes one head snippet — a second element
134
- * would be a second thing to keep in order. The element carries an id derived from the tag, so a
135
- * page that runs the snippet twice (two stampings, a hot reload) does not configure the tag twice
136
- * and double-count every page view. `window.gtag` is published only when nothing else owns it, so
137
- * application code can send its own events.
138
- */
139
- const gtagScript = (layer, id) => `(function(w,d,l,i){var m='owl-gtag-'+i;if(d.getElementById(m))return;` +
140
- `w[l]=w[l]||[];function g(){w[l].push(arguments)}if(!w.gtag)w.gtag=g;` +
141
- `g('js',new Date());g('config',i);` +
142
- `var j=d.createElement('script');j.id=m;j.async=true;` +
143
- `j.src='https://www.googletagmanager.com/gtag/js?id='+encodeURIComponent(i)` +
144
- `+(l!='dataLayer'?'&l='+encodeURIComponent(l):'');` +
145
- `(d.head||d.documentElement).appendChild(j)})` +
146
- `(window,document,${JSON.stringify(layer)},${JSON.stringify(id)})`;
147
- /**
148
- * The one inline `<head>` script for a Google tag of any kind: the consent bootstrap FIRST, then
149
- * ads redaction, then the loader the id's prefix calls for — the Tag Manager container for `GTM-`,
150
- * gtag.js with `js` and `config` for `G-`, `GT-`, `AW-` and `DC-`.
151
- *
152
- * The order is the rule {@link gtmHeadScript} exists for, and it holds for gtag.js just the same:
153
- * a tag decides what it may do from the consent state present when it loads. The bootstrap
154
- * declares everything denied and applies any stored decision in the same turn, so a returning
155
- * visitor's tag starts granted and a new visitor's starts cookieless.
156
- *
157
- * An id that is not a loadable id ({@link isGoogleTagId}) yields the consent bootstrap alone — a
158
- * page must never lose its consent defaults because someone mistyped a tag. The result is safe to
159
- * place inline in HTML as-is: `</` and `<!--` inside any configured value are escaped.
160
- *
161
- * In `GOOGLE_TAG_DEFAULT_MODE` (`'basic'`) the loader itself — the last piece — is wrapped in
162
- * `consentGateScript`: it runs immediately for a returning visitor whose stored record already
163
- * grants a signal-bearing category, and otherwise waits for `@owlmeans/consent`'s `CONSENT_EVENT`
164
- * before ever requesting the tag. The bootstrap and the redaction flags are unaffected and still
165
- * run unconditionally — Consent Mode's OWN denied-by-default signals are declared either way, so a
166
- * tag that later does load still starts from `ad_storage`/`analytics_storage` denied. Pass
167
- * `mode: 'advanced'` for the original, unconditional load.
168
- */
169
- export const googleTagHeadScript = (opts) => {
170
- const bootstrap = consentBootstrapScript(opts);
171
- const kind = googleTagKind(opts.id);
172
- if (kind == null) {
173
- return inlineSafe(bootstrap);
174
- }
175
- const layer = layerOf(opts);
176
- const loader = kind === 'gtm' ? gtmContainerScript(layer, opts.id) : gtagScript(layer, opts.id);
177
- const redaction = redactionScript(layer);
178
- if ((opts.mode ?? GOOGLE_TAG_DEFAULT_MODE) === 'basic') {
179
- return inlineSafe(`${bootstrap};${redaction};${consentGateScript(loader, opts)}`);
180
- }
181
- return inlineSafe(`${bootstrap};${redaction};${loader}`);
182
- };
183
- const analyticsService = (name, purpose, cookies) => ({
184
- name, provider: GOOGLE, category: CONSENT_ANALYTICS, purpose, cookies, privacyHref: GOOGLE_PRIVACY,
185
- });
186
- const adsService = (name, purpose, cookies) => ({
187
- name, provider: GOOGLE, category: CONSENT_MARKETING, purpose, cookies, privacyHref: GOOGLE_PRIVACY,
188
- });
189
- /**
190
- * What a Google tag discloses on the cookie policy, for `CookiePolicy`'s `services`.
191
- *
192
- * Read off the id's prefix, because that is all the page knows: `G-` is Google Analytics 4
193
- * (`_ga`, and `_ga_<id without G->` which carries the session), `AW-` Google Ads, `DC-` Floodlight.
194
- * A `GTM-` container and a `GT-` Google tag route to whatever their owner configured at Google,
195
- * so both are disclosed as an analytics AND an advertising entry, worded as configured there —
196
- * the policy may not claim less than the tag can do. An invalid id discloses nothing, matching
197
- * {@link googleTagHeadScript}, which loads nothing for it.
198
- */
199
- export const googleTagServices = (id) => {
200
- if (!isGoogleTagId(id)) {
201
- return [];
202
- }
203
- const prefix = id.slice(0, id.indexOf('-'));
204
- switch (prefix) {
205
- case 'G':
206
- return [analyticsService('Google Analytics', 'Measures how visitors use the site — pages viewed, time spent, device and approximate '
207
- + `location — so it can be improved. ${UNTIL_ANALYTICS}`, ['_ga', `_ga_${id.slice(2)}`])];
208
- case 'AW':
209
- return [adsService('Google Ads', 'Measures which ads led to a visit or a sign-up, and may add visitors to audiences for '
210
- + `showing them ads elsewhere. ${UNTIL_MARKETING}`, ['_gcl_au', '_gcl_aw'])];
211
- case 'DC':
212
- return [adsService('Google Campaign Manager 360 (Floodlight)', `Measures which ad campaigns led to a visit or a sign-up. ${UNTIL_MARKETING}`, ['_gcl_au', '_gcl_dc'])];
213
- default: {
214
- const source = prefix === 'GTM' ? 'Google Tag Manager' : 'Google tag';
215
- const where = prefix === 'GTM' ? 'in its container' : 'for it at Google';
216
- return [
217
- analyticsService(`${source} — analytics`, `Runs the analytics tags configured ${where}, typically Google Analytics. `
218
- + UNTIL_ANALYTICS, ['_ga', '_ga_*']),
219
- adsService(`${source} — advertising`, `Runs the advertising tags configured ${where}, typically Google Ads conversion `
220
- + `tracking and remarketing. ${UNTIL_MARKETING}`, ['_gcl_au', '_gcl_aw']),
221
- ];
222
- }
223
- }
224
- };
1
+ export * from './tag.js';
225
2
  export { GOOGLE_TAG_CSP_SOURCES, GOOGLE_TAG_DEFAULT_MODE, GOOGLE_TAG_FRAME_SOURCES } from './consts.js';
226
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAA;AAExB,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA"}