Relation blocks
Pick by hand what goes with a product, and let the page show exactly that list.
A store already has two ways to show "other products" on a page: a Collection — a fixed group — and Related products, inferred from the collections a product shares.
Neither can say this: "buy this shirt and take those trousers with it." That is a claim only a person makes, and Relation blocks is where they make it.
A block is named at the store, filled at each product
This is the strangest part and the one that explains everything else.
Your product page is one template shared by every product. So a list placed on it cannot point at "shirt X's block" — the same page also serves the trousers, the shoes and everything else, and every one of them would show the wrong shelf.
So it is split in two:
- You name a block once, under Manage → Relation blocks — "Bought together", say.
- Each product fills that block itself, on the product's own form.
The page binds to the name; each product answers that name with a list of its own.
Creating a block
On the Relation blocks screen, press New block. Four fields:
Block name — what you see: "Bought together".
Key — derived from the name ("bought-together"). This is what a page remembers, so it cannot be changed once the block exists. Changing it would leave every page naming it pointing at nothing — an empty shelf, with no error anywhere. Before you save, edit it freely.
Belongs to and Holds — two separate fields, and this is the part that earns its keep.
"Belongs to" is not "Holds", and that is deliberate
Belongs to is who fills the block. Holds is what goes in it. They are independent, so all four combinations work:
| Block | Belongs to | Holds | Used for |
|---|---|---|---|
| Bought together | Products | Products | A cross-sell shelf on a product page |
| Related reading | Products | Articles | Guides for the thing being viewed |
| Products in this post | Articles | Products | Selling inside a blog post |
| Read next | Articles | Articles | Keeping a reader on the site |
Collapsing the two into one field loses exactly the capability you want: a product holding a shelf of articles, an article holding a shelf of products.
Filling a block
Open a product and go to the Organization tab. The Relation blocks card lists every block a product can fill — including the ones that hold articles.
Each block has a Pick items button and a list you can drag. The order you drag is the order the page shows — not alphabetical, not the order you added them.
Articles work the same way, on the Meta tab of the article form.
If the store has no blocks yet, the card does not sit there blank — it links to the screen that creates one. "This product has nothing related" and "this store has defined no blocks" are different statements, and only the second is true.
Putting it on a page
Drop a Product list onto a page, open its properties, and under Source choose your block by name.
The Source list only offers blocks this list can actually show. A Product list sees only blocks that hold products; a block of articles never appears there, because choosing it would build product cards out of article ids — every card blank, with nothing to say why.
When a shelf is empty
An empty shelf renders whatever you designed for the empty state, and the properties panel says why — two different causes needing two different actions:
- "Nothing picked for this block" — the block is right, nobody has filled it. Open the product and pick items.
- "This block belongs to another type" — you put a "Read next" block (which articles fill) on a product page. Choose another block under Source.
It never quietly grabs a few products to fill the gap. An empty shelf is an honest answer; a shelf padded with whatever was to hand, under a heading that says "Bought together", looks exactly like a working feature — and you would never find out which blocks you forgot to fill.
Deleting and copying
Delete a product that sits in another product's block and the confirmation tells you first how many shelves will lose an item.
Copy a store and the blocks travel with it. A block is matched by key: if the target store already has one with that key, the items go into the block already there rather than creating a second — and the target's own definition wins, because the items already filed there were filed under its rules.
An item that did not make it into the new store is dropped from the shelf, rather than left as a gap nobody can explain.
Updated 08/09/2026