Skip to main content
Banner injection lets a merchandising rule embed promotional media directly into a collection grid. Banners are a rule consequence in the same family as pins: the rule decides when a banner shows up (collection, contextual conditions, schedule), and the banner decides what shows up. A banner can be a full-width hero above the grid or an inline tile (1×1 or 2×2) that sits inside the grid alongside products. Every rule can carry up to five banners, each with independent Web and Mobile media.
Banners are emitted as configuration on the browse response — they’re a passthrough for your storefront to render. Layers does not render banners into your theme directly. See What ships in the browse response for the payload shape.
Every banner has:
  • A name for internal organization (not shown to shoppers).
  • Web Media and Mobile Media — independent images per device. A banner only goes live once both are set.
  • A Mode:
    • overtake — the banner takes the place of a product card in the grid.
    • inject — the banner is inserted alongside product cards. Only inject banners can carry a click-through link.
  • A Per-Device Layout controlling placement and size:
    • placement: hero (full-width row above the grid) or inline (a cell inside the grid).
    • width × height: cell span. Inline tiles support 1×1 and 2×2.
    • position: row-major grid cell index (or null for unplaced).
  • An optional Schedule (schedule_start_at / schedule_end_at) — open-ended on either side.
  • Optional Contextual Conditions — the same shape as rule-level contextual conditions, evaluated per banner.
  • A Sort Index that controls the order banners are applied when a rule has more than one.
Each banner has its own on/off state. Hero and inline placements can coexist inside the same rule.

How Banners Combine With Pins and Expressions

A merchandising rule can carry any combination of pins, sort expressions, variant breakouts, and banners. Banners are layered on top of the underlying product order — they don’t reorder products, they take grid space:
  • Hero banners render before the first product row. They never push products out of the result.
  • Inline overtake banners consume the grid cell at their position, displacing the product that would have appeared there.
  • Inline inject banners insert themselves into the grid, shifting products after them by one cell.
Pin drag-and-drop and banner layout are independent — placing a banner doesn’t reshuffle pinned products, and re-pinning a product doesn’t move banners. A rule that carries banners but no pins, expressions, or variant breakouts is still considered to have an effective impact, so banner-only rules are never silently dropped.

Scheduling and Targeting

Banners inherit the rule’s own scheduling and contextual conditions implicitly — if the rule isn’t active for the request, the banner isn’t either. On top of that, each banner can carry its own schedule and contextual conditions:
  • The banner’s schedule_start_at / schedule_end_at window controls when the banner is enabled. Layers checks scheduled banners continuously and toggles the banner’s enabled state to match — changes typically take effect within about a minute of the configured time. Browse responses ship whatever banners are currently enabled; the schedule window itself isn’t re-checked per request.
  • The banner’s contextual conditions are evaluated per request and must evaluate true for the banner to ship.
This is the same scheduler-driven model used by rule scheduling and scheduled pins, so banner schedules behave consistently with the rest of merchandising. In rule preview, every enabled banner is shown regardless of its contextual conditions so you can audit the full set you’re editing. Live browse traffic always applies them.

What Ships in the Browse Response

When a rule matches a request and has at least one enabled banner that passes its own gates, the browse response carries a banners array under that rule’s applied-rule entry. Layers does not render anything into your storefront — your theme is responsible for placing the banner into the grid based on its placement and position.
{
  "appliedRules": [
    {
      "id": "01J...rule",
      "banners": [
        {
          "id": "01JC...banner",
          "name": "Summer Sale Hero",
          "mode": "inject",
          "link": "/collections/summer-sale",
          "sort_index": 0,
          "web_media": { "src": "https://cdn.shopify.com/.../hero-web.jpg", "alt": "Summer Sale" },
          "mobile_media": { "src": "https://cdn.shopify.com/.../hero-mobile.jpg", "alt": "Summer Sale" },
          "web_layout":   { "placement": "hero",   "width": 1, "height": 1, "position": null },
          "mobile_layout":{ "placement": "hero",   "width": 1, "height": 1, "position": null }
        },
        {
          "id": "01JC...banner2",
          "name": "Featured Bundle Tile",
          "mode": "overtake",
          "link": null,
          "sort_index": 1,
          "web_media": { "src": "https://cdn.shopify.com/.../bundle-web.jpg", "alt": "Bundle" },
          "mobile_media": { "src": "https://cdn.shopify.com/.../bundle-mobile.jpg", "alt": "Bundle" },
          "web_layout":   { "placement": "inline", "width": 2, "height": 2, "position": 4 },
          "mobile_layout":{ "placement": "inline", "width": 1, "height": 1, "position": 2 }
        }
      ]
    }
  ]
}
Pick the layout for the current device (web_layout or mobile_layout), then:
  • For placement: "hero", render above the grid before the first product cell.
  • For placement: "inline", place at position (row-major) with the banner spanning width × height cells. If multiple banners target the same cell, the lower sort_index wins.
  • If a banner’s mode is inject and a link is set, wrap the banner in an anchor.

Mirrored Metaobjects

Each enabled banner is also mirrored to a $app:banner metaobject in your Shopify store, linked back to the rule. Storefront code that prefers reading from metaobjects (e.g. a fully Liquid-rendered grid) can use those alongside the browse-response payload. See Metaobjects.

Limits and Behavior

  • Max 5 banners per rule.
  • Both Web and Mobile media required to go live. A banner without both slots filled is treated as disabled, even if it’s toggled on.
  • Per-device layout is independent. A hero on web can be an inline tile on mobile, or vice versa.
  • Config history covers banners. Banner add/edit/remove/reorder is captured in rule config history snapshots and restored when you roll a rule back.
  • Cache invalidation runs on any banner change (not just pin/expression changes), so a banners-only edit goes live immediately.

See Also