@buildinams/core 0.3.0 → 0.4.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/README.md +24 -1
- package/dist/analytics/google/index.d.ts +158 -0
- package/dist/analytics/google/index.js +274 -0
- package/dist/analytics/google/index.js.map +1 -0
- package/dist/analytics/index.d.ts +101 -0
- package/dist/analytics/index.js +384 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/shopify/index.d.ts +186 -0
- package/dist/analytics/shopify/index.js +175 -0
- package/dist/analytics/shopify/index.js.map +1 -0
- package/dist/{chunk-IAAQVL6M.js → chunk-FJ7SNQQI.js} +24 -5
- package/dist/chunk-FJ7SNQQI.js.map +1 -0
- package/dist/chunk-G2BKC4BU.js +8 -0
- package/dist/chunk-G2BKC4BU.js.map +1 -0
- package/dist/chunk-GQVN2ECX.js +14 -0
- package/dist/chunk-GQVN2ECX.js.map +1 -0
- package/dist/chunk-LL3VTFNY.js +22 -0
- package/dist/chunk-LL3VTFNY.js.map +1 -0
- package/dist/chunk-M3HNM5HC.js +48 -0
- package/dist/chunk-M3HNM5HC.js.map +1 -0
- package/dist/chunk-MHFGMH3G.js +11 -0
- package/dist/chunk-MHFGMH3G.js.map +1 -0
- package/dist/chunk-OS2T6P2T.js +50 -0
- package/dist/chunk-OS2T6P2T.js.map +1 -0
- package/dist/chunk-QIJGG2F4.js +51 -0
- package/dist/chunk-QIJGG2F4.js.map +1 -0
- package/dist/consent/cookiebot/index.d.ts +16 -0
- package/dist/consent/cookiebot/index.js +27 -0
- package/dist/consent/cookiebot/index.js.map +1 -0
- package/dist/consent/google/index.d.ts +23 -0
- package/dist/consent/google/index.js +48 -0
- package/dist/consent/google/index.js.map +1 -0
- package/dist/consent/index.d.ts +1 -0
- package/dist/consent/index.js +3 -0
- package/dist/consent/index.js.map +1 -0
- package/dist/consent/onetrust/index.d.ts +23 -0
- package/dist/consent/onetrust/index.js +39 -0
- package/dist/consent/onetrust/index.js.map +1 -0
- package/dist/consent/shopify/index.d.ts +44 -0
- package/dist/consent/shopify/index.js +84 -0
- package/dist/consent/shopify/index.js.map +1 -0
- package/dist/cookies/index.d.ts +230 -0
- package/dist/cookies/index.js +188 -0
- package/dist/cookies/index.js.map +1 -0
- package/dist/define-events-CxZjoUlG.d.ts +255 -0
- package/dist/destination-5KJ5PeR3.d.ts +122 -0
- package/dist/index-Zef1nnTP.d.ts +36 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +64 -1
- package/dist/index.js.map +1 -1
- package/dist/listeners-DkU-vBPa.d.ts +15 -0
- package/dist/navigation/index.d.ts +1 -1
- package/dist/navigation/index.js +1 -1
- package/dist/schema/index.d.ts +16 -9
- package/dist/schema/index.js +1 -1
- package/dist/schema-CfQvhbuU.d.ts +87 -0
- package/dist/store/index.js +1 -1
- package/dist/tracking/cart/index.d.ts +74 -0
- package/dist/tracking/cart/index.js +118 -0
- package/dist/tracking/cart/index.js.map +1 -0
- package/dist/tracking/dom/index.d.ts +320 -0
- package/dist/tracking/dom/index.js +1196 -0
- package/dist/tracking/dom/index.js.map +1 -0
- package/docs/analytics.md +883 -0
- package/docs/cookies.md +354 -0
- package/docs/decisions/001-analytics-project-events.md +31 -0
- package/docs/decisions/002-tracking-dom-opt-in.md +29 -0
- package/docs/decisions/003-tracking-element-data.md +27 -0
- package/docs/decisions/004-cookies-explicit-store.md +26 -0
- package/docs/decisions/005-cookies-invalid-reads-fall-back.md +27 -0
- package/docs/decisions/006-cookies-server-only-types.md +19 -0
- package/docs/decisions/007-cookies-options-on-definition.md +25 -0
- package/docs/decisions/008-cookies-in-vertical-slices.md +24 -0
- package/docs/decisions/009-analytics-consent-targets.md +29 -0
- package/docs/decisions/010-analytics-destination-contract.md +29 -0
- package/docs/decisions/011-tracking-decoupled.md +30 -0
- package/docs/tracking.md +221 -0
- package/package.json +84 -3
- package/dist/chunk-IAAQVL6M.js.map +0 -1
- package/dist/chunk-SIU7SKJK.js +0 -139
- package/dist/chunk-SIU7SKJK.js.map +0 -1
- package/dist/schema-iy92gbTC.d.ts +0 -36
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { l as Clicked, d as EventCatalog, m as EcommerceOccurrences, j as EcommerceShapes, n as ShapeLeaf, F as FormUsed, P as PageViewed, o as Scrolled, V as VideoPlayed } from '../../define-events-CxZjoUlG.js';
|
|
2
|
+
export { p as PageType } from '../../define-events-CxZjoUlG.js';
|
|
3
|
+
import { S as Subscribe } from '../../listeners-DkU-vBPa.js';
|
|
4
|
+
|
|
5
|
+
/** The data, or a function that builds it when a plugin first reads it, e.g. when the element becomes visible. */
|
|
6
|
+
type TrackValue<Data> = Data | (() => Data);
|
|
7
|
+
|
|
8
|
+
declare const ROLE = "data-track";
|
|
9
|
+
type AutoTrackKind = "links" | "forms";
|
|
10
|
+
|
|
11
|
+
/** What a plugin reports, as the watcher's listeners receive it. */
|
|
12
|
+
type DomEvent<Name extends string = string, Payload extends object = object, Source extends Element | undefined = Element | undefined> = undefined extends Source ? {
|
|
13
|
+
name: Name;
|
|
14
|
+
payload: Payload;
|
|
15
|
+
} : {
|
|
16
|
+
name: Name;
|
|
17
|
+
payload: Payload;
|
|
18
|
+
element: Source;
|
|
19
|
+
};
|
|
20
|
+
declare const plugin: unique symbol;
|
|
21
|
+
/**
|
|
22
|
+
* Created by `pageViews()`, `ecommerce()`, `clicks()`, `videos()`, `forms()` or `scroll()`, and passed to
|
|
23
|
+
* `createDomWatcher()`. Its type says what it reports, and the fields, data and `auto` kinds `track()` takes.
|
|
24
|
+
*/
|
|
25
|
+
type DomPlugin<Event extends DomEvent = DomEvent, Attributes extends object = object, Data extends object = object, Auto extends AutoTrackKind = AutoTrackKind> = {
|
|
26
|
+
readonly [plugin]?: {
|
|
27
|
+
event: Event;
|
|
28
|
+
attributes: Attributes;
|
|
29
|
+
data: Data;
|
|
30
|
+
auto: Auto;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
/** A plugin's own `data-track-<field>` attributes, each a string. */
|
|
34
|
+
type CustomFields = Record<string, string>;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Plugin for `createDomWatcher()`: `clicked` for links and buttons with `track({ click })`, and links inside
|
|
38
|
+
* `track({ auto: "links" })`, with `location` from the nearest `track({ location })`. `Fields` are the project's own
|
|
39
|
+
* fields of `click`, also in the payload.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* clicks<{ cta: string }>();
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
declare const clicks: <Fields extends CustomFields = Record<never, never>>() => DomPlugin<{
|
|
47
|
+
name: "clicked";
|
|
48
|
+
payload: Clicked & Partial<Fields>;
|
|
49
|
+
element: Element;
|
|
50
|
+
}, {
|
|
51
|
+
click: {
|
|
52
|
+
id?: string;
|
|
53
|
+
} & Fields;
|
|
54
|
+
location: {
|
|
55
|
+
name: string;
|
|
56
|
+
};
|
|
57
|
+
}, Record<never, never>, "links">;
|
|
58
|
+
|
|
59
|
+
/** What `track()` returns to spread on the element. */
|
|
60
|
+
type TrackProps = {
|
|
61
|
+
[ROLE]?: string;
|
|
62
|
+
} & {
|
|
63
|
+
[name: `${typeof ROLE}-${string}`]: string;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
type DomWatcherOptions = {
|
|
67
|
+
/** Where the plugins watch for markup and events. Defaults to `document`. */
|
|
68
|
+
root?: Document | Element;
|
|
69
|
+
};
|
|
70
|
+
type UnionToIntersection<Union> = (Union extends unknown ? (value: Union) => void : never) extends (value: infer Intersection) => void ? Intersection : never;
|
|
71
|
+
type Brand<Plugin> = NonNullable<Plugin extends DomPlugin ? Plugin[keyof Plugin] : never>;
|
|
72
|
+
/** What the plugins report, as the watcher's listeners receive it. */
|
|
73
|
+
type DomEventOf<Plugins extends readonly DomPlugin[]> = Brand<Plugins[number]>["event"];
|
|
74
|
+
type AttributesOf<Plugins extends readonly DomPlugin[]> = UnionToIntersection<Brand<Plugins[number]>["attributes"]>;
|
|
75
|
+
type DataOf<Plugins extends readonly DomPlugin[]> = UnionToIntersection<Brand<Plugins[number]>["data"]>;
|
|
76
|
+
type AutoOf<Plugins extends readonly DomPlugin[]> = Brand<Plugins[number]>["auto"];
|
|
77
|
+
/** Payloads of the plugins' events, by name. */
|
|
78
|
+
type EventMapOf<Event extends {
|
|
79
|
+
name: string;
|
|
80
|
+
payload: object;
|
|
81
|
+
}> = {
|
|
82
|
+
[E in Event as E["name"]]: E["payload"];
|
|
83
|
+
};
|
|
84
|
+
/** What `track()` takes: per type, its fields, or `true` when they're all optional, and data for `ecommerce()`. */
|
|
85
|
+
type TrackSpec<Plugins extends readonly DomPlugin[]> = {
|
|
86
|
+
[T in keyof AttributesOf<Plugins>]?: Record<never, never> extends AttributesOf<Plugins>[T] ? AttributesOf<Plugins>[T] | true : AttributesOf<Plugins>[T];
|
|
87
|
+
} & {
|
|
88
|
+
[R in keyof DataOf<Plugins>]?: TrackValue<DataOf<Plugins>[R]> | undefined;
|
|
89
|
+
} & ([AutoOf<Plugins>] extends [never] ? unknown : {
|
|
90
|
+
auto?: AutoOf<Plugins> | readonly [AutoOf<Plugins>, ...AutoOf<Plugins>[]] | false;
|
|
91
|
+
});
|
|
92
|
+
type Tracked<Spec, Data> = [keyof Spec & keyof Data] extends [never] ? TrackProps : TrackProps & {
|
|
93
|
+
ref: (element: Element | null) => void;
|
|
94
|
+
};
|
|
95
|
+
type DomWatcher<Plugins extends readonly DomPlugin[]> = {
|
|
96
|
+
/**
|
|
97
|
+
* Props to spread on an element, so the plugins track it. Each key is a type, written in `data-track`, with its fields
|
|
98
|
+
* as `data-track-<field>` attributes, so server components and CMS markup can write them too. Only the types of the
|
|
99
|
+
* watcher's plugins:
|
|
100
|
+
*
|
|
101
|
+
* - `pageView`: `pageViewed` when the element appears, with `pageViews()`. Put it on each page's root.
|
|
102
|
+
* - `click`: `clicked` for this button or link, with `clicks()`. Buttons always need it.
|
|
103
|
+
* - `location`: `location` on every `clicked` inside it, with `clicks()`. Reports nothing by itself.
|
|
104
|
+
* - `auto`: tracks every link (`"links"`) or form (`"forms"`) inside it, with `clicks()` and `forms()`; `false` turns
|
|
105
|
+
* it off for a subtree. The nearest one decides.
|
|
106
|
+
* - `video`: video events for this `<video>` or the videos inside it, with `videos()`.
|
|
107
|
+
* - `form`: `formStarted` and `formSubmitted` for this form, with `forms()`.
|
|
108
|
+
* - `scroll`: `scrolled` as the visitor scrolls through this element, with `scroll()`.
|
|
109
|
+
*
|
|
110
|
+
* The project's item, list or promotion, for `ecommerce()`, come with a `ref`, which sets the data on the element
|
|
111
|
+
* once it mounts, so it stays out of the HTML. Without data, e.g. while a quick view is closed, the element isn't
|
|
112
|
+
* tracked as one.
|
|
113
|
+
*
|
|
114
|
+
* - `viewItem`: `itemViewed` when visible, once per URL for each product. On a product page.
|
|
115
|
+
* - `quickView`: `itemViewed` each time it becomes visible. On a quick view.
|
|
116
|
+
* - `promotion`: `promotionViewed` when visible, `promotionSelected` for clicks inside it.
|
|
117
|
+
* - `list`: places the items inside it in the list.
|
|
118
|
+
* - `item`: `itemsViewed` when visible, batched per list, `itemSelected` for clicks inside it.
|
|
119
|
+
*
|
|
120
|
+
* Data can be a function, built when the plugin first reads it, e.g. when the element becomes visible; once read, a
|
|
121
|
+
* new function from a later render is built to compare it, so keep it stable where building is costly. An element
|
|
122
|
+
* with its own ref needs a ref that calls both. Without a framework, call `ref` with the element: it also adds or
|
|
123
|
+
* removes the data's types.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```tsx
|
|
127
|
+
* <main {...track({ pageView: { pageType: "product" } })}>
|
|
128
|
+
* <footer {...track({ auto: "links", location: { name: "footer" } })}>
|
|
129
|
+
* <section {...track({ promotion: { id: "summer" }, location: { name: "hero" } })}>
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
track: <Spec extends TrackSpec<Plugins>>(spec: Spec & Record<Exclude<keyof Spec, keyof TrackSpec<Plugins>>, never>) => Tracked<Spec, DataOf<Plugins>>;
|
|
133
|
+
/**
|
|
134
|
+
* Hands what the plugins report to `listener`: every event, or only those named. Pass the watcher to
|
|
135
|
+
* `createAnalytics()`'s `sources` instead to track them. The first subscription starts the plugins in the browser,
|
|
136
|
+
* and the last one to unsubscribe stops them. What they report while starting, e.g. a server-rendered page's view,
|
|
137
|
+
* reaches every subscription made in the same task.
|
|
138
|
+
*/
|
|
139
|
+
subscribe: Subscribe<DomEventOf<Plugins>>;
|
|
140
|
+
/** Catalog entries for what the plugins report, to spread into `defineEvents()`. */
|
|
141
|
+
events: EventCatalog<EventMapOf<DomEventOf<Plugins>>>;
|
|
142
|
+
/**
|
|
143
|
+
* Tells the plugins a new page is shown, for a router that tracks page views itself instead of `pageViews()`. Views
|
|
144
|
+
* pending from the previous page are emitted, and what stays in view counts again.
|
|
145
|
+
*/
|
|
146
|
+
newPage: () => void;
|
|
147
|
+
/** Emits the views `ecommerce()` batches, e.g. right before tracking an event that must come after them. */
|
|
148
|
+
flush: () => void;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Watches markup with the plugins you pass and reports what happens, so call sites only need the watcher's `track()`.
|
|
152
|
+
* Creating it does nothing, so server components can import it; the first `subscribe()` starts it in the browser:
|
|
153
|
+
*
|
|
154
|
+
* - `pageViews()`: `pageViewed` for `track({ pageView })`.
|
|
155
|
+
* - `ecommerce()`: `itemViewed`, `itemsViewed`, `itemSelected`, `promotionViewed` and `promotionSelected` for
|
|
156
|
+
* `track({ viewItem | quickView | list | item | promotion })`.
|
|
157
|
+
* - `clicks()`: `clicked` for links and buttons with `track({ click })`, and links inside `track({ auto: "links" })`.
|
|
158
|
+
* - `videos()`: `videoStarted`, `videoProgressed` and `videoCompleted` for `track({ video })`.
|
|
159
|
+
* - `forms()`: `formStarted` and `formSubmitted` for `track({ form })`, and forms inside `track({ auto: "forms" })`.
|
|
160
|
+
* - `scroll()`: `scrolled` as `track({ scroll })` is scrolled into view, by default at 25, 50, 75 and 90%.
|
|
161
|
+
*
|
|
162
|
+
* The plugins decide which types `track()` takes, and with which fields and data. Nothing is tracked without its type
|
|
163
|
+
* in `data-track`, so a project decides what reaches analytics. Works with server-rendered and CMS markup, as it
|
|
164
|
+
* listens on the root instead of the elements.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* export const domWatcher = createDomWatcher([pageViews(), clicks<{ cta: string }>(), ecommerce<{ item: Item }>()]);
|
|
169
|
+
* export const { track } = domWatcher;
|
|
170
|
+
*
|
|
171
|
+
* export const events = defineEvents({ ...domWatcher.events });
|
|
172
|
+
* export const analytics = createAnalytics<EventsOf<typeof events>>({ events, sources: [domWatcher], consent });
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
declare const createDomWatcher: <const Plugins extends readonly DomPlugin[]>(plugins: Plugins, { root: rootOption }?: DomWatcherOptions) => DomWatcher<Plugins>;
|
|
176
|
+
|
|
177
|
+
type Occurrences = EcommerceOccurrences<EcommerceShapes>;
|
|
178
|
+
/** The project's item, and its list and promotion when it has them. */
|
|
179
|
+
type EcommerceInput = {
|
|
180
|
+
item: object;
|
|
181
|
+
list?: object;
|
|
182
|
+
promotion?: object;
|
|
183
|
+
};
|
|
184
|
+
type Complete<Shapes extends EcommerceInput> = {
|
|
185
|
+
item: Shapes["item"];
|
|
186
|
+
list: ShapeLeaf<Shapes, "list">;
|
|
187
|
+
promotion: ShapeLeaf<Shapes, "promotion">;
|
|
188
|
+
};
|
|
189
|
+
type EcommerceEvent<Shapes extends EcommerceInput> = {
|
|
190
|
+
[K in keyof Occurrences]: DomEvent<K, EcommerceOccurrences<Complete<Shapes>>[K], undefined>;
|
|
191
|
+
}[keyof Occurrences];
|
|
192
|
+
type EcommerceData<Shapes extends EcommerceInput> = {
|
|
193
|
+
viewItem: Shapes["item"];
|
|
194
|
+
quickView: Shapes["item"];
|
|
195
|
+
item: Shapes["item"];
|
|
196
|
+
} & Pick<Complete<Shapes>, Extract<keyof Shapes, "list" | "promotion">>;
|
|
197
|
+
type EcommerceOptions<Item = object> = {
|
|
198
|
+
/**
|
|
199
|
+
* Which product an item is, e.g. `({ product }) => product.id`, so a product page's `{ product, variant }` matches
|
|
200
|
+
* the `{ product }` of the card it was selected on, and counts as one view per product. Defaults to the item's JSON.
|
|
201
|
+
*/
|
|
202
|
+
id?: (item: Item) => string;
|
|
203
|
+
/** Share of a promotion or item, or of the viewport for those taller than it, that counts as viewed. */
|
|
204
|
+
threshold?: number;
|
|
205
|
+
/**
|
|
206
|
+
* Milliseconds that views are collected for before they're tracked in the order they happened, with one
|
|
207
|
+
* `itemsViewed` per list.
|
|
208
|
+
*/
|
|
209
|
+
batchDelay?: number;
|
|
210
|
+
/**
|
|
211
|
+
* Where the tab keeps the placements of the products last selected, so a product page loaded in full, e.g. on a
|
|
212
|
+
* multi-page site, gets the list it was selected from. Change it when the list's or promotion's shape changes. Default
|
|
213
|
+
* `"analytics-placements"`.
|
|
214
|
+
*/
|
|
215
|
+
storageKey?: string;
|
|
216
|
+
};
|
|
217
|
+
/**
|
|
218
|
+
* Plugin for `createDomWatcher()`: views and selections of products, lists and promotions, with the data passed to the
|
|
219
|
+
* watcher's `track()`, placed by the markup around it:
|
|
220
|
+
*
|
|
221
|
+
* - `itemViewed` for `track({ viewItem })` when it becomes visible, and `track({ quickView })` each time it does.
|
|
222
|
+
* - `promotionViewed` and `promotionSelected` for `track({ promotion })`.
|
|
223
|
+
* - `itemsViewed` and `itemSelected` for `track({ item })`, inside `track({ list })`.
|
|
224
|
+
*
|
|
225
|
+
* Views are batched, and emitted before anything else the watcher emits. Leave out `list` or `promotion` when the
|
|
226
|
+
* project has none.
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```ts
|
|
230
|
+
* ecommerce<{ item: { product: ProductFragment; variant?: VariantFragment }; list: List }>({
|
|
231
|
+
* id: ({ product }) => product.id,
|
|
232
|
+
* });
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
declare const ecommerce: <Shapes extends EcommerceInput>({ id, threshold, batchDelay, storageKey, }?: EcommerceOptions<Shapes["item"]>) => DomPlugin<EcommerceEvent<Shapes>, Record<never, never>, EcommerceData<Shapes>, never>;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Plugin for `createDomWatcher()`: `formStarted` and `formSubmitted` for forms with `track({ form })` or inside
|
|
239
|
+
* `track({ auto: "forms" })`. Never field values. `Fields` are the project's own fields of `form`, also in
|
|
240
|
+
* the payload.
|
|
241
|
+
*/
|
|
242
|
+
declare const forms: <Fields extends CustomFields = Record<never, never>>() => DomPlugin<{
|
|
243
|
+
name: "formStarted";
|
|
244
|
+
payload: FormUsed & Partial<Fields>;
|
|
245
|
+
element: HTMLFormElement;
|
|
246
|
+
} | {
|
|
247
|
+
name: "formSubmitted";
|
|
248
|
+
payload: FormUsed & {
|
|
249
|
+
formSubmitText?: string;
|
|
250
|
+
} & Partial<Fields>;
|
|
251
|
+
element: HTMLFormElement;
|
|
252
|
+
}, {
|
|
253
|
+
form: {
|
|
254
|
+
id?: string;
|
|
255
|
+
} & Fields;
|
|
256
|
+
}, Record<never, never>, "forms">;
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Plugin for `createDomWatcher()`: `pageViewed` for elements with `track({ pageView })` when they appear or are shown
|
|
260
|
+
* again, once per URL. `Fields` are the project's own fields of `pageView`, also in the payload.
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```ts
|
|
264
|
+
* pageViews<{ section: string }>();
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
declare const pageViews: <Fields extends CustomFields = Record<never, never>>() => DomPlugin<{
|
|
268
|
+
name: "pageViewed";
|
|
269
|
+
payload: PageViewed & Partial<Fields>;
|
|
270
|
+
element: Element;
|
|
271
|
+
}, {
|
|
272
|
+
pageView: PageViewed & Fields;
|
|
273
|
+
}, Record<never, never>, never>;
|
|
274
|
+
|
|
275
|
+
type ScrollOptions = {
|
|
276
|
+
/** Percentages of the element scrolled into view that each report `scrolled` once per URL. */
|
|
277
|
+
thresholds?: readonly number[];
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Plugin for `createDomWatcher()`: `scrolled` for elements with `track({ scroll })`, once per URL for each threshold
|
|
281
|
+
* (25, 50, 75 and 90%) of the element scrolled into view. Only after a scroll, also a restored scroll position, so an
|
|
282
|
+
* element that fits the viewport isn't tracked on load. Put it on the page's root for scroll depth, or on an article.
|
|
283
|
+
* `Fields` are the project's own fields of `scroll`, also in the payload.
|
|
284
|
+
*/
|
|
285
|
+
declare const scroll: <Fields extends CustomFields = Record<never, never>>({ thresholds, }?: ScrollOptions) => DomPlugin<{
|
|
286
|
+
name: "scrolled";
|
|
287
|
+
payload: Scrolled & Partial<Fields>;
|
|
288
|
+
element: Element;
|
|
289
|
+
}, {
|
|
290
|
+
scroll: {
|
|
291
|
+
id?: string;
|
|
292
|
+
} & Fields;
|
|
293
|
+
}, Record<never, never>, never>;
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Plugin for `createDomWatcher()`: `videoStarted`, `videoProgressed` (10, 25, 50 and 75%) and `videoCompleted` for
|
|
297
|
+
* `<video>` elements with, or inside, `track({ video })`, so decorative loops aren't tracked. `Fields` are the
|
|
298
|
+
* project's own fields of `video`, also in the payload.
|
|
299
|
+
*/
|
|
300
|
+
declare const videos: <Fields extends CustomFields = Record<never, never>>() => DomPlugin<{
|
|
301
|
+
name: "videoStarted";
|
|
302
|
+
payload: VideoPlayed & Partial<Fields>;
|
|
303
|
+
element: HTMLVideoElement;
|
|
304
|
+
} | {
|
|
305
|
+
name: "videoProgressed";
|
|
306
|
+
payload: VideoPlayed & {
|
|
307
|
+
videoPercent: number;
|
|
308
|
+
} & Partial<Fields>;
|
|
309
|
+
element: HTMLVideoElement;
|
|
310
|
+
} | {
|
|
311
|
+
name: "videoCompleted";
|
|
312
|
+
payload: VideoPlayed & Partial<Fields>;
|
|
313
|
+
element: HTMLVideoElement;
|
|
314
|
+
}, {
|
|
315
|
+
video: {
|
|
316
|
+
title?: string;
|
|
317
|
+
} & Fields;
|
|
318
|
+
}, Record<never, never>, never>;
|
|
319
|
+
|
|
320
|
+
export { type DomPlugin, type DomWatcher, type DomWatcherOptions, type EcommerceOptions, type TrackProps, type TrackSpec, clicks, createDomWatcher, ecommerce, forms, pageViews, scroll, videos };
|