@getvitops/astro 3.0.0 → 4.1.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,242 @@
1
1
  # @getvitops/astro
2
2
 
3
+ ## 4.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 2c890c0: Link a site to its ad properties: `site.ads`, `vitops ads`, and `<Ads />`.
8
+
9
+ `vitops search` covers the whole Search Console relationship. Nothing covered the equivalent one
10
+ with ad platforms, and a site's ad accounts had nowhere to live — so a Meta pixel pasted into a
11
+ template was invisible to the rest of the toolchain. It set `_fbp` on a site whose generated cookie
12
+ notice never mentioned it, whose consent gate never cleared it on revoke, and — for LinkedIn and
13
+ Pinterest — whose attribution never captured the click ID at all, so every conversion from those
14
+ platforms arrived indistinguishable from organic traffic.
15
+
16
+ **New `site.ads` block**, keyed by platform (`google`, `meta`, `linkedin`, `reddit`, `tiktok`,
17
+ `microsoft`, `pinterest`, `snapchat`):
18
+
19
+ ```jsonc
20
+ {
21
+ "site": {
22
+ "ads": {
23
+ "meta": { "pixelId": "123456789", "domainVerification": "abc123" },
24
+ "google": {
25
+ "accountId": "123-456-7890",
26
+ "pixelId": "AW-987654321",
27
+ "conversionLabel": "xyz",
28
+ },
29
+ },
30
+ },
31
+ }
32
+ ```
33
+
34
+ **`vitops ads setup`** ensures each platform's domain-verification DNS record. Only four platforms
35
+ verify a domain at all — Meta, TikTok, Pinterest and Snapchat, by apex DNS TXT — and that record is
36
+ the one thing created for you (in Cloudflare, via `CLOUDFLARE_API_TOKEN`; created only, never edited
37
+ or deleted). Google Ads, LinkedIn, Reddit and Microsoft Ads have no domain verification: linking
38
+ there is the tag and the account id, and the run says so rather than skipping in silence. No
39
+ platform Marketing API is called — Meta's needs a system-user token and Google's an approved
40
+ developer token with your own account on the line — so the final "Verify" click is surfaced as a
41
+ reminder. `--dry` prints the plan, `--check` reports drift and exits non-zero.
42
+
43
+ **It asks for what the config is missing.** A verification token does not exist until someone
44
+ fetches it from the platform UI, so a first run prompts for it, naming the exact UI path, folds the
45
+ answer into the plan and writes it to your config. The token is not a secret — it is published in
46
+ DNS, and the platform fetching it back is the ownership proof, exactly like the IndexNow key.
47
+ Prompting requires a TTY: with `--dry`, `--check`, `--no-prompt`, or in CI, you get a named error
48
+ instead and the run never hangs. `--no-write` keeps the answer out of the config.
49
+
50
+ **`vitops ads tags`** prints each pixel as an inert, consent-gated `<script>` — `type="text/plain"`
51
+ with the library URL on `data-src`, so an undecided visitor's page issues no third-party request.
52
+ For Bricks, WordPress, Eleventy: any stack without the Astro integration.
53
+
54
+ **`vitops ads lint`** reports the gaps that are invisible at runtime: a click ID the platform stamps
55
+ that attribution does not capture, a pixel while `site.tracking` is off, a property with no tag id.
56
+
57
+ **`<Ads />` in `@getvitops/astro`**, a sibling of `<Analytics />` rather than part of it — ad
58
+ properties come from the site config, state their own consent category (`marketing` by default,
59
+ rather than being derived), and switch per environment on their own
60
+ (`environments.<env>.ads`, defaulting to `analytics`, then true, so a preview deployment can send
61
+ pageviews without firing conversion pixels). Both components now render through one `<GatedTags />`,
62
+ so the inert markup has a single implementation.
63
+
64
+ **Your cookie notice now discloses every configured pixel** — name, cookies and opt-out — from the
65
+ same table that writes `data-consent-cookies`, so the notice and the revoke cannot disagree. If you
66
+ add `site.ads` to a config whose privacy policy or cookie notice you have already published,
67
+ re-generate and re-read them.
68
+
69
+ `li_fat_id` (LinkedIn) and `epik` (Pinterest) join the click-ID capture vocabulary; a site running
70
+ either platform starts attributing conversions it previously recorded as organic.
71
+
72
+ ### Patch Changes
73
+
74
+ - Updated dependencies [2c890c0]
75
+ - Updated dependencies [e764090]
76
+ - @getvitops/generator@4.1.0
77
+ - @getvitops/utils@4.1.0
78
+ - @getvitops/vite@4.1.0
79
+ - @getvitops/core@4.1.0
80
+
81
+ ## 4.0.0
82
+
83
+ ### Major Changes
84
+
85
+ - c6b99e7: Consent is now demand-driven: the banner appears when something actually needs permission, not on every first visit.
86
+
87
+ Previously, enabling the gate showed a banner to every new visitor regardless of what the site did — including sites whose only analytics provider was cookieless, where there was nothing to consent to. The build decided whether the machinery shipped and the runtime showed the banner because no cookie existed yet.
88
+
89
+ Now those are two separate facts. The build decides what the banner _can_ ask (rows in the markup); the runtime decides what it _does_ ask. A gated tag registers its demand when it reaches its loading strategy, and `<color-scheme-toggle>` registers `preferences` when a visitor picks a scheme. A site that gates nothing never interrupts anyone.
90
+
91
+ **Breaking — consent cookie schema (v1 → v2).** Consent is now recorded per category as granted / declined / **not yet asked**. The third state is what lets a later demand ask about a category an earlier prompt didn't cover: accepting an analytics banner no longer silently declines preferences. Every stored v1 choice is invalid and re-prompts once — a v1 cookie asserted a definite answer for categories the visitor was never shown.
92
+
93
+ **Breaking — `ConsentApi`.**
94
+ - `needed()` now means "something demanded a category the visitor hasn't answered", not "no cookie yet". A custom banner calling it will now stay hidden until something asks.
95
+ - `ConsentState.decided` (a single boolean) is gone. Use `decidedFor(state, category)`, or `undecidedCategories(state)`.
96
+ - New: `require(category)` registers a demand and reports whether it is granted; `request(category)` resolves once the visitor answers it; `demanded()` lists what has asked so far.
97
+ - `acceptAll()` / `rejectAll()` still mean every optional category. The banner no longer routes its buttons through them — "Accept" applies to the categories on screen.
98
+
99
+ **Breaking — `<color-scheme-toggle>` persistence.** The chosen scheme still applies immediately, but writing it to `localStorage` now waits on the `preferences` category **when the site has a consent gate**. Sites without `consent` enabled are unaffected and keep storing as before. If your site enables consent and offers a theme toggle, make sure `preferences` is among the offered categories (it is by default).
100
+
101
+ **Changed — offered categories.** `consent.categories` defaults to `['analytics', 'preferences']` (plus `marketing` when a configured tag needs it) rather than only what analytics detection could see. An unused row is hidden markup, so offering broadly costs nothing and covers `data-consent` markup no build-time scan can find. Pass `categories` explicitly to narrow it.
102
+
103
+ **Added — `<Head />` emits a small inline consent stub** when the gate is on. `consent.js` and `elements.js` are both deferred with no ordering between them, so without it a theme toggle could be clicked before the gate existed, read "no gate", and store. The stub answers `false` and queues, and the runtime replays the queue on load.
104
+
105
+ **Fixed — the generated cookie notice** now discloses the stored display preference when `preferences` is offered, and no longer promises a banner "shown when you first visit", which is no longer how the banner works.
106
+
107
+ ### Minor Changes
108
+
109
+ - c6b99e7: Ad-click attribution and conversion notifications ship as part of the toolchain.
110
+
111
+ A visitor arriving on an ad carries a click ID in the URL; `<Tracking />` captures it into a first-party `_ac` cookie, and when that visitor later submits a form or taps a `tel:` link, the conversion handler reads the cookie back and notifies whoever the config says. Previously this was per-site code.
112
+
113
+ **Added — `@getvitops/utils/tracking`.** The attribution vocabulary and cookie, as pure functions over a cookie _string_ so the browser capture and the server-side handler share one implementation: `parseTrackingCookie`, `serializeTrackingCookie`, `mergeTracking`, `identifyPlatform`, `getPrimaryClickId`, plus the click-ID/UTM tables. No DOM, no network, no clock — every function that needs "now" takes it as an argument, so it runs unchanged in a Worker.
114
+
115
+ **Added — `@getvitops/utils/notify`.** Conversion notifications, split the way `indexing/` is: `plan.ts` decides everything purely (which channels fire, who they reach, and **why anything is skipped**), `render.ts` turns the event into prose, `email.ts` executes and decides nothing. A misconfigured site can therefore be told exactly why no notification will arrive — a silently unsent one is indistinguishable from no conversion.
116
+
117
+ The `ConversionEvent` is the abstraction: the event is the _fact_, and how it reads is the channel's business.
118
+
119
+ **Added — the `email` channel, via Cloudflare Email Sending.** Uses the current structured binding (`env.EMAIL.send({ to, from, subject, html, text })`), not the legacy `EmailMessage` + hand-built MIME path. The binding is **passed in, never imported**, so `@getvitops/utils` takes no Cloudflare dependency and the sender is testable with a stub. Retries only the transient error codes; a configuration fault like `E_SENDER_NOT_VERIFIED` is surfaced verbatim rather than collapsed into "send failed". With no binding it prints the notification — the dev path.
120
+
121
+ Remember to onboard the sending domain (`wrangler email sending enable <domain>`) and add `"send_email": [{ "name": "EMAIL" }]` to `wrangler.jsonc`, or every send fails.
122
+
123
+ **Added — `<Tracking />` and `createConversionRoute()`** in `@getvitops/astro` (`@getvitops/astro/Tracking.astro`, `@getvitops/astro/routes`). The route factory handles both the `tel:` beacon and a form POST; validation and business rules stay the consumer's, because every site's form differs. A failed notification never fails the request — the visitor has already submitted, and refusing them because our mail didn't go out turns a lost notification into a lost conversion.
124
+
125
+ **Added — `site.tracking` and a widened `site.notifications`.** `notifications.email` now accepts a full channel object as well as a bare address (which still means what it did). `tracking` gains `category`.
126
+
127
+ **Fixed — the capture script now asks for consent instead of only reading it.** It previously checked `granted('marketing')` passively, which under the demand-driven banner is a permanent no-op: nothing else on a page demands `marketing`, so the banner never offered it, so it was never granted, so `_ac` was never written — silently, on every site with the gate enabled. It now calls `require()`, which is what raises the banner, and only when the URL actually carried a click ID or UTM. A visitor arriving organically has nothing to attribute and is never asked.
128
+
129
+ The integration adds `marketing` to the offered categories when tracking is on, so the banner has a row for the category the script will demand, and warns when tracking is enabled with `consent` off.
130
+
131
+ **Fixed — revoking consent now clears `_ac`.** The marker `<Tracking />` emits carries `data-consent-cookies`, which the consent runtime's cleanup reads. There was no cleanup path for this cookie before.
132
+
133
+ **Fixed — the cookie notice discloses `_ac`.** It is first-party, so no provider table would ever name it, and a site running attribution alongside a cookieless analytics provider was previously described as setting no cookies at all.
134
+
135
+ - 14813fa: Add `<wc-tree>`, and a schema walker that feeds it.
136
+
137
+ `<wc-tree>` is progressive enhancement for the existing `.tree` pattern: given a nested
138
+ `<details>` disclosure tree it adds a filter, expand-all / collapse-all, and hash deep-linking.
139
+ It ships in `elements.js`.
140
+
141
+ `@getvitops/astro` gains `./components/Tree.astro` and `./components/tree.ts` (its `TreeItem`
142
+ type) to build that markup from data. As with every wrapper over a web component, `<Tree />`
143
+ emits the `<wc-tree>` tag itself with the accessible fallback inside — so `<Tree items={…} />`
144
+ is the whole call, and wrapping it in your own `<wc-tree>` nests two elements on one tree.
145
+
146
+ The slotted markup is the whole content and works without it — every node readable, expandable
147
+ and linkable — so the element only adds what CSS cannot do. Four things worth knowing:
148
+ - **The toolbar is generated, never authored.** A search field that does nothing is worse than
149
+ no search field, so the controls exist only once the element upgrades.
150
+ - **Deep-linking is the non-obvious one.** A node inside a closed `<details>` has no layout box,
151
+ so the browser's own fragment navigation finds nothing and silently stays at the top of the
152
+ page. `<wc-tree>` opens the target's ancestors — and the target's own disclosure — then scrolls.
153
+ - **Filtering matches a node's own label and description, never its subtree's text.** The obvious
154
+ `textContent` implementation makes every ancestor of a hit match, so the root matches any query
155
+ and the filter narrows nothing. That decision lives in a pure, tested module (`matchTree`)
156
+ rather than in the DOM wiring.
157
+ - **It initialises even when upgraded mid-insertion.** An element connected during an
158
+ `innerHTML` write — a view-transition swap, a client-side navigation — has no children yet
159
+ (measured: zero). Setup retries once the insertion completes, because the failure mode was
160
+ silent: no toolbar, no filter, no deep link, no error.
161
+
162
+ `patterns/tree.css` now supports two markup shapes: the item may be the `<details>` (the
163
+ pattern's original contract) or an `<li class="tree__item">` wrapping one, which is what gives
164
+ assistive tech list position and depth.
165
+
166
+ **`.tree` indent is fixed and now fluid**, which matters for any deep tree. Three separate leaks
167
+ compounded, each invisible in the CSS and each charging roughly one extra indent per level:
168
+ - the rule set both `margin-inline-start` and `padding-inline-start` to `--tree-indent`;
169
+ - `.tree { padding: var(--_p) }` applied to every nested `.tree`, not just the outermost — on all
170
+ four sides, so it narrowed from the end as well;
171
+ - `patterns/details.css` gives every non-summary child of a `<details>`
172
+ `margin-inline: var(--_content-margin)`, and its `details, .details` selector takes `:is()`
173
+ specificity under CSS nesting (**0-1-1**), so `.tree { margin: 0 }` at 0-1-0 _loses_ to it. A
174
+ nested tree is exactly such a child.
175
+
176
+ Measured in a browser: **41px per level against a 24px design**, so a 9-deep tree spent 382px on
177
+ indent and left its deepest label 162px wide. Now 24px per level, 198px total, and 653px of label.
178
+ The nested rule resets both box axes before applying the one indent it owes, and the default is
179
+ `clamp(0.75rem, 2.5vw, 1.5rem)` — 12px on a phone, 24px on a desktop — because a tree's depth is a
180
+ property of the data and cannot be known when the pattern is written. `--tree-indent` still
181
+ overrides it, and the `--lines` elbow derives from the same resolved value so the two cannot
182
+ disagree.
183
+
184
+ **Leaf rows now align with their branch siblings.** A branch spends a toggle column on its chevron
185
+ before its label; a leaf has none, so every leaf label sat one full column (24px, measured) to the
186
+ inline-start of its siblings and nothing at a given depth lined up. `.tree` exposes
187
+ `--_node-indent` (the toggle column) and `--_leaf-indent` (what a row without a toggle owes to
188
+ reach the same label column); `.tree__content` and `.tree__desc` both read the latter rather than
189
+ re-deriving the sum.
190
+
191
+ `<wc-tree>` also wraps its generated filter in `.input-group`, because `forms.css` styles text
192
+ controls as `.form-group > input` / `.input-group > input` — a bare `<input>` rendered with the
193
+ browser's 2px inset border and square corners next to the framework's own rounded controls.
194
+
195
+ `schemaTreeNodes(schema, { idPrefix, maxDepth, prune })` is new in `@getvitops/generator`: it walks
196
+ a JSON Schema — the same walk behind the `authoring.md` / `config.md` references — and returns tree
197
+ **data**, not markup, so each medium renders it (markdown for agents, an accessible `<details>`
198
+ tree for a site). Field ids are dotted config paths (`site.analytics.clarityId`), so any field can
199
+ be linked to directly.
200
+
201
+ `prune` exists for a specific hazard. The project config declares `designSystem.themes` as a
202
+ looser shape than `DesignSystemSchema`, because the full one is applied separately by
203
+ `resolveTheme` — so its embedded copy is an **approximation**, and measurably missing the
204
+ descriptions for `colors`, `colors.palette`, `colors.roles` and `colors.utilities`. Anything
205
+ rendering that copy as the token reference would silently document the colour system less well
206
+ than the toolchain already does; `prune` lets a caller stop at the wrapper and render `jsonSchema`
207
+ alongside instead.
208
+
209
+ `renderInlineMarkdown()` is exported for schema description text. It **lifts code spans out before
210
+ applying emphasis**, and that ordering is load-bearing rather than tidy: `colors.utilities`
211
+ describes its families as `` `bg-*` ``, `` `text-*` ``, `` `border-*` `` — literal asterisk
212
+ _wildcards_. Run emphasis over the raw string and the `*` closing `bg-*` pairs with the one
213
+ closing `text-*`, italicising the text between two unrelated utilities and eating both asterisks,
214
+ leaving prose that names families which don't exist. It also now renders single-asterisk emphasis,
215
+ which the schema does use (`*presentation*`, `*domain properties*`) and which previously printed
216
+ the asterisks literally.
217
+
218
+ Also fixed: `config.md` claimed "Only the wrapper is listed here" under `designSystem` and then
219
+ emitted the entire token schema anyway — `themes.<name>` _is_ a design system, so the walk
220
+ descended into it. It now stops at the wrapper and delegates to `authoring.md` as it always said
221
+ it did.
222
+
223
+ ### Patch Changes
224
+
225
+ - Updated dependencies [14813fa]
226
+ - Updated dependencies [c6b99e7]
227
+ - Updated dependencies [c6b99e7]
228
+ - Updated dependencies [f7bc0a0]
229
+ - Updated dependencies [14813fa]
230
+ - Updated dependencies [ceed51f]
231
+ - Updated dependencies [a9d7916]
232
+ - Updated dependencies [14813fa]
233
+ - Updated dependencies
234
+ - Updated dependencies [14813fa]
235
+ - @getvitops/generator@4.0.0
236
+ - @getvitops/utils@4.0.0
237
+ - @getvitops/core@4.0.0
238
+ - @getvitops/vite@4.0.0
239
+
3
240
  ## 3.0.0
4
241
 
5
242
  ### Major Changes
package/README.md CHANGED
@@ -171,7 +171,7 @@ weighs `lastmod` only while it stays consistent with what actually changed:
171
171
  - **A shallow clone gets nothing, loudly.** It shells out to `git`, so `fetch-depth: 1` (the
172
172
  actions/checkout default) yields no history — it warns and emits no dates. Set `fetch-depth: 0`.
173
173
 
174
- This is also what makes `vitops indexing` able to submit only what changed, rather than everything on
174
+ This is also what makes `vitops search notify` able to submit only what changed, rather than everything on
175
175
  every deploy.
176
176
 
177
177
  ## `<Seo />`
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { LegalOutput, SiteFont, StylesheetFormat } from "@getvitops/generator";
2
2
  import { generateIconInclude } from "@getvitops/utils";
3
+ import { AdProvider } from "@getvitops/utils/ads";
3
4
  import { OutputKind } from "@getvitops/utils/media";
4
5
  import { AstroIntegration } from "astro";
5
6
  export * from "@getvitops/utils";
@@ -102,9 +103,22 @@ interface GetvitopsConsentOptions {
102
103
  /** Link the banner to the cookie notice (`vitops legal` renders one). */
103
104
  policyUrl?: string;
104
105
  }
105
- /** One tag, fully resolved. */
106
- interface ResolvedTag {
107
- key: 'googleAnalytics' | 'clarity' | 'matomo' | 'plausible';
106
+ /**
107
+ * A third-party tag, fully resolved — everything `<GatedTags />` needs to render
108
+ * one, with nothing left to decide.
109
+ *
110
+ * Shared by `<Analytics />` and `<Ads />` on purpose: the inert-markup rule
111
+ * (`type="text/plain"`, the URL on `data-src`, never a live `src`) is the whole
112
+ * consent gate, and it must have exactly one implementation. What differs between
113
+ * the two is where the tag comes from and who decides its category, which is why
114
+ * they have separate resolvers over one shape rather than one resolver over two
115
+ * vocabularies.
116
+ *
117
+ * `key` is left to each resolver: analytics keys are its four providers, ads keys
118
+ * are `AdProvider`. Widening it into one union here would let a provider from
119
+ * either side satisfy a check meant for the other.
120
+ */
121
+ interface GatedTag {
108
122
  /** The provider as a reader would recognise it — used in warnings. */
109
123
  provider: string;
110
124
  category: ConsentCategory;
@@ -123,6 +137,10 @@ interface ResolvedTag {
123
137
  src: string | null;
124
138
  attrs: Record<string, string>;
125
139
  }
140
+ /** One analytics tag. */
141
+ interface ResolvedTag extends GatedTag {
142
+ key: 'googleAnalytics' | 'clarity' | 'matomo' | 'plausible';
143
+ }
126
144
  interface ResolvedAnalytics {
127
145
  tags: ResolvedTag[];
128
146
  /** Does anything here need `@getvitops/core/consent` loaded? */
@@ -143,7 +161,7 @@ interface ResolveAnalyticsContext {
143
161
  */
144
162
  declare function resolveAnalytics(opts: GetvitopsAnalyticsOptions | undefined, ctx?: ResolveAnalyticsContext): ResolvedAnalytics;
145
163
  /** Which optional categories a set of tags actually needs a visitor to decide. */
146
- declare function consentCategories(tags: ResolvedTag[]): OptionalConsentCategory[];
164
+ declare function consentCategories(tags: GatedTag[]): OptionalConsentCategory[];
147
165
  //#endregion
148
166
  //#region src/seo.d.ts
149
167
  /**
@@ -324,6 +342,57 @@ interface SeoContext {
324
342
  */
325
343
  declare function resolveSeo(defaults: GetvitopsSeoOptions, props: SeoProps, ctx: SeoContext): ResolvedSeo;
326
344
  //#endregion
345
+ //#region src/tracking.d.ts
346
+ /**
347
+ * The `<Tracking />` resolution layer — tracking config in, what to emit out.
348
+ *
349
+ * Separate from `Tracking.astro` for the same reason `analytics.ts` is separate
350
+ * from `Analytics.astro`: everything decidable is a pure function asserted in
351
+ * `tracking.test.ts`, and the component only renders what this returns.
352
+ *
353
+ * The one decision here is **which consent category the `_ac` cookie waits on**,
354
+ * and it is stated rather than inferred. `_ac` is a 90-day identifier tying a
355
+ * visitor to the ad that brought them, so `marketing` is the default — but a site
356
+ * using click IDs purely for its own campaign reporting may reasonably file it
357
+ * under `analytics`, and that is the consumer's call to make, not ours to guess.
358
+ */
359
+ /** Which consent category the attribution cookie waits on. */
360
+ type TrackingCategory = 'marketing' | 'analytics';
361
+ interface GetvitopsTrackingOptions {
362
+ /** Capture ad click IDs and UTMs into `_ac`. */
363
+ enabled?: boolean;
364
+ /** Default `marketing`. */
365
+ category?: TrackingCategory;
366
+ /** Informational; capture recognises every known click-ID parameter regardless. */
367
+ platforms?: string[];
368
+ }
369
+ /** The cookie the capture script writes. Mirrors `TRACKING_COOKIE` in utils. */
370
+ declare const TRACKING_COOKIE = "_ac";
371
+ interface ResolvedTracking {
372
+ enabled: boolean;
373
+ category: TrackingCategory;
374
+ /** Cookie names to clear on revoke — rides on `data-consent-cookies`. */
375
+ cookies: string[];
376
+ /** Configuration problems, as prose. The integration logs these. */
377
+ warnings: string[];
378
+ }
379
+ interface ResolveTrackingContext {
380
+ /** Is the consent gate enabled on this site (`vitops({ consent })`)? */
381
+ consent?: boolean;
382
+ /** Categories the banner offers, so we can catch a demand with no row. */
383
+ consentCategories?: readonly string[];
384
+ }
385
+ /**
386
+ * Resolve the tracking config into what the component emits.
387
+ *
388
+ * Two warnings, both about the same failure — a persistent identifier written
389
+ * with no way for the visitor to decline, or a permission asked for with no way
390
+ * to answer. Returned as data rather than logged here so the check is a test
391
+ * rather than a line someone might scroll past, exactly as `resolveAnalytics`
392
+ * does.
393
+ */
394
+ declare function resolveTracking(opts: GetvitopsTrackingOptions | undefined, ctx?: ResolveTrackingContext): ResolvedTracking;
395
+ //#endregion
327
396
  //#region src/integration.d.ts
328
397
  interface GetvitopsFaviconOptions {
329
398
  /** Source SVG or PNG. */
@@ -400,7 +469,7 @@ interface GetvitopsCssOptions {
400
469
  *
401
470
  * Off by default: turning it on flips the site dark for dark-OS visitors, which
402
471
  * is a visible change to an existing site. Turning it **on** is what makes
403
- * `<color-scheme-toggle>`'s "System" position do anything (System removes the
472
+ * `<wc-color-scheme-toggle>`'s "System" position do anything (System removes the
404
473
  * theme attribute, so without this block it falls through to light), and it is
405
474
  * the only way a no-JS page gets the OS appearance at all.
406
475
  *
@@ -663,6 +732,21 @@ interface GetvitopsOptions {
663
732
  * actually offers.
664
733
  */
665
734
  consent?: boolean | GetvitopsConsentOptions;
735
+ /**
736
+ * Ad-click attribution for `<Tracking />` — capture click IDs and UTMs from the
737
+ * landing URL into the `_ac` cookie, so a conversion can be attributed to the
738
+ * ad that produced it. Off unless provided.
739
+ *
740
+ * `_ac` is a 90-day identifier, so writing it waits on consent (`marketing` by
741
+ * default) — and **asking for that permission is what raises the banner**, on
742
+ * the arrival that carried a click ID and on no other. A visitor who arrives
743
+ * organically has nothing to attribute and is never asked.
744
+ *
745
+ * Read the cookie back with `parseTrackingCookie` from
746
+ * `@getvitops/utils/tracking`, and turn a conversion into a notification with
747
+ * `@getvitops/utils/notify`.
748
+ */
749
+ tracking?: boolean | GetvitopsTrackingOptions;
666
750
  }
667
751
  interface GetvitopsFontsOptions {
668
752
  /** Path to a site config (JSON) whose `fonts` array holds the declarations. */
@@ -718,6 +802,48 @@ interface GetvitopsIconsOptions {
718
802
  }
719
803
  declare function vitops(opts?: GetvitopsOptions): AstroIntegration;
720
804
  //#endregion
805
+ //#region src/ads.d.ts
806
+ /**
807
+ * One ad property, mirroring a `site.ads` entry field for field.
808
+ *
809
+ * Structural rather than `SiteAdProperty` imported from the generator, matching
810
+ * how `GetvitopsSeoOptions` and `GetvitopsTrackingOptions` already work: the
811
+ * component surface must stay usable by a consumer who passes a plain object.
812
+ */
813
+ interface GetvitopsAdProperty {
814
+ accountId?: string;
815
+ pixelId?: string;
816
+ conversionLabel?: string;
817
+ /** Default `marketing`. `analytics` for a property used purely for measurement. */
818
+ category?: 'marketing' | 'analytics';
819
+ /** False keeps the property on record without emitting its tag. */
820
+ enabled?: boolean;
821
+ }
822
+ type GetvitopsAdsOptions = Partial<Record<AdProvider, GetvitopsAdProperty>>;
823
+ /** One ad tag. `key` is the platform, so a caller can find one without matching prose. */
824
+ interface ResolvedAdTag extends GatedTag {
825
+ key: AdProvider;
826
+ }
827
+ interface ResolvedAds {
828
+ tags: ResolvedAdTag[];
829
+ /** Does anything here need `@getvitops/core/consent` loaded? */
830
+ needsRuntime: boolean;
831
+ /** Configuration problems, as prose. The integration logs these. */
832
+ warnings: string[];
833
+ }
834
+ interface ResolveAdsContext {
835
+ /** Is the consent gate enabled on this site (`vitops({ consent })`)? */
836
+ consent?: boolean;
837
+ /** Categories the banner offers, so we can catch a demand with no row. */
838
+ consentCategories?: readonly string[];
839
+ /** `environments.<env>.ads` — false switches every tag off for this build. */
840
+ enabled?: boolean;
841
+ /** When the tags load. Default `idle`: a pixel is never worth the critical path. */
842
+ strategy?: AnalyticsStrategy;
843
+ }
844
+ /** Resolve the configured ad properties into the tags `<Ads />` emits. */
845
+ declare function resolveAds(ads: GetvitopsAdsOptions | undefined, ctx?: ResolveAdsContext): ResolvedAds;
846
+ //#endregion
721
847
  //#region src/lastmod.d.ts
722
848
  interface GitLastmodOptions {
723
849
  /** Directories to read history from (default `src/pages`, `src/content`, `src/data`). */
@@ -747,5 +873,5 @@ declare function slugFromContent(file: string): string | undefined;
747
873
  */
748
874
  declare function gitLastmod(options?: GitLastmodOptions): Promise<(item: GetvitopsSitemapEntry) => GetvitopsSitemapEntry>;
749
875
  //#endregion
750
- export { type AnalyticsStrategy, type ClarityOptions, type ConsentCategory, type GetvitopsAnalyticsOptions, type GetvitopsConsentOptions, type GetvitopsCssOptions, type GetvitopsFaviconOptions, type GetvitopsMediaOptions, type GetvitopsOptions, type GetvitopsSeoOptions, type GetvitopsSitemapChangeFreq, type GetvitopsSitemapEntry, type GetvitopsSitemapOptions, type GitLastmodOptions, type GoogleAnalyticsOptions, type MatomoOptions, type OptionalConsentCategory, type PlausibleOptions, type ResolveAnalyticsContext, type ResolvedAnalytics, type ResolvedSeo, type ResolvedTag, type SeoContext, type SeoNameTag, type SeoOgType, type SeoPropertyTag, type SeoProps, type SeoTwitterCard, consentCategories, vitops as default, gitLastmod, resolveAnalytics, resolveSeo, routeFromPage, slugFromContent };
876
+ export { type AnalyticsStrategy, type ClarityOptions, type ConsentCategory, type GatedTag, type GetvitopsAdProperty, type GetvitopsAdsOptions, type GetvitopsAnalyticsOptions, type GetvitopsConsentOptions, type GetvitopsCssOptions, type GetvitopsFaviconOptions, type GetvitopsMediaOptions, type GetvitopsOptions, type GetvitopsSeoOptions, type GetvitopsSitemapChangeFreq, type GetvitopsSitemapEntry, type GetvitopsSitemapOptions, type GetvitopsTrackingOptions, type GitLastmodOptions, type GoogleAnalyticsOptions, type MatomoOptions, type OptionalConsentCategory, type PlausibleOptions, type ResolveAdsContext, type ResolveAnalyticsContext, type ResolveTrackingContext, type ResolvedAdTag, type ResolvedAds, type ResolvedAnalytics, type ResolvedSeo, type ResolvedTag, type ResolvedTracking, type SeoContext, type SeoNameTag, type SeoOgType, type SeoPropertyTag, type SeoProps, type SeoTwitterCard, TRACKING_COOKIE, type TrackingCategory, consentCategories, vitops as default, gitLastmod, resolveAds, resolveAnalytics, resolveSeo, resolveTracking, routeFromPage, slugFromContent };
751
877
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/analytics.ts","../src/seo.ts","../src/integration.ts","../src/lastmod.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/analytics.ts","../src/seo.ts","../src/tracking.ts","../src/integration.ts","../src/ads.ts","../src/lastmod.ts"],"mappings":"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"}