Concepts
This page explains the ideas behind Listing Interrupter — what a slot really is, why the grid always closes evenly, and why some things are deliberately not configurable. You do not need it to use the plugin, but it makes the behaviour predictable instead of surprising.
Vocabulary
These are the terms the admin, this documentation and the plugin's code all use.
- Interrupter (or tile) — one piece of promotional content injected into a product listing grid. The thing you create and manage.
- Banner — the tile type that ships today: background image, badge line, headline, subline, CTA text and link, colours, alignment.
- Position — the grid slot the tile occupies, counted from 1. Position 1 is before the first product.
- Span — how wide the tile is, in product cells (
1,2,3, …) or full row. - Target — where a tile may appear: the categories it is checked into, in the sales channels it is assigned to.
- Page range — which listing pages a tile appears on.
- Availability rule — an existing Shopware Rule Builder rule attached to a tile. Covers both audience and schedule.
- Viewport override — a tablet- or mobile-specific value for a field that otherwise inherits from desktop.
A listing page is a grid of cells
A category page shows a fixed number of items — say 24 — arranged in rows whose column count comes from your theme (Shopware's default is 4 columns on desktop, 2 on tablet, 1 on mobile).
The plugin treats that page as 24 cells, not 24 products. A tile occupies cells:
- A tile with a span of
NoccupiesNcells and the page fetchesNfewer products. - A full row tile adds a row of its own and occupies no product cells at all.
This is why the grid still closes on a complete row when a tile is present. It is also why those displaced products are not lost — the page after it starts that many products earlier, so every product remains reachable, and the pager's page count grows to match.
The alternative — simply adding the tile as a 25th cell — was the plugin's original design. It was replaced because a page ending in a single orphaned product reads as a layout bug, not as a campaign.
Positions are cell numbers, not product numbers
Because a tile occupies cells, "the 5th slot" and "after the 4th product" stop being the same thing as soon as a wider tile sits ahead. The plugin counts cells: a three-cell tile at slot 1 makes the next product slot number 4.
The placement canvas walks the grid with exactly the same arithmetic the storefront uses, which is why the number on a slot dot is the position that gets saved when you drop there.
When several tiles land on the same page
Tiles at the same position share the row, ordered by priority, and on a tie the older tile comes first. Within an insertion gap the storefront renders tiles in position order, so the page's DOM always matches what the canvas showed you.
Why the tile designer is purpose-built
A tile's content is a fixed schema stored on the plugin's own entity. It is not a CMS slot that can host arbitrary CMS elements.
The trade is deliberate. Hosting CMS elements buys unlimited flexibility, but it costs a detour into the Shopping Experiences editor for every edit, a much weaker live preview, and — in the competing implementation of this idea — a framework dependency you have to install first. The promise here is a tile built in under a minute and placed visually, which a fixed schema with an instant preview can keep and a slot indirection cannot.
The consequence is that you cannot embed a third-party CMS element inside a tile. New content shapes arrive as new tile types instead.
Inheritance is resolved by the browser, not by device sniffing
Tablet and mobile inherit from desktop until you override a field. That resolution happens server-side, for all three viewports at once, and the page then carries all three answers in its markup — as Bootstrap column classes, display utilities, and a small scoped style block for colours that differ.
Your browser picks the one that applies at its current width. Nothing detects a device.
This matters because listing pages are HTTP-cached and served to every screen size from the same cache entry. Baking one "detected" viewport into that cached HTML would serve the wrong tile to everyone else. The trade-off is that a tile with no overrides renders exactly as it did before overrides existed — the extra markup only appears when an override actually diverges.
Viewport visibility is presentation-only
Hiding a tile on mobile hides the tile. It does not give mobile its products back.
Displacement is decided on the server, before any browser is involved, and a cached page cannot have a different product count per screen width without splitting the cache per device. So a breakpoint where the tile is hidden shows the same grid minus the tile: the cells stay reserved, the products that moved to the next page stay there.
The same applies to per-viewport width overrides — only the desktop width counts towards displacement.
Rules are evaluated once, by Shopware
The plugin never evaluates a rule's conditions itself. It asks the sales channel context which rules Shopware already matched for this request, and shows the tiles whose rules are all in that set.
That is the same set Shopware's HTTP cache varies its cache key on. Using it means a page cached for one audience — a guest, or a visitor outside a campaign's date window — can never be served to a context whose matched rules differ. Evaluating the rule payload independently would break that alignment and leak tile visibility between contexts.
One consequence: a page already sitting in the cache is not re-rendered the moment a date window opens or closes. It refreshes on its normal cache lifetime.
Why the list page does not say "rule not matching"
The status badge tells you whether a tile is active. It does not claim to know whether the tile's rules match, because the admin has no shopper: no cart, no customer group, no session to evaluate a rule against. A badge that guessed would sometimes tell you a working tile is broken, which is worse than telling you nothing.
Cache invalidation is targeted
Saving a tile refreshes the storefront without a manual cache clear — but it does not flush the cache.
The plugin resolves exactly which categories a change affects and invalidates only those listing routes, using Shopware's own listing-route cache tags. That covers reassignment (the category a tile left and the one it joined), plain content edits, and deletion.
Emptying the whole cache would satisfy the same "no manual clear" promise while throwing away every listing page that had nothing to do with your edit.
The preview selection is not part of the tile
The sales channel and category above the placement canvas exist to make the canvas concrete. They are never saved.
A tile has one position, and that position means the same thing in every category it targets — so there is no "preferred" category to store. The selectors default to the tile's first assigned channel and category, which is why you rarely have to touch them, and they reset when you reopen the tile.
The practical consequence, mentioned in the placement guide, is that moving a tile moves it in every category it targets. Duplicating is how you give one category its own placement.
