Web SDK Ad Customization
activeOn the SDK-rendering path (Render Display Ads with the Web SDK) the Web SDK fetches, renders, and tracks every Display Ads slot you place. This page is the reference for changing how those ads look, without giving up the fetching and tracking the SDK does for you.
It does not apply to Sponsored Ads, which the SDK does not render — you own that markup entirely.
There are three levers, in increasing order of control:
| Goal | Use |
|---|---|
| Recolor, resize, round, or reposition the existing markup | CSS classes — your own stylesheet |
| Toggle behavior the SDK already supports (closable, sticky, slider, grid columns…) | Display options — configured on the Binoban platform |
| Change the markup itself: reorder, omit, wrap, or render through your own code | Custom creative templates |
None of them changes behavior. Which creative shows, impression and click tracking, and slider mechanics stay owned by the SDK in all three cases.
CSS classes
The SDK renders every ad into your <div data-bob-id="…"> slot using predictable,
BEM-style class names. They are a stable contract — target them from your own CSS.
The SDK also injects a small base stylesheet into a <style id="bob-ads-display-styles">
element in <head>. Your own rules override it with ordinary specificity: load your
stylesheet after it, or use a slightly more specific selector.
Slot lifecycle
The SDK toggles state classes on your slot element as it renders:
| Class | Meaning |
|---|---|
bob-ads--loaded | A creative has been rendered into this slot. |
bob-ads--failed | No ad was available. The slot is also set aria-hidden="true" and hidden with display:none. |
Container and creative
| Class | Element |
|---|---|
bob-ads-container | The wrapper the SDK renders inside your slot. |
bob-ads-container--{type} | Type modifier — bob-ads-container--banners or bob-ads-container--native. |
bob-ads-container--{type}-{template} | Type and template modifier (e.g. bob-ads-container--native-native_slider). |
bob-ads-container--scaleup | Present when the scaleUp display option is on (the creative stretches to fill). |
bob-ads-container__close | The built-in close button, shown when the slot is closable. |
bob-ads-creative | The clickable creative anchor (<a>). Wraps every creative, built-in or custom. |
bob-ads-creative__image | The <img> inside a banner creative. |
bob-ads-banner | A banner creative anchor. |
Native creative
| Class | Element |
|---|---|
bob-ads-native | A native creative anchor. |
bob-ads-native--{template} | Template modifier (e.g. bob-ads-native--native_text). |
bob-ads-native__image | The native image wrapper (the <img> is inside). |
bob-ads-native__title | The native title. |
bob-ads-native__cta | The native call-to-action (wraps a <button>). |
Slider (carousel) layouts
| Class | Element |
|---|---|
bob-ads-slider | The slider root. |
bob-ads-slider__container | The track holding the slides. |
bob-ads-slider__slide | A single slide. |
bob-ads-slider__button | A previous/next arrow button. |
bob-ads-slider__button--prev / bob-ads-slider__button--next | Arrow direction modifiers. |
bob-ads-slider__button__svg | The arrow icon. |
bob-ads-slider__dots | The pagination-dots container. |
bob-ads-slider__dot | A single pagination dot. |
bob-ads-slider__dot--selected | The active dot. |
Sticky placement
| Class | Element |
|---|---|
bob-ads-sticky-position | A slot pinned to the viewport (fixed position). |
bob-ads-sticky-position__{position} | Placement modifier — top, right, left, bottom, top_right, top_left, bottom_right, bottom_left. |
Example
/* Round every creative and give native cards a subtle border */
.bob-ads-creative {
border-radius: 12px;
overflow: hidden;
}
.bob-ads-native {
border: 1px solid #eee;
}
/* Recolor the slider's active dot */
.bob-ads-slider__dot--selected:after {
box-shadow: inset 0 0 0 0.2rem #263d69;
}
Display options
Each ad slot can carry a set of display options. These are configured on the Binoban platform, per inventory and ad slot, and delivered with the ad response — you do not set them from the SDK. They are documented here so you know what behavior to expect and what the SDK will render.
General
| Option | Type | Effect |
|---|---|---|
closable | boolean | Shows a close button. Closing hides the slot and emits a close event. |
samePage | boolean | Opens the ad's destination in the same tab (_self) instead of a new tab (_blank). |
borderRadius | string | CSS radius applied to the creative (e.g. "8px"), with overflow clipped. |
rotate | boolean | Rotates which creative shows across page views when a slot has several. |
fillWithRepeat | boolean | Repeats creatives to fill the slot when there are more cells than creatives. |
scaleUp | boolean | Stretches the creative to fill its container (adds bob-ads-container--scaleup). |
Card
| Option | Type | Effect |
|---|---|---|
card.cardBg | string | Background color of the native card. |
card.ctaBg | string | Background color of the native CTA button. |
Slider
| Option | Type | Effect |
|---|---|---|
slider.hideArrows | boolean | Hides the previous/next arrows. |
slider.hideDots | boolean | Hides the pagination dots. |
slider.disableAutoStart | boolean | Disables autoplay. |
slider.isLtr | boolean | Sets slide direction to left-to-right. The default is right-to-left. |
slider.size | number | Slide width as a percentage of the track (e.g. 50 for two per view). |
slider.spacing | number | Gap between slides, in pixels. |
Grid
| Option | Type | Effect |
|---|---|---|
grid.maxColumns | number | Maximum columns for the native grid layout. Defaults to 3. |
Sticky
| Option | Type | Effect |
|---|---|---|
sticky.position | enum | Where the slot pins: TOP, RIGHT, LEFT, BOTTOM, TOP_RIGHT, TOP_LEFT, BOTTOM_RIGHT, BOTTOM_LEFT. |
sticky.transformX | string | Horizontal offset (CSS translate X, e.g. "10px"). |
sticky.transformY | string | Vertical offset (CSS translate Y). |
sticky.boxBg | string | Background color of the sticky box. |
sticky.boxShadow | string | Box-shadow of the sticky box. |
Custom creative templates
When CSS on the fixed structure is not enough — you need to reorder elements, add a badge, omit something, wrap the creative in your own card, or render it through your own code — supply a custom creative template. The SDK still fetches the ads, manages the layout (slider, sticky, grid), and reports every event.
This is creative-level customization: you template one ad item, and the SDK places your markup into each cell of the layout the campaign selected.
Two ways to author a template
1. Declarative <template> (no JavaScript)
Place a <template data-bob-template> inside the ad slot. The SDK clones it for each
creative, fills in the ad data, and wires up the events.
<div data-bob-id="hero-slot">
<template data-bob-template>
<article class="promo">
<span class="promo__badge">Sponsored</span>
<img data-bob-src="image" alt="" />
<h3 data-bob-text="title"></h3>
<p class="promo__cta" data-bob-text="cta" data-bob-if="cta"></p>
<button data-bob-action="close" aria-label="Close">×</button>
</article>
</template>
</div>
Reuse one template across many slots by giving it an id and pointing slots at it:
<template id="promo-card">
<article class="promo">
<img data-bob-src="image" alt="" />
<h3 data-bob-text="title"></h3>
</article>
</template>
<div data-bob-id="rail-1" data-bob-template="promo-card"></div>
<div data-bob-id="rail-2" data-bob-template="promo-card"></div>
2. JavaScript render callback
Register renderers through the adTemplates option when you load the SDK. This is the
recommended programmatic path: your renderers are registered before the SDK loads its
first ads, so there is no flicker.
Binoban.load({
credentials: {
apiKey: "PROJECT_API_KEY",
sourceIdentifier: "PROJECT_SOURCE_IDENTIFIER",
},
host: {
rtbPath: "YOUR_BINOBAN_SERVER_RTB_URL",
sdkPath: "YOUR_BINOBAN_SERVER_SDK_URL",
apiPath: "YOUR_BINOBAN_SERVER_API_URL",
},
adTemplates: {
// Named renderers, referenced by data-bob-template="promo-card"
renderers: {
"promo-card": (ad, api) => {
const el = document.createElement("article");
el.className = "promo";
el.innerHTML = `<img src="${ad.image}" alt=""><h3>${ad.title}</h3>`;
return el; // return an HTMLElement or an HTML string
},
},
// Or a blanket fallback per creative type:
defaults: {
native: (ad, api) => {
/* build and return your node */
},
banner: (ad, api) => {
/* … */
},
},
},
});
adTemplates and not ads?The ads option is already used for RTB host and click configuration, so custom templates
live under adTemplates.
Binding attributes
Inside a <template>, these data-bob- attributes tell the SDK where to put the ad data.
The SDK writes text and attribute values only — it never injects markup from ad data — so
your template is safe from content-driven injection.
| Attribute | What it does |
|---|---|
data-bob-text="field" | Sets the element's text to ad.field. |
data-bob-src="field" | Sets an image's src to ad.field. |
data-bob-attr:NAME="field" | Sets attribute NAME to ad.field (e.g. data-bob-attr:alt="title"). |
data-bob-if="field" | Removes the element when ad.field is empty. |
data-bob-action="close" | Marks your close button. Honored only when the slot is closable. |
There is no click marker — the whole creative is the link. The SDK wraps your markup in
an <a class="bob-ads-creative"> and handles navigation and click tracking itself.
Ad data fields
Templates and renderers bind to this curated, read-only field set. Internal fields such as bid and campaign identifiers are deliberately not exposed.
| Ad type | Fields |
|---|---|
| Native | image, title, cta, landingUrl, logo, icon |
| Banner | image, targetUrl, width, height |
A JavaScript renderer also receives an api:
interface CreativeRenderApi {
// Wire an element as the close trigger (no-op unless the slot is closable).
bindClose(el: Element): void;
// The resolved display options for this slot (read-only).
ui?: AdsInventoryUi;
}
Which template applies
For each creative, the first match wins:
- an inline
<template data-bob-template>inside the slot element; data-bob-template="name"on the slot — matching a document<template id="name">, or a registeredrenderers["name"]. A matching document template wins over a same-named renderer.- a per-type default renderer (
adTemplates.defaults.banner/.native); - otherwise, the SDK's built-in rendering.
What the SDK still owns
A template changes structure, never behavior:
- Click — the creative is an SDK
<a>reusing the standard click handling: a 500 ms flush delay before navigation,_selfor_blankfrom thesamePagedisplay option, andrel="nofollow noopener". - Impression — fired once, when the creative first enters the viewport.
- Close — wired to your
data-bob-action="close"element, and only when the slot is closable. It hides the slot and emits the close event.
Fallback and safety
Any failure — missing template content, a renderer that throws, or a binder error — falls back to the built-in renderer for that creative. A slot is never left empty because of a bad template. Turn on debug mode to see why a template was skipped.
Ad data is advertiser-controlled, so the binder also hardens attribute bindings:
data-bob-attr:NAMEnever sets an event-handler attribute. AnyNAMEstarting withon(e.g.onclick) is stripped outright.- On URL-bearing attributes (
href,src,xlink:href,formaction,action,poster,background,cite— including viadata-bob-src), ajavascript:,vbscript:, ordata:text/htmlvalue is neutralized to an empty string instead of being written. Ordinary URLs pass through unchanged.
Non-URL, non-handler attributes are unaffected.
If a slot is closable and resolves to a custom template, your creative replaces the SDK's
built-in close button. Include a data-bob-action="close" element in your template, or the
slot has no close control.
Limitations
Slider layouts render a single, collection-level close button. If a JavaScript renderer succeeds for some slides but fails for others — falling back to the built-in creative for those — the shared close button is suppressed. Declarative templates are deterministic per slide, so this affects only renderer functions with per-item failures.
Related
- Render Display Ads with the Web SDK — how to place a slot and what the SDK does automatically.
- Web SDK Reference — the full method and configuration surface.
- Track ad impressions and clicks — the events the SDK emits for every creative.
- Ad slots & formats — the slot types and templates these options apply to.