@@ -25,6 +25,14 @@ import { installGptGuard } from './script_guard';
2525 */
2626
2727const TS_INITIAL_TARGETING_KEY = 'ts_initial' as const ;
28+ const TS_BID_TARGETING_KEYS = [
29+ 'hb_pb' ,
30+ 'hb_bidder' ,
31+ 'hb_adid' ,
32+ 'hb_cache_host' ,
33+ 'hb_cache_path' ,
34+ ] as const ;
35+ const TS_BASE_TARGETING_KEYS = [ ...TS_BID_TARGETING_KEYS , TS_INITIAL_TARGETING_KEY ] as const ;
2836
2937// ------------------------------------------------------------------
3038// googletag type stubs (minimal surface needed by the shim)
@@ -34,6 +42,7 @@ interface GoogleTagSlot {
3442 getAdUnitPath ( ) : string ;
3543 getSlotElementId ( ) : string ;
3644 setTargeting ( key : string , value : string | string [ ] ) : GoogleTagSlot ;
45+ clearTargeting ?( key ?: string ) : GoogleTagSlot ;
3746 addService ( service : GoogleTagPubAdsService ) : GoogleTagSlot ;
3847 getTargeting ?( key : string ) : string [ ] ;
3948}
@@ -82,6 +91,14 @@ function messageSourceBelongsToConfiguredSlot(source: MessageEventSource | null)
8291 ) ;
8392}
8493
94+ function clearTargetingKeys ( slot : GoogleTagSlot , keys : Iterable < string > ) : void {
95+ if ( typeof slot . clearTargeting !== 'function' ) return ;
96+
97+ for ( const key of new Set ( keys ) ) {
98+ slot . clearTargeting ( key ) ;
99+ }
100+ }
101+
85102interface GoogleTagPubAdsService {
86103 setTargeting ( key : string , value : string | string [ ] ) : GoogleTagPubAdsService ;
87104 getTargeting ( key : string ) : string [ ] ;
@@ -333,6 +350,8 @@ export function installTsAdInit(): void {
333350 // All slots to refresh (TS-defined + publisher-owned reused).
334351 const slotsToRefresh : GoogleTagSlot [ ] = [ ] ;
335352 const divToSlotId : Record < string , string > = { } ;
353+ const prevSlotTargetingKeys = ts . prevSlotTargetingKeys ?? { } ;
354+ const nextSlotTargetingKeys : Record < string , string [ ] > = { } ;
336355
337356 slots . forEach ( ( slot ) => {
338357 // Resolve actual div ID: exact match first, then prefix query.
@@ -363,19 +382,26 @@ export function installTsAdInit(): void {
363382 tsOwned = true ;
364383 }
365384
385+ const slotDivId2 = gptSlot . getSlotElementId ?.( ) ?? actualDivId ;
386+ clearTargetingKeys ( gptSlot , [
387+ ...TS_BASE_TARGETING_KEYS ,
388+ ...( prevSlotTargetingKeys [ actualDivId ] ?? [ ] ) ,
389+ ...( prevSlotTargetingKeys [ slotDivId2 ] ?? [ ] ) ,
390+ ] ) ;
391+
366392 Object . entries ( slot . targeting ?? { } ) . forEach ( ( [ k , v ] ) => gptSlot . setTargeting ( k , v ) ) ;
367- ( [ 'hb_pb' , 'hb_bidder' , 'hb_adid' , 'hb_cache_host' , 'hb_cache_path' ] as const ) . forEach (
368- ( key ) => {
369- if ( bid [ key ] ) gptSlot . setTargeting ( key , String ( bid [ key ] ! ) ) ;
370- }
371- ) ;
393+ TS_BID_TARGETING_KEYS . forEach ( ( key ) => {
394+ if ( bid [ key ] ) gptSlot . setTargeting ( key , String ( bid [ key ] ! ) ) ;
395+ } ) ;
372396 gptSlot . setTargeting ( TS_INITIAL_TARGETING_KEY , '1' ) ;
373397 // Map both inner div and container div → slot ID so slotRenderEnded
374398 // (which reports the GPT slot's div, i.e. slotDivId/container) can look up
375399 // the slot, while adm injection (which targets the inner div) also works.
376400 divToSlotId [ actualDivId ] = slot . id ;
377- const slotDivId2 = gptSlot . getSlotElementId ?.( ) ?? actualDivId ;
378401 if ( slotDivId2 !== actualDivId ) divToSlotId [ slotDivId2 ] = slot . id ;
402+ const slotTargetingKeys = Object . keys ( slot . targeting ?? { } ) ;
403+ nextSlotTargetingKeys [ actualDivId ] = slotTargetingKeys ;
404+ if ( slotDivId2 !== actualDivId ) nextSlotTargetingKeys [ slotDivId2 ] = slotTargetingKeys ;
379405 if ( tsOwned ) newSlots . push ( gptSlot ) ;
380406 slotsToRefresh . push ( gptSlot ) ;
381407
@@ -391,6 +417,7 @@ export function installTsAdInit(): void {
391417 ts . prevGptSlots = newSlots as unknown [ ] ;
392418 // Replace (not merge) so destroyed slots from previous navigation don't linger.
393419 ts . divToSlotId = divToSlotId ;
420+ ts . prevSlotTargetingKeys = nextSlotTargetingKeys ;
394421
395422 // enableSingleRequest and enableServices must only be called once per page load.
396423 if ( ! ts . servicesEnabled ) {
0 commit comments