Render merchandising banners with the Layers SDK by reading data.banners from the collection controller. Hero rows and inline tiles overtake or inject products.
This guide is the SDK equivalent of Rendering banners in Liquid. The browse payload, layout selection, and grid math are identical. With @commerce-blocks/sdk, sdk.collection() makes the HTTP call, deduplicates requests, caches the response, and exposes data.banners on reactive state you can subscribe to.Use this version when you have already installed @commerce-blocks/sdk in your theme. For a no-dependencies version, see the Liquid + Fetch guide.Hero banners are horizontal banners spanning the entire product grid above the first product row. They are not restricted to inline tile sizes. Inline banners can span one or more columns, bounded by the grid rather than a fixed 1×1 or 2×2 preset. Inline sizes are grid-cell spans, not image dimensions in pixels. The editor can resize inline banners across columns and up to four rows.
Banners ship as a top-level, pre-sorted array on the collection controller’s data:
data.banners// → Array<{// id: string,// rule_id: string | null, // ID of the merchandising rule that produced the banner// name: string,// mode: 'overtake' | 'inject',// link: string | null,// type: string, // 'link' for the built-in type, or your custom type's slug// data: Record<string, unknown>,// values for that type's field schema// sort_index: number,// web_media: { id, src, alt, width, height, source, mediaContentType },// mobile_media: { id, src, alt, width, height, source, mediaContentType },// web_layout: { placement: 'hero' | 'inline', width, height, position },// mobile_layout:{ placement: 'hero' | 'inline', width, height, position },// }>
Each banner carries the rule_id of the merchandising rule that produced it. data._meta.appliedRules (a flat array of rule ID strings) still lists every applied rule.Four parts of the banner payload matter for rendering:
Per-device media and layout. Pick web_* on desktop and mobile_* on mobile. They’re independent. A hero on web can be an inline tile on mobile.
Mode.overtake replaces the product card at position. inject inserts the banner and shifts trailing products by one cell.
Link. On the built-in link type, only inject banners can carry a top-level link. Wrap them in an anchor. Render overtake banners as plain media. Custom banner types put their click-through URL inside data instead.
Type and data.type is the banner type slug: 'link' for the built-in type, or the slug of one of your custom types. data carries the values of that type’s field schema. Switch renderers on type and read fields out of data.
The SDK dedupes identical requests and caches responses in memory for the life of the page. It re-runs the subscriber whenever you call get() with new filter or pagination args.
Listen for mql.addEventListener('change', ...) and re-render when the breakpoint flips. Banners can have completely different layouts per device. A 2×2 web tile may be a hero on mobile.
Hero banners render across the full grid width above the products. Ignore their inline width and height cell spans; your theme controls the hero’s height and image cropping. Inline banners slot into the product grid by position (row-major, 0-indexed). overtake replaces the product at that index; inject splices the banner in and shifts trailing products. The response is already sorted by sort_index, so no extra sort is needed.
Use grid-column: span <width>; grid-row: span <height> (or the --span-x / --span-y properties) on banner cells so 2×2 tiles actually cover four grid cells.
Reuse the same collection controller and subscriber, and call get() with new args. Layers recomputes the banner payload on every request, so banners are always in sync with the current filter set.
The rendering steps on this page work unchanged for the built-in Link type. If you’ve defined custom banner types, each banner also carries a type slug and a data object with the type’s saved field values. Switch renderers on type and read fields out of data. The envelope (media, layout, mode) is the same across all types.
type PickedBanner = ReturnType<typeof layoutForDevice>function layoutForDevice(banner) { const media = isMobile() ? banner.mobile_media : banner.web_media const layout = isMobile() ? banner.mobile_layout : banner.web_layout if (!media?.src || !layout) return null return { media, layout, mode: banner.mode, link: banner.link, type: banner.type, data: banner.data ?? {}, id: banner.id, }}function renderBannerBody(picked: NonNullable<PickedBanner>) { const { type, data } = picked switch (type) { case 'link': return `<img src="${picked.media.src}" alt="${picked.media.alt ?? ''}" />` case 'countdown_promo': return ` <img src="${picked.media.src}" alt="${picked.media.alt ?? ''}" /> <h3>${escapeHtml(String(data.headline ?? ''))}</h3> <time datetime="${data.end_at}">${escapeHtml(String(data.cta_label ?? 'Shop the drop'))}</time> ` case 'spotlight_product': // product_reference fields arrive pre-resolved to { id, handle }. return ` <a href="/products/${data.spotlight_product?.handle ?? ''}"> <img src="${picked.media.src}" alt="${picked.media.alt ?? ''}" /> <span>${escapeHtml(String(data.overlay_label ?? ''))}</span> </a> ` default: // Unknown type - fall back to the media so a newly-added type still renders. return `<img src="${picked.media.src}" alt="${picked.media.alt ?? ''}" />` }}
Reference fields (product_reference, collection_reference, variant_reference) arrive pre-resolved to { id, handle }. Unpublished references are dropped from the payload, so you don’t need to guard against dead handles. Retyped or removed fields on the banner type are dropped too. Treat any field on data as optional and fall back cleanly.
The Layers theme app extension does not render banners. Your theme owns that. The embed does handle:
Authenticating the browse request (token, cart context, identity).
Sending the storefront pixel events that track shopper engagement on the underlying grid.
The storefront pixel also tracks banner_impression and banner_click events automatically for any rendered element whose data-banner-id matches a banner id from the Layers response, as in the examples above. Keep that attribute on your banner markup so these events fire.
data.banners is empty. No merchandising rule matched the request, or every matching rule had no enabled banners. Confirm at least one active rule on this collection has banners attached and both media slots filled.Banners only appear on first load, not after filtering. Your subscriber probably re-renders products but not banners. Re-read data.banners from the same payload on every state update. They ship together.Inline banner is at the wrong cell.position is row-major and 0-indexed. Verify the device’s *_layout.position matches the cell index you expect after flattening the grid to a single array.2×2 inline tile renders as a 1×1. Your CSS isn’t honoring width/height. Apply grid-column: span <width>; grid-row: span <height> on banner cells.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Layers","colors":{"primary":"#607FFD","light":"#AFC0FF","dark":"#3A57E8"},"logo":{"light":"https://mintcdn.com/protoninc/PNs-gxGUVcdBDEEC/logo.svg?fit=max\u0026auto=format\u0026n=PNs-gxGUVcdBDEEC\u0026q=85\u0026s=989e3194cb32f07e7018b8b7186b9007","dark":"https://mintcdn.com/protoninc/PNs-gxGUVcdBDEEC/logo.svg?fit=max\u0026auto=format\u0026n=PNs-gxGUVcdBDEEC\u0026q=85\u0026s=989e3194cb32f07e7018b8b7186b9007","href":"https://www.uselayers.com/?utm_source=docs\u0026utm_medium=referral\u0026utm_campaign=docs-to-site"},"favicon":"https://mintcdn.com/protoninc/qubyNEZK4oJTl9By/favicon.svg?fit=max\u0026auto=format\u0026n=qubyNEZK4oJTl9By\u0026q=85\u0026s=3611d60346e12f15e4684bc60cb69ece","api":{"mdx":{"server":"https://app.uselayers.com/api/storefront/v1"}},"navbar":{"links":[{"href":"https://www.uselayers.com/changelog?utm_source=docs\u0026utm_medium=referral\u0026utm_campaign=docs-to-site","label":"Changelog"},{"href":"mailto:support@uselayers.com","label":"Support"},{"href":"https://app.uselayers.com/dashboard?utm_source=docs\u0026utm_medium=referral\u0026utm_campaign=docs-to-dashboard","label":"Dashboard"}],"primary":{"type":"button","label":"Request Demo","href":"https://www.uselayers.com/demo?utm_source=docs\u0026utm_medium=referral\u0026utm_campaign=docs-to-site"}},"footer":{"socials":{"linkedin":"https://www.linkedin.com/company/uselayers"},"links":[{"header":"Legal","items":[{"label":"Privacy Statement","href":"https://docs.uselayers.com/legal/privacy-statement"},{"label":"Terms of Use","href":"https://docs.uselayers.com/legal/terms-of-use"}]}]},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"styling":{"latex":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"protoninc","hasAudioNarration":false,"actualSubdomain":"protoninc","customDomains":["docs.uselayers.com"],"gitSource":{"type":"github","owner":"protonagency","repo":"layers-docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"feedback":{"thumbs":true,"edits":false,"issues":false,"agentFeedback":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"REMOVE_BRANDING":{"status":"ENABLED"}},"buildId":"6af348591e35380993b05ecf","clientVersion":"0.0.4102","searchFilterCounts":[{"language":"default","tag":"Documentation","count":103},{"language":"default","tag":"Help Center","count":90},{"language":"default","tag":"Merchandising","count":57},{"language":"default","tag":"Developers","count":42},{"language":"default","tag":"API Reference","count":25},{"language":"default","tag":"SDK","count":20},{"language":"default","tag":"Sort Orders","count":18},{"language":"default","tag":"Configuration","count":15},{"language":"default","tag":"Liquid","count":14},{"language":"default","tag":"Search \u0026 Discovery","count":14}]},"assistantConfig":{"enableAskAiButton":true,"enableAskAiSearchBar":false,"deflection":{"enabled":true,"email":"support@uselayers.com","showHelpButton":true}},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"developers/rendering-banners-with-the-sdk","slug":"/developers/rendering-banners-with-the-sdk","pageMetadata":{"title":"Rendering banners with the SDK","description":"Render merchandising banners with the Layers SDK by reading data.banners from the collection controller. Hero rows and inline tiles overtake or inject products.","href":"/developers/rendering-banners-with-the-sdk"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Render merchandising banners with the Layers SDK by reading data.banners from the collection controller. Hero rows and inline tiles overtake or inject products.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Tip}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tip)_missingMdxReference(`Tip`,true);return _jsxs(_Fragment,{children:[_jsx(Heading,{level:`2`,id:`overview`,children:`Overview`}),`\n`,_jsxs(_components.p,{children:[`This guide is the SDK equivalent of `,_jsx(_components.a,{href:`/developers/rendering-banners-in-liquid`,children:`Rendering banners in Liquid`}),`. The browse payload, layout selection, and grid math are identical. With `,_jsx(_components.code,{children:`@commerce-blocks/sdk`}),`, `,_jsx(_components.code,{children:`sdk.collection()`}),` makes the HTTP call, deduplicates requests, caches the response, and exposes `,_jsx(_components.code,{children:`data.banners`}),` on reactive state you can subscribe to.`]}),`\n`,_jsxs(_components.p,{children:[`Use this version when you have already installed `,_jsx(_components.a,{href:`/sdk/installation`,children:_jsx(_components.code,{children:`@commerce-blocks/sdk`})}),` in your theme. For a no-dependencies version, see the `,_jsx(_components.a,{href:`/developers/rendering-banners-in-liquid`,children:`Liquid + Fetch guide`}),`.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Hero banners`}),` are horizontal banners spanning the entire product grid above the first product row. They are not restricted to inline tile sizes. `,_jsx(_components.strong,{children:`Inline banners`}),` can span one or more columns, bounded by the grid rather than a fixed 1×1 or 2×2 preset. Inline sizes are grid-cell spans, not image dimensions in pixels. The editor can resize inline banners across columns and up to four rows.`]}),`\n`,_jsx(Heading,{level:`2`,id:`prerequisites`,children:`Prerequisites`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`The Layers Shopify app installed and the theme app extension enabled in `,_jsx(_components.strong,{children:`Online Store → Themes → Customize → App embeds`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`The SDK installed and initialized in your theme. See `,_jsx(_components.a,{href:`/sdk/installation`,children:`SDK installation`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`At least one merchandising rule with banners attached. See `,_jsx(_components.a,{href:`/help/merchandising/add-banner-to-rule`,children:`Add a banner to a rule`}),`.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`the-banner-payload`,children:`The banner payload`}),`\n`,_jsxs(_components.p,{children:[`Banners ship as a top-level, pre-sorted array on the collection controller’s `,_jsx(_components.code,{children:`data`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`15`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`15`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`data.banners`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// → Array\u003c{`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// id: string,`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// rule_id: string | null,`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // ID of the merchandising rule that produced the banner`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// name: string,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// mode: 'overtake' | 'inject',`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// link: string | null,`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// type: string,`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // 'link' for the built-in type, or your custom type's slug`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// data: Record\u003cstring, unknown>,// values for that type's field schema`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// sort_index: number,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// web_media: { id, src, alt, width, height, source, mediaContentType },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// mobile_media: { id, src, alt, width, height, source, mediaContentType },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// web_layout: { placement: 'hero' | 'inline', width, height, position },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// mobile_layout:{ placement: 'hero' | 'inline', width, height, position },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// }>`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Each banner carries the `,_jsx(_components.code,{children:`rule_id`}),` of the `,_jsx(_components.a,{href:`/platform/merchandising`,children:`merchandising rule`}),` that produced it. `,_jsx(_components.code,{children:`data._meta.appliedRules`}),` (a flat array of rule ID strings) still lists every applied rule.`]}),`\n`,_jsx(_components.p,{children:`Four parts of the banner payload matter for rendering:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Per-device media and layout.`}),` Pick `,_jsx(_components.code,{children:`web_*`}),` on desktop and `,_jsx(_components.code,{children:`mobile_*`}),` on mobile. They’re independent. A hero on web can be an inline tile on mobile.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Mode.`}),` `,_jsx(_components.code,{children:`overtake`}),` replaces the product card at `,_jsx(_components.code,{children:`position`}),`. `,_jsx(_components.code,{children:`inject`}),` inserts the banner and shifts trailing products by one cell.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Link.`}),` On the built-in `,_jsx(_components.code,{children:`link`}),` type, only `,_jsx(_components.code,{children:`inject`}),` banners can carry a top-level `,_jsx(_components.code,{children:`link`}),`. Wrap them in an anchor. Render overtake banners as plain media. Custom `,_jsx(_components.a,{href:`/platform/merchandising/banner-types`,children:`banner types`}),` put their click-through URL inside `,_jsx(_components.code,{children:`data`}),` instead.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Type and data.`}),` `,_jsx(_components.code,{children:`type`}),` is the banner type slug: `,_jsx(_components.code,{children:`'link'`}),` for the built-in type, or the slug of one of your custom types. `,_jsx(_components.code,{children:`data`}),` carries the values of that type’s field schema. Switch renderers on `,_jsx(_components.code,{children:`type`}),` and read fields out of `,_jsx(_components.code,{children:`data`}),`.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`step-1-subscribe-to-the-collection-controller`,children:`Step 1: Subscribe to the collection controller`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`sdk.collection()`}),` returns a reactive controller. Subscribe once and read `,_jsx(_components.code,{children:`data.products`}),` and `,_jsx(_components.code,{children:`data.banners`}),` from the same payload.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`18`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`18`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { getSDK } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@commerce-blocks/sdk'`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { data: sdk, error: sdkError } = getSDK()`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (sdkError) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` console.error(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'SDK not initialized:'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, sdkError.message)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` collection = sdk.collection({ collectionHandle: COLLECTION_HANDLE })`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`collection.subscribe(({ data, loading, error }) => {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (loading || error || !data) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`return`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` render({`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` products: data.products ?? [],`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` banners: data.banners ?? [],`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` })`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`})`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`collection.get({ pagination: { page: 1, limit: 24 } })`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The SDK dedupes identical requests and caches responses in memory for the life of the page. It re-runs the subscriber whenever you call `,_jsx(_components.code,{children:`get()`}),` with new filter or pagination args.`]}),`\n`,_jsx(Heading,{level:`2`,id:`step-2-pick-the-layout-for-the-current-device`,children:`Step 2: Pick the layout for the current device`}),`\n`,_jsx(_components.p,{children:`A banner only has a usable layout when both the media slot and the layout for the active device are present. Skip banners that don’t have both.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`9`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`9`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` mql = window.matchMedia(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'(max-width: 749px)'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` isMobile = () => mql.matches`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`function`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` layoutForDevice(banner) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` media = isMobile() ? banner.mobile_media : banner.web_media`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` layout = isMobile() ? banner.mobile_layout : banner.web_layout`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (!media?.src || !layout) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`return`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` null`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { media, layout, mode: banner.mode, link: banner.link, id: banner.id }`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[`Listen for `,_jsx(_components.code,{children:`mql.addEventListener('change', ...)`}),` and re-render when the breakpoint flips. Banners can have completely different layouts per device. A `,_jsx(_components.code,{children:`2×2`}),` web tile may be a hero on mobile.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`step-3-place-banners-around-the-products`,children:`Step 3: Place banners around the products`}),`\n`,_jsxs(_components.p,{children:[`Hero banners render across the full grid width above the products. Ignore their inline `,_jsx(_components.code,{children:`width`}),` and `,_jsx(_components.code,{children:`height`}),` cell spans; your theme controls the hero’s height and image cropping. Inline banners slot into the product grid by `,_jsx(_components.code,{children:`position`}),` (row-major, 0-indexed). `,_jsx(_components.code,{children:`overtake`}),` replaces the product at that index; `,_jsx(_components.code,{children:`inject`}),` splices the banner in and shifts trailing products. The response is already sorted by `,_jsx(_components.code,{children:`sort_index`}),`, so no extra sort is needed.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`72`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`72`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`function`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` render({ products, banners }) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` host = document.querySelector(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'.collection'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` grid = document.querySelector(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'.collection__grid'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Clear previously rendered hero banners.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` host.querySelectorAll(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'.layers-banner--hero'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`).forEach((el) => el.remove())`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Hero banners - render above the grid.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` banner `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`of`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` banners) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` picked = layoutForDevice(banner)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (picked?.layout.placement === `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'hero'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) renderHero(host, picked)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Inline banners - combined with products into grid cells.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cells = buildGridCells(products, banners)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` grid.innerHTML = cells.map(renderCell).join(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`''`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`function`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` buildGridCells(products, banners) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cells = products.map((p) => ({ type: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'product'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, product: p }))`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inline = banners`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .map((b) => ({ banner: b, picked: layoutForDevice(b) }))`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .filter(({ picked }) => picked \u0026\u0026 picked.layout.placement === `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'inline'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { picked } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`of`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inline) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` position = picked.layout.position ?? 0`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cell = {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` type: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'banner'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` mode: picked.mode,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` link: picked.link,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` media: picked.media,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` width: picked.layout.width,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` height: picked.layout.height,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` id: picked.id,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (picked.mode === `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'overtake'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (position \u003c cells.length) cells[position] = cell`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` else`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cells.push(cell)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`else`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cells.splice(Math.min(position, cells.length), 0, cell)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cells`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`function`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` renderCell(cell) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (cell.type === `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'product'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` renderProductCell(cell.product)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inner = `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'`\u003cimg src=\"${cell.media.src}\" alt=\"${cell.media.alt ?? \\'\\'}\" />`'})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` style = `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"`--span-x:${cell.width};--span-y:${cell.height}`\"})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` classes = `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"`layers-banner layers-banner--inline layers-banner--${cell.mode}`\"})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (cell.mode === `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'inject'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` \u0026\u0026 cell.link) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:' `\u003ca href=\"${cell.link}\" class=\"${classes}\" data-banner-id=\"${cell.id}\" style=\"${style}\">${inner}\u003c/a>`'})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:' `\u003cdiv class=\"${classes}\" data-banner-id=\"${cell.id}\" style=\"${style}\">${inner}\u003c/div>`'})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`function`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` renderHero(host, picked) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` wrapper = picked.mode === `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'inject'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` \u0026\u0026 picked.link`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ? `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'`\u003ca href=\"${picked.link}\" class=\"layers-banner layers-banner--hero\" data-banner-id=\"${picked.id}\">`'})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` : `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:'`\u003cdiv class=\"layers-banner layers-banner--hero\" data-banner-id=\"${picked.id}\">`'})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` closing = picked.mode === `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'inject'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` \u0026\u0026 picked.link ? `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'\u003c/a>'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` : `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'\u003c/div>'`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` host.insertAdjacentHTML(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'afterbegin'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:' `${wrapper}\u003cimg src=\"${picked.media.src}\" alt=\"${picked.media.alt ?? \\'\\'}\" />${closing}`'}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Use `,_jsx(_components.code,{children:`grid-column: span \u003cwidth>; grid-row: span \u003cheight>`}),` (or the `,_jsx(_components.code,{children:`--span-x`}),` / `,_jsx(_components.code,{children:`--span-y`}),` properties) on banner cells so `,_jsx(_components.code,{children:`2×2`}),` tiles actually cover four grid cells.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`9`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`9`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`function`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` renderProductCell(product) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" `\"})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:' \u003ca href=\"/products/${product.handle}\" class=\"product-card\">'})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003cimg src=\"\\${product.featuredMedia?.url ?? ''}\" alt=\"\" />`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" \u003ch3>${product.title}\u003c/h3>\"})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" \u003cspan>${product.price?.formatted ?? ''}\u003c/span>\"})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003c/a>`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" `\"})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`re-running-on-filter-or-pagination-changes`,children:`Re-running on filter or pagination changes`}),`\n`,_jsxs(_components.p,{children:[`Reuse the same collection controller and subscriber, and call `,_jsx(_components.code,{children:`get()`}),` with new args. Layers recomputes the banner payload on every request, so banners are always in sync with the current filter set.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`4`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`collection.get({`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filterGroup: activeFilters,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` pagination: { page, limit: 24 },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`})`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`custom-banner-types`,children:`Custom banner types`}),`\n`,_jsxs(_components.p,{children:[`The rendering steps on this page work unchanged for the built-in `,_jsx(_components.strong,{children:`Link`}),` type. If you’ve defined `,_jsx(_components.a,{href:`/platform/merchandising/banner-types`,children:`custom banner types`}),`, each banner also carries a `,_jsx(_components.code,{children:`type`}),` slug and a `,_jsx(_components.code,{children:`data`}),` object with the type’s saved field values. Switch renderers on `,_jsx(_components.code,{children:`type`}),` and read fields out of `,_jsx(_components.code,{children:`data`}),`. The envelope (media, layout, mode) is the same across all types.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`44`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`44`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`type`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` PickedBanner = ReturnType\u003c`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`typeof`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` layoutForDevice>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`function`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` layoutForDevice(banner) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` media = isMobile() ? banner.mobile_media : banner.web_media`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` layout = isMobile() ? banner.mobile_layout : banner.web_layout`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (!media?.src || !layout) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`return`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` null`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` media,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` layout,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` mode: banner.mode,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` link: banner.link,`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` type`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: banner.`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`type`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` data: banner.data ?? {},`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` id: banner.id,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`function`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` renderBannerBody(picked: NonNullable\u003cPickedBanner>) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`type`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, data } = picked`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` switch`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`type`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` case`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'link'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:' `\u003cimg src=\"${picked.media.src}\" alt=\"${picked.media.alt ?? \\'\\'}\" />`'})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` case`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'countdown_promo'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" `\"})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003cimg src=\"\\${picked.media.src}\" alt=\"\\${picked.media.alt ?? ''}\" />`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" \u003ch3>${escapeHtml(String(data.headline ?? ''))}\u003c/h3>\"})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003ctime datetime=\"\\${data.end_at}\">\\${escapeHtml(String(data.cta_label ?? 'Shop the drop'))}\u003c/time>`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" `\"})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` case`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'spotlight_product'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // product_reference fields arrive pre-resolved to { id, handle }.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" `\"})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003ca href=\"/products/\\${data.spotlight_product?.handle ?? ''}\">`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003cimg src=\"\\${picked.media.src}\" alt=\"\\${picked.media.alt ?? ''}\" />`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" \u003cspan>${escapeHtml(String(data.overlay_label ?? ''))}\u003c/span>\"})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003c/a>`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" `\"})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` default`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Unknown type - fall back to the media so a newly-added type still renders.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:' `\u003cimg src=\"${picked.media.src}\" alt=\"${picked.media.alt ?? \\'\\'}\" />`'})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Reference fields (`,_jsx(_components.code,{children:`product_reference`}),`, `,_jsx(_components.code,{children:`collection_reference`}),`, `,_jsx(_components.code,{children:`variant_reference`}),`) arrive pre-resolved to `,_jsx(_components.code,{children:`{ id, handle }`}),`. Unpublished references are dropped from the payload, so you don’t need to guard against dead handles. Retyped or removed fields on the banner type are dropped too. Treat any field on `,_jsx(_components.code,{children:`data`}),` as optional and fall back cleanly.`]}),`\n`,_jsx(Heading,{level:`2`,id:`fallback-rules`,children:`Fallback rules`}),`\n`,_jsxs(_components.p,{children:[`Per `,_jsx(_components.a,{href:`/platform/merchandising/banners#limits-and-behavior`,children:`Banner Injection`}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`A banner without both the device’s media slot and layout is treated as disabled. `,_jsx(_components.code,{children:`layoutForDevice`}),` returns `,_jsx(_components.code,{children:`null`}),` and you skip it.`]}),`\n`,_jsxs(_components.li,{children:[`A banner without `,_jsx(_components.code,{children:`web_media`}),` or `,_jsx(_components.code,{children:`mobile_media`}),` filled is never enabled by Layers, so it won’t appear in the payload in the first place.`]}),`\n`,_jsxs(_components.li,{children:[`Banners with `,_jsx(_components.code,{children:`mode: 'overtake'`}),` ignore any `,_jsx(_components.code,{children:`link`}),` value. Only `,_jsx(_components.code,{children:`inject`}),` banners are clickable.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`what-the-app-embed-handles-for-you`,children:`What the app embed handles for you`}),`\n`,_jsxs(_components.p,{children:[`The Layers theme app extension does `,_jsx(_components.strong,{children:`not`}),` render banners. Your theme owns that. The embed does handle:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Authenticating the browse request (token, cart context, identity).`}),`\n`,_jsxs(_components.li,{children:[`Sending the `,_jsx(_components.a,{href:`/shopify-integration/storefront-pixel`,children:`storefront pixel`}),` events that track shopper engagement on the underlying grid.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The storefront pixel also tracks `,_jsx(_components.code,{children:`banner_impression`}),` and `,_jsx(_components.code,{children:`banner_click`}),` events automatically for any rendered element whose `,_jsx(_components.code,{children:`data-banner-id`}),` matches a banner `,_jsx(_components.code,{children:`id`}),` from the Layers response, as in the examples above. Keep that attribute on your banner markup so these events fire.`]}),`\n`,_jsx(Heading,{level:`2`,id:`why-the-sdk-over-fetch`,children:`Why the SDK over Fetch`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{style:{textAlign:`left`},children:`Concern`}),_jsx(_components.th,{style:{textAlign:`left`},children:`Fetch version`}),_jsx(_components.th,{style:{textAlign:`left`},children:`SDK version`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:`Driving the request`}),_jsxs(_components.td,{style:{textAlign:`left`},children:[_jsx(_components.code,{children:`fetch`}),` to `,_jsx(_components.code,{children:`/browse/{handle}`})]}),_jsx(_components.td,{style:{textAlign:`left`},children:_jsx(_components.code,{children:`collection.get()`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:`Re-renders`}),_jsx(_components.td,{style:{textAlign:`left`},children:`DIY DOM updates`}),_jsxs(_components.td,{style:{textAlign:`left`},children:[_jsx(_components.code,{children:`subscribe()`}),` callback`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:`Caching during the page`}),_jsx(_components.td,{style:{textAlign:`left`},children:`DIY`}),_jsx(_components.td,{style:{textAlign:`left`},children:`In-memory cache and request deduplication`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:`Re-rendering on filter change`}),_jsx(_components.td,{style:{textAlign:`left`},children:`Manual orchestration`}),_jsxs(_components.td,{style:{textAlign:`left`},children:[`Same controller, call `,_jsx(_components.code,{children:`get()`}),` again`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{style:{textAlign:`left`},children:`Banner placement`}),_jsx(_components.td,{style:{textAlign:`left`},children:`Same: your theme owns the grid math`}),_jsx(_components.td,{style:{textAlign:`left`},children:`Same: your theme owns the grid math`})]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`troubleshooting`,children:`Troubleshooting`}),`\n`,_jsxs(_components.p,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`data.banners`}),` is empty.`]}),` No merchandising rule matched the request, or every matching rule had no enabled banners. Confirm at least one active rule on this collection has banners attached and both media slots filled.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Banners only appear on first load, not after filtering.`}),` Your subscriber probably re-renders products but not banners. Re-read `,_jsx(_components.code,{children:`data.banners`}),` from the same payload on every state update. They ship together.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Inline banner is at the wrong cell.`}),` `,_jsx(_components.code,{children:`position`}),` is row-major and 0-indexed. Verify the device’s `,_jsx(_components.code,{children:`*_layout.position`}),` matches the cell index you expect after flattening the grid to a single array.`]}),`\n`,_jsxs(_components.p,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`2×2`}),` inline tile renders as a `,_jsx(_components.code,{children:`1×1`}),`.`]}),` Your CSS isn’t honoring `,_jsx(_components.code,{children:`width`}),`/`,_jsx(_components.code,{children:`height`}),`. Apply `,_jsx(_components.code,{children:`grid-column: span \u003cwidth>; grid-row: span \u003cheight>`}),` on banner cells.`]}),`\n`,_jsx(Heading,{level:`2`,id:`see-also`,children:`See also`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/developers/rendering-banners-in-liquid`,children:`Rendering banners in Liquid (Fetch)`}),` — the no-dependency equivalent.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/platform/merchandising/banners`,children:`Banner Injection`}),` — payload reference and dashboard model.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/platform/merchandising/banner-types`,children:`Banner Types`}),` — define the typed field schemas banners can use.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/help/merchandising/add-banner-to-rule`,children:`Add a banner to a rule`}),` — merchandiser walkthrough.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/sdk/api-reference/client-methods`,children:`Client methods — collection`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/api-reference/browse`,children:`Browse API`}),` — request and response reference.`]}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Rendering banners with the SDK","description":"Render merchandising banners with the Layers SDK by reading data.banners from the collection controller. Hero rows and inline tiles overtake or inject products.","href":"/developers/rendering-banners-with-the-sdk"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Overview","slug":"overview","depth":2,"children":[]},{"title":"Prerequisites","slug":"prerequisites","depth":2,"children":[]},{"title":"The banner payload","slug":"the-banner-payload","depth":2,"children":[]},{"title":"Step 1: Subscribe to the collection controller","slug":"step-1-subscribe-to-the-collection-controller","depth":2,"children":[]},{"title":"Step 2: Pick the layout for the current device","slug":"step-2-pick-the-layout-for-the-current-device","depth":2,"children":[]},{"title":"Step 3: Place banners around the products","slug":"step-3-place-banners-around-the-products","depth":2,"children":[]},{"title":"Re-running on filter or pagination changes","slug":"re-running-on-filter-or-pagination-changes","depth":2,"children":[]},{"title":"Custom banner types","slug":"custom-banner-types","depth":2,"children":[]},{"title":"Fallback rules","slug":"fallback-rules","depth":2,"children":[]},{"title":"What the app embed handles for you","slug":"what-the-app-embed-handles-for-you","depth":2,"children":[]},{"title":"Why the SDK over Fetch","slug":"why-the-sdk-over-fetch","depth":2,"children":[]},{"title":"Troubleshooting","slug":"troubleshooting","depth":2,"children":[]},{"title":"See also","slug":"see-also","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/protoninc/d2da920448b9ce07/track.js"],"subdomain":"protoninc","siteName":"Layers","title":"Rendering banners with the SDK - Layers","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-19T18:18:23.794Z","originalFileLocation":"developers/rendering-banners-with-the-sdk.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Render merchandising banners with the Layers SDK by reading data.banners from the collection controller. Hero rows and inline tiles overtake or inject products.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Layers\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/protoninc/-Zid9_7urMZu-aPC/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/protoninc/-Zid9_7urMZu-aPC/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/protoninc/-Zid9_7urMZu-aPC/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/protoninc/-Zid9_7urMZu-aPC/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/protoninc/-Zid9_7urMZu-aPC/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/protoninc/-Zid9_7urMZu-aPC/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/protoninc/-Zid9_7urMZu-aPC/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/protoninc/-Zid9_7urMZu-aPC/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/protoninc/-Zid9_7urMZu-aPC/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Rendering banners with the SDK - Layers\">\u003cmeta data-mint-head property=\"og:description\" content=\"Render merchandising banners with the Layers SDK by reading data.banners from the collection controller. Hero rows and inline tiles overtake or inject products.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Layers\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.uselayers.com/developers/rendering-banners-with-the-sdk\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://protoninc.mintlify.site/_mintlify/api/og/v2?division=Liquid+%2B+SDK+guides\u0026amp;title=Rendering+banners+with+the+SDK\u0026amp;description=Render+merchandising+banners+with+the+Layers+SDK+by+reading+data.banners+from+the+collection+controller.+Hero+rows+and+inline+tiles+overtake+or+inject+products.\u0026amp;theme=b639e83e40674e1127455713\u0026amp;signature=40fd6b4e5abf11e3cf4399051cf12f4e304ece23e1df25d8be8336cf49d188af\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Rendering banners with the SDK - Layers\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Render merchandising banners with the Layers SDK by reading data.banners from the collection controller. Hero rows and inline tiles overtake or inject products.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://protoninc.mintlify.site/_mintlify/api/og/v2?division=Liquid+%2B+SDK+guides\u0026amp;title=Rendering+banners+with+the+SDK\u0026amp;description=Render+merchandising+banners+with+the+Layers+SDK+by+reading+data.banners+from+the+collection+controller.+Hero+rows+and+inline+tiles+overtake+or+inject+products.\u0026amp;theme=b639e83e40674e1127455713\u0026amp;signature=40fd6b4e5abf11e3cf4399051cf12f4e304ece23e1df25d8be8336cf49d188af\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/protoninc/-Zid9_7urMZu-aPC/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Layers\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#607FFD\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.uselayers.com/developers/rendering-banners-with-the-sdk\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/developers/rendering-banners-with-the-sdk.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.uselayers.com/#organization\",\"name\":\"Layers\",\"url\":\"https://docs.uselayers.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/protoninc/PNs-gxGUVcdBDEEC/logo.svg?fit=max\u0026auto=format\u0026n=PNs-gxGUVcdBDEEC\u0026q=85\u0026s=989e3194cb32f07e7018b8b7186b9007\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.uselayers.com#website\",\"name\":\"Layers\",\"url\":\"https://docs.uselayers.com\",\"publisher\":{\"@id\":\"https://docs.uselayers.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.uselayers.com/developers/rendering-banners-with-the-sdk#webpage\",\"url\":\"https://docs.uselayers.com/developers/rendering-banners-with-the-sdk\",\"name\":\"Rendering banners with the SDK\",\"description\":\"Render merchandising banners with the Layers SDK by reading data.banners from the collection controller. Hero rows and inline tiles overtake or inject products.\",\"dateModified\":\"2026-10-19T18:18:23.794Z\",\"isPartOf\":{\"@id\":\"https://docs.uselayers.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.uselayers.com/developers/rendering-banners-with-the-sdk#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.uselayers.com/developers/rendering-banners-with-the-sdk#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Liquid + SDK guides\",\"item\":\"https://docs.uselayers.com/developers/rendering-facets-with-the-sdk\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Rendering banners with the SDK\",\"item\":\"https://docs.uselayers.com/developers/rendering-banners-with-the-sdk\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.uselayers.com/developers/rendering-banners-with-the-sdk#article\",\"headline\":\"Rendering banners with the SDK\",\"name\":\"Rendering banners with the SDK\",\"description\":\"Render merchandising banners with the Layers SDK by reading data.banners from the collection controller. Hero rows and inline tiles overtake or inject products.\",\"url\":\"https://docs.uselayers.com/developers/rendering-banners-with-the-sdk\",\"mainEntityOfPage\":{\"@id\":\"https://docs.uselayers.com/developers/rendering-banners-with-the-sdk#webpage\"},\"dateModified\":\"2026-10-19T18:18:23.794Z\",\"publisher\":{\"@id\":\"https://docs.uselayers.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.uselayers.com#website\"}}]}\u003c/script>","agentPointerHref":"/developers/rendering-banners-with-the-sdk.md","siteName":"Layers","nav":{"global":null,"anchors":[{"anchor":"Documentation","pages":[{"title":"Documentation","href":"/introduction"}]},{"anchor":"Help Center","icon":"map","pages":[{"title":"Help Center","href":"/help/onboarding/install"}]},{"anchor":"Developers","icon":"code","tabs":[{"tab":"SDK","pages":[{"title":"SDK","href":"/developers/overview"}]},{"tab":"Product Schema","pages":[{"title":"Product Schema","href":"/developers/product-schema"}]},{"tab":"Liquid","groups":[{"group":"Liquid Integration","pages":[{"title":"Theme implementation checklist","href":"/developers/theme-implementation-checklist"},{"title":"Liquid integration","href":"/developers/liquid-integration"},{"title":"What the app embed and SDK handle for you","href":"/developers/app-embed"},{"title":"Visual Search widget","href":"/developers/visual-search-widget"}]},{"group":"Liquid + Fetch guides","pages":[{"title":"Rendering facets in Liquid","href":"/developers/rendering-facets-in-liquid"},{"title":"Rendering sort orders in Liquid","href":"/developers/rendering-sort-orders-in-liquid"},{"title":"Rendering blocks in Liquid","href":"/developers/rendering-blocks-in-liquid"},{"title":"Rendering banners in Liquid","href":"/developers/rendering-banners-in-liquid"},{"title":"Implementing search in Liquid","href":"/developers/implementing-search-in-liquid"}]},{"group":"Liquid + SDK guides","pages":[{"title":"Rendering facets with the SDK","href":"/developers/rendering-facets-with-the-sdk"},{"title":"Rendering sort orders with the SDK","href":"/developers/rendering-sort-orders-with-the-sdk"},{"title":"Rendering blocks with the SDK","description":"Render Layers recommendation blocks in a Shopify theme as a Liquid section, hydrated by the @commerce-blocks/sdk blocks controller with cart context.","href":"/developers/rendering-blocks-with-the-sdk"},{"title":"Rendering banners with the SDK","href":"/developers/rendering-banners-with-the-sdk"},{"title":"Implementing search with the SDK","description":"Build a Shopify theme search experience with @commerce-blocks/sdk using autocomplete, prepare/get, facets, sort orders, and reactive controllers.","href":"/developers/implementing-search-with-the-sdk"}]}]}]},{"anchor":"API Reference","icon":"rectangle-terminal","pages":[{"title":"API Reference","href":"/api-reference/browse"}]},{"anchor":"Integrations","icon":"plug","href":"https://www.uselayers.com/integrations?utm_source=docs\u0026utm_medium=referral\u0026utm_campaign=docs-to-site"}]},"basePath":"","title":"Rendering banners with the SDK - Layers","buildId":"dpl_596ePT575z4qnAFksq1biRW97aLY","deploymentId":"dpl_596ePT575z4qnAFksq1biRW97aLY","dynamics":[],"chunks":[]}