Skip to main content

Implementing Dynamic Zones

Dynamic zones are available through the React Components, React Hooks, and Web Components workflows — there is no Headless equivalent.

SurfsideDynamicZone renders whichever creative type wins a dynamic zone auction — banner, video, or carousel — without you needing to decide in advance.

import { SurfsideDynamicZone } from '@surfside/ads-react';

<SurfsideDynamicZone
zoneId="your-zone-id"
carousel={{
cardMinWidth: 200,
carouselLimits: { type: 'infinite' },
nextType: 'page'
}}
/>

Requires a SurfsideProvider2 ancestor.

What a dynamic zone is​

A dynamic zone is a single zone ID configured in the Surfside platform to request multiple creative types in one bid request — for example, a 4×1 banner, an 8×1 banner, and a product card carousel — and fill whichever has demand. If no 4×1 banners are available, the bidder might fill with an 8×1 instead. If there are no banners at all, it might fall back to a carousel.

The creative types to try, their priority, and their fallback order are all configured in the Surfside platform against the zone ID. You need the correct dynamic zone ID from the platform to use this component — a standard zone ID will not work.

Props​

PropTypeRequiredDescription
zoneIdstringYesThe dynamic zone ID from the Surfside platform
carouselISurfsideCarouselRenderPropsNoFrontend rendering options applied when the zone fills with a carousel
categorystring[]NoCategory targeting hints passed to the bidder
enabledbooleanNoWhen false, the component renders nothing. Default true
onError(error: ErrResult) => voidNoCalled when the zone fails to fill or an error occurs

When a dynamic zone fills with a carousel, some of the carousel's behavior is configured in the Surfside platform — for example, what kind of recommender to use. However, frontend layout details like card sizing and scroll behavior are not something the backend can know about, so they have to be passed from your application.

If the zone returns a carousel and you do not provide carousel, the component falls back to the defaults used by the library. Pass carousel to override them:

<SurfsideDynamicZone
zoneId="your-zone-id"
carousel={{
cardMinWidth: 200,
carouselLimits: { type: 'limited', limit: 6 },
nextType: 'product'
}}
/>

ISurfsideCarouselRenderProps​

FieldTypeDescription
cardMinWidthnumberMinimum pixel width of each product card
carouselLimits{ type: 'infinite' } | { type: 'limited', limit: number }Whether the carousel loads more products as the user scrolls, or shows a fixed number
nextType'page' | 'product'Controls how the next set of products is fetched — by page or by individual product

Category targeting​

Pass category to narrow which ads are eligible for the placement:

<SurfsideDynamicZone
zoneId="your-zone-id"
carousel={{ cardMinWidth: 200, carouselLimits: { type: 'infinite' }, nextType: 'page' }}
category={['edibles']}
/>

Error handling​

Use onError to react when the zone fails to fill:

<SurfsideDynamicZone
zoneId="your-zone-id"
carousel={{ cardMinWidth: 200, carouselLimits: { type: 'infinite' }, nextType: 'page' }}
onError={(err) => console.warn('Dynamic zone did not fill', err.error)}
/>