@@ -35,6 +35,7 @@ export type AdVariant = 'banner' | 'choice'
3535 * same normalized response shape, so the rest of the hook is provider-agnostic.
3636 */
3737export type AdProvider = 'gravity' | 'carbon'
38+ export type AdSurface = 'waiting_room'
3839
3940export type AdData =
4041 | { variant : 'banner' ; ad : AdResponse }
@@ -112,11 +113,14 @@ export const useGravityAd = (options?: {
112113 provider ?: AdProvider
113114 /** Backup ad network to try when the primary returns no fill or errors. */
114115 fallbackProvider ?: AdProvider
116+ /** Product surface requesting the ad. The server maps this to placements. */
117+ surface ?: AdSurface
115118} ) : GravityAdState => {
116119 const enabled = options ?. enabled ?? true
117120 const forceStart = options ?. forceStart ?? false
118121 const provider : AdProvider = options ?. provider ?? 'gravity'
119122 const fallbackProvider = options ?. fallbackProvider
123+ const surface = options ?. surface
120124 const [ ad , setAd ] = useState < AdResponse | null > ( null )
121125 const [ adData , setAdData ] = useState < AdData | null > ( null )
122126 const [ isLoading , setIsLoading ] = useState ( false )
@@ -299,6 +303,7 @@ export const useGravityAd = (options?: {
299303 messages : adMessages ,
300304 sessionId : useChatStore . getState ( ) . chatSessionId ,
301305 device : getDeviceInfo ( ) ,
306+ ...( surface ? { surface } : { } ) ,
302307 // Carbon requires a real browser-ish useragent for targeting/fraud
303308 // detection. Gravity ignores it. We source one centrally so every
304309 // provider that needs it sees the same value.
@@ -430,7 +435,7 @@ export const useGravityAd = (options?: {
430435 clearInterval ( id )
431436 ctrlRef . current . intervalId = null
432437 }
433- } , [ shouldStart , shouldHideAds , provider , fallbackProvider ] )
438+ } , [ shouldStart , shouldHideAds , provider , fallbackProvider , surface ] )
434439
435440 // Don't return ad when ads should be hidden
436441 const visible = shouldStart && ! shouldHideAds
0 commit comments