From 6cf0bd28068a6c183f2d3383c7bb670ccefa8639 Mon Sep 17 00:00:00 2001 From: "AzureAD\\kevinvoortmans" Date: Thu, 23 Oct 2025 14:22:00 +0200 Subject: [PATCH 1/5] Added new Hooks --- .changeset/nasty-lamps-eat.md | 5 ++++ apps/docs/slots.md | 10 +++++--- apps/example/src/main.ts | 30 ++++++++++++++++++----- packages/sdk/src/slot/slot.composables.ts | 10 +++++++- packages/sdk/src/slot/slot.ts | 10 ++++++++ packages/sdk/src/slot/slot.types.ts | 8 ++++++ 6 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 .changeset/nasty-lamps-eat.md diff --git a/.changeset/nasty-lamps-eat.md b/.changeset/nasty-lamps-eat.md new file mode 100644 index 00000000..f84784c4 --- /dev/null +++ b/.changeset/nasty-lamps-eat.md @@ -0,0 +1,5 @@ +--- +"@adhese/sdk": patch +--- + +Added 2 new slot hooks: onImpressionTracked and onViewableTracked. Triggering when an impression and viewability tracker is being fired off. diff --git a/apps/docs/slots.md b/apps/docs/slots.md index d84d6c6d..5173c70f 100644 --- a/apps/docs/slots.md +++ b/apps/docs/slots.md @@ -204,11 +204,13 @@ adhese.addSlot({ ### Slot hooks In a setup function the following hooks are available: -- `onBeforeRender` Hook that is called when the format of the slot changes. -- `onRender` Hook that is called when the slot is rendered. +- `onInit` Hook that is called when the slot is initialized. - `onBeforeRequest` Hook that is called before the slot is requested from the server. Can be used to hijack the request entirely by returning a `AdheseAd` yourself. If you pass an ad yourself the request to the server is ignored and your ad is used. - `onRequest` Hook that is called when the slot is requested from the server. -- `onInit` Hook that is called when the slot is initialized. -- `onDispose` Hook that is called when the slot is disposed. - `onEmpty` Hook that is called when the slot is empty. +- `onBeforeRender` Hook that is called when the format of the slot changes. +- `onRender` Hook that is called when the slot is rendered. +- `onImpressionTracked` Hook that is called when the slots impressions is tracked. +- `onViewableTracked` Hook that is called when the slots viewable impressions is tracked. +- `onDispose` Hook that is called when the slot is disposed. - `onError` Hook that is called when the slot encounters an error. diff --git a/apps/example/src/main.ts b/apps/example/src/main.ts index 0c7ba204..b29612e6 100644 --- a/apps/example/src/main.ts +++ b/apps/example/src/main.ts @@ -2,22 +2,31 @@ import { createAdhese } from '@adhese/sdk'; import { devtoolsPlugin } from '@adhese/sdk-devtools'; const adhese = createAdhese({ - account: 'demo', + account: 'adusatest', debug: true, consent: true, initialSlots: [ { - format: 'halfpage', + format: 'flex', + slot: "_1", containingElement: 'skyscraper', setup(context, hooks): void { hooks.onEmpty(() => { /* eslint-disable no-console */ console.log('triggering empty', context); }); - }, + hooks.onImpressionTracked((ad)=> { + console.log("Impression Tracked fire for:", ad) + }) + hooks.onViewableTracked((ad)=> { + console.log("Viewable Impression tracked fire for:", ad) + }) + }, + width: "970px", + height: "250px" }, ], - location: 'demo.com_kitchen', + location: 'stopandshop.com_website_home', refreshOnResize: false, plugins: [devtoolsPlugin], }); @@ -25,12 +34,21 @@ const adhese = createAdhese({ window.adhese = adhese; adhese.addSlot({ - format: 'billboard', + format: 'flex', containingElement: 'leaderboard', + slot:"_2", renderMode: 'inline', setup(context, hooks): void { hooks.onEmpty(() => { console.log('triggering empty', context); }); - }, + hooks.onImpressionTracked((ad)=> { + console.log("Impression Tracked fire for:", ad) + }) + hooks.onViewableTracked((ad)=> { + console.log("Viewable Impression tracked fire for:", ad) + }) + }, + width: "970px", + height: "250px" }); diff --git a/packages/sdk/src/slot/slot.composables.ts b/packages/sdk/src/slot/slot.composables.ts index 80a6bac7..989cbe59 100644 --- a/packages/sdk/src/slot/slot.composables.ts +++ b/packages/sdk/src/slot/slot.composables.ts @@ -152,6 +152,8 @@ export function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref>[0]; runOnEmpty: ReturnType>[0]; runOnError: ReturnType>[0]; + runOnImpressionTracked: ReturnType>[0]; + runOnViewableTracked: ReturnType>[0]; } & AdheseSlotHooks { const [runOnBeforeRender, onBeforeRender, disposeOnBeforeRender] = createAsyncHook(); const [runOnRender, onRender, disposeOnRender] = createPassiveHook(); @@ -161,6 +163,8 @@ export function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref(); + const [runOnImpressionTracked, onImpressionTracked, disposeOnImpressionTracked] = createAsyncHook(); + const [runOnViewableTracked, onViewableTracked, disposeOnViewableTracked] = createAsyncHook(); setup?.(slotContext, { onBeforeRender, @@ -171,6 +175,8 @@ export function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref { @@ -182,7 +188,9 @@ export function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref>[1]; + /** + * Hook that is called when the slots impressions tracker is fired. + */ + onImpressionTracked: ReturnType>[1]; + /** + * Hook that is called when the slots impressions tracker is fired. + */ + onViewableTracked: ReturnType>[1]; }; export type AdheseSlotOptions = { /** From 1048ae4953ffbb79bb54975a15cf0679186bb46d Mon Sep 17 00:00:00 2001 From: "AzureAD\\kevinvoortmans" Date: Thu, 23 Oct 2025 14:25:02 +0200 Subject: [PATCH 2/5] lint fixes --- apps/example/src/main.ts | 40 +++++++++++------------ packages/sdk/src/slot/slot.composables.ts | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/apps/example/src/main.ts b/apps/example/src/main.ts index b29612e6..e798c06a 100644 --- a/apps/example/src/main.ts +++ b/apps/example/src/main.ts @@ -8,22 +8,22 @@ const adhese = createAdhese({ initialSlots: [ { format: 'flex', - slot: "_1", + slot: '_1', containingElement: 'skyscraper', setup(context, hooks): void { hooks.onEmpty(() => { /* eslint-disable no-console */ console.log('triggering empty', context); }); - hooks.onImpressionTracked((ad)=> { - console.log("Impression Tracked fire for:", ad) - }) - hooks.onViewableTracked((ad)=> { - console.log("Viewable Impression tracked fire for:", ad) - }) - }, - width: "970px", - height: "250px" + hooks.onImpressionTracked((ad) => { + console.log('Impression Tracked fire for:', ad); + }); + hooks.onViewableTracked((ad) => { + console.log('Viewable Impression tracked fire for:', ad); + }); + }, + width: '970px', + height: '250px', }, ], location: 'stopandshop.com_website_home', @@ -36,19 +36,19 @@ window.adhese = adhese; adhese.addSlot({ format: 'flex', containingElement: 'leaderboard', - slot:"_2", + slot: '_2', renderMode: 'inline', setup(context, hooks): void { hooks.onEmpty(() => { console.log('triggering empty', context); }); - hooks.onImpressionTracked((ad)=> { - console.log("Impression Tracked fire for:", ad) - }) - hooks.onViewableTracked((ad)=> { - console.log("Viewable Impression tracked fire for:", ad) - }) - }, - width: "970px", - height: "250px" + hooks.onImpressionTracked((ad) => { + console.log('Impression Tracked fire for:', ad); + }); + hooks.onViewableTracked((ad) => { + console.log('Viewable Impression tracked fire for:', ad); + }); + }, + width: '970px', + height: '250px', }); diff --git a/packages/sdk/src/slot/slot.composables.ts b/packages/sdk/src/slot/slot.composables.ts index 989cbe59..e0e4cebd 100644 --- a/packages/sdk/src/slot/slot.composables.ts +++ b/packages/sdk/src/slot/slot.composables.ts @@ -176,7 +176,7 @@ export function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref { From be14f2bb4652d52f60bebd719f8056b37ffd44cb Mon Sep 17 00:00:00 2001 From: "AzureAD\\kevinvoortmans" Date: Thu, 23 Oct 2025 15:36:03 +0200 Subject: [PATCH 3/5] moved onImpressionTracked function in check + changed to minor changeset --- .changeset/nasty-lamps-eat.md | 2 +- packages/sdk/src/slot/slot.composables.ts | 8 ++++---- packages/sdk/src/slot/slot.ts | 2 +- packages/sdk/src/slot/slot.types.ts | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.changeset/nasty-lamps-eat.md b/.changeset/nasty-lamps-eat.md index f84784c4..bf705d8f 100644 --- a/.changeset/nasty-lamps-eat.md +++ b/.changeset/nasty-lamps-eat.md @@ -1,5 +1,5 @@ --- -"@adhese/sdk": patch +"@adhese/sdk": minor --- Added 2 new slot hooks: onImpressionTracked and onViewableTracked. Triggering when an impression and viewability tracker is being fired off. diff --git a/packages/sdk/src/slot/slot.composables.ts b/packages/sdk/src/slot/slot.composables.ts index e0e4cebd..5f0f7e7b 100644 --- a/packages/sdk/src/slot/slot.composables.ts +++ b/packages/sdk/src/slot/slot.composables.ts @@ -152,8 +152,8 @@ export function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref>[0]; runOnEmpty: ReturnType>[0]; runOnError: ReturnType>[0]; - runOnImpressionTracked: ReturnType>[0]; - runOnViewableTracked: ReturnType>[0]; + runOnImpressionTracked: ReturnType>[0]; + runOnViewableTracked: ReturnType>[0]; } & AdheseSlotHooks { const [runOnBeforeRender, onBeforeRender, disposeOnBeforeRender] = createAsyncHook(); const [runOnRender, onRender, disposeOnRender] = createPassiveHook(); @@ -163,8 +163,8 @@ export function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref(); - const [runOnImpressionTracked, onImpressionTracked, disposeOnImpressionTracked] = createAsyncHook(); - const [runOnViewableTracked, onViewableTracked, disposeOnViewableTracked] = createAsyncHook(); + const [runOnImpressionTracked, onImpressionTracked, disposeOnImpressionTracked] = createAsyncHook(); + const [runOnViewableTracked, onViewableTracked, disposeOnViewableTracked] = createAsyncHook(); setup?.(slotContext, { onBeforeRender, diff --git a/packages/sdk/src/slot/slot.ts b/packages/sdk/src/slot/slot.ts index 71cc69b9..0ab0207d 100644 --- a/packages/sdk/src/slot/slot.ts +++ b/packages/sdk/src/slot/slot.ts @@ -272,6 +272,7 @@ export function createSlot(slotOptions: AdheseSlotOptions): AdheseSlot { impressionTrackingPixelElement.value = addTrackingPixel( newData.impressionCounter, ); + runOnImpressionTracked(newData); isImpressionTracked.value = true; context.logger.debug( `Impression tracking pixel fired for ${slotContext.value?.name}`, @@ -289,7 +290,6 @@ export function createSlot(slotOptions: AdheseSlotOptions): AdheseSlot { `Additional Impression tracking pixel fired for ${slotContext.value?.name}`, ); } - runOnImpressionTracked(newData); } }, { immediate: true }, diff --git a/packages/sdk/src/slot/slot.types.ts b/packages/sdk/src/slot/slot.types.ts index bbc23318..a350a1c9 100644 --- a/packages/sdk/src/slot/slot.types.ts +++ b/packages/sdk/src/slot/slot.types.ts @@ -38,11 +38,11 @@ export type AdheseSlotHooks = { /** * Hook that is called when the slots impressions tracker is fired. */ - onImpressionTracked: ReturnType>[1]; + onImpressionTracked: ReturnType>[1]; /** * Hook that is called when the slots impressions tracker is fired. */ - onViewableTracked: ReturnType>[1]; + onViewableTracked: ReturnType>[1]; }; export type AdheseSlotOptions = { /** From 8aaeaa345d6cf3468e56aaf88f73afb5bb023ff8 Mon Sep 17 00:00:00 2001 From: "AzureAD\\kevinvoortmans" Date: Fri, 24 Oct 2025 08:39:44 +0200 Subject: [PATCH 4/5] chaning Hook mode from async to passive --- .changeset/fifty-roses-give.md | 5 +++++ packages/sdk/src/slot/slot.composables.ts | 8 ++++---- packages/sdk/src/slot/slot.types.ts | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .changeset/fifty-roses-give.md diff --git a/.changeset/fifty-roses-give.md b/.changeset/fifty-roses-give.md new file mode 100644 index 00000000..d3461274 --- /dev/null +++ b/.changeset/fifty-roses-give.md @@ -0,0 +1,5 @@ +--- +"@adhese/sdk": patch +--- + +Changing Tracked Hooks from Async to Passive. diff --git a/packages/sdk/src/slot/slot.composables.ts b/packages/sdk/src/slot/slot.composables.ts index 5f0f7e7b..391cbca4 100644 --- a/packages/sdk/src/slot/slot.composables.ts +++ b/packages/sdk/src/slot/slot.composables.ts @@ -152,8 +152,8 @@ export function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref>[0]; runOnEmpty: ReturnType>[0]; runOnError: ReturnType>[0]; - runOnImpressionTracked: ReturnType>[0]; - runOnViewableTracked: ReturnType>[0]; + runOnImpressionTracked: ReturnType>[0]; + runOnViewableTracked: ReturnType>[0]; } & AdheseSlotHooks { const [runOnBeforeRender, onBeforeRender, disposeOnBeforeRender] = createAsyncHook(); const [runOnRender, onRender, disposeOnRender] = createPassiveHook(); @@ -163,8 +163,8 @@ export function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref(); - const [runOnImpressionTracked, onImpressionTracked, disposeOnImpressionTracked] = createAsyncHook(); - const [runOnViewableTracked, onViewableTracked, disposeOnViewableTracked] = createAsyncHook(); + const [runOnImpressionTracked, onImpressionTracked, disposeOnImpressionTracked] = createPassiveHook(); + const [runOnViewableTracked, onViewableTracked, disposeOnViewableTracked] = createPassiveHook(); setup?.(slotContext, { onBeforeRender, diff --git a/packages/sdk/src/slot/slot.types.ts b/packages/sdk/src/slot/slot.types.ts index a350a1c9..37ecef50 100644 --- a/packages/sdk/src/slot/slot.types.ts +++ b/packages/sdk/src/slot/slot.types.ts @@ -38,11 +38,11 @@ export type AdheseSlotHooks = { /** * Hook that is called when the slots impressions tracker is fired. */ - onImpressionTracked: ReturnType>[1]; + onImpressionTracked: ReturnType>[1]; /** * Hook that is called when the slots impressions tracker is fired. */ - onViewableTracked: ReturnType>[1]; + onViewableTracked: ReturnType>[1]; }; export type AdheseSlotOptions = { /** From ff170c8a2110ba0f8ed7e238d68c5989ae13bedf Mon Sep 17 00:00:00 2001 From: "AzureAD\\kevinvoortmans" Date: Fri, 24 Oct 2025 10:04:09 +0200 Subject: [PATCH 5/5] fix eager rendering triggering twice bug --- .changeset/nasty-lamps-eat.md | 5 ----- packages/sdk/src/slot/slot.ts | 31 ++++++++++++++++--------------- 2 files changed, 16 insertions(+), 20 deletions(-) delete mode 100644 .changeset/nasty-lamps-eat.md diff --git a/.changeset/nasty-lamps-eat.md b/.changeset/nasty-lamps-eat.md deleted file mode 100644 index bf705d8f..00000000 --- a/.changeset/nasty-lamps-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@adhese/sdk": minor ---- - -Added 2 new slot hooks: onImpressionTracked and onViewableTracked. Triggering when an impression and viewability tracker is being fired off. diff --git a/packages/sdk/src/slot/slot.ts b/packages/sdk/src/slot/slot.ts index 0ab0207d..b22db4bb 100644 --- a/packages/sdk/src/slot/slot.ts +++ b/packages/sdk/src/slot/slot.ts @@ -201,21 +201,22 @@ export function createSlot(slotOptions: AdheseSlotOptions): AdheseSlot { { immediate: true, deep: true }, ); - const isInViewport = useRenderIntersectionObserver({ - options, - element, - hooks, - }); - - watch( - isInViewport, - async (newIsInViewport) => { - if (newIsInViewport && status.value !== 'rendered') - await slotContext.value?.render(); - }, - { immediate: true }, - ); - + if (!context.options.eagerRendering){ + const isInViewport = useRenderIntersectionObserver({ + options, + element, + hooks, + }); + + watch( + isInViewport, + async (newIsInViewport) => { + if (newIsInViewport && status.value !== 'rendered') + await slotContext.value?.render(); + }, + { immediate: true }, + ); + } hooks.onDispose(() => { disposeQueryDetector(); });