Skip to main content
A container is an ordinary Liquid section with named slots. Each slot holds an ordered list of other section instances. You design the layout; editors choose the sections that fill it. Use containers for a feature panel beside smaller cards, a content area with a sidebar, or a five-panel showcase. Slots are not limited to left and right columns.
Section slots require container rendering and editor authoring support in your environment. Adding a file to your local theme does not install or publish it in a company’s theme.

Understand the building blocks

Your templates remain Liquid. The JSON inside {% schema %} stores declarations or configuration; it is not a JSON template migration. Do not create Shopify-style JSON section-group files for this feature. Navbar and footer templates remain separate from page containers, including country-specific variants. They are not eligible slot children.

Create your first container

Create sections/editorial_grid/index.liquid in your theme:
The definition’s slots array declares the available drop targets. Each {% section_slot 'main' %} tag renders the corresponding slot and its assigned children at that position in your markup. Create assets/section-editorial-grid.css:
This example uses a two-to-one desktop split and stacks on small screens. The gap on each slot separates multiple child sections inside it. Replace the example spacing with your theme’s tokens where available.

Follow the slot contract

  • Give each slot a unique, stable ID and a readable name.
  • Use 1–64 ASCII letters, numbers, underscores, or hyphens for slot and section instance IDs. Avoid the reserved identifiers __proto__, constructor, and prototype.
  • Pass a quoted literal to the tag. Dynamic slot names are not supported.
  • Declare every rendered slot in the section schema, and render each slot once.
  • Keep slot IDs stable after publishing. Renaming a slot requires updating its saved assignments too.
For example, this is valid:
This is not valid:
An undeclared slot renders nothing. A declared, empty slot still renders its wrapper.

Add sections in the editor

After installing the container and its stylesheet in your target theme:
  1. Open a compatible page in the Page Editor.
  2. Add the container from Sections.
  3. Drag a new section into a slot in the preview, or move an existing page section into it.
  4. Use Layers to inspect nested sections, reorder them, or move them between slots and back to the page.
  5. Edit each child’s settings and blocks as you would for a root section.
  6. Save, reload, and inspect the result before publishing.
The editor supplies visible drop guides for empty slots. Those guides are editor UI, not storefront content. Visitors see your container styling and the sections you add—not the editor’s drop instructions. Existing section controls continue to support editing, hiding, duplication, deletion, and undo/redo. Duplicating a container copies its subtree with new section and block IDs. Deleting a container removes its children too.
Slot placement does not remove a section’s page-type requirements. A section that needs product context still needs a product page. Also test its CSS at the slot’s width: a full-width hero does not automatically become a compact card.

See the saved Liquid template

The editor keeps all section instances in the page schema’s flat sections map. A container instance’s slots object points to child IDs; it does not embed child objects. Here is a complete minimal page body. It assumes you have installed the editorial grid above and the text section below. Preserve any existing layout declaration or surrounding page markup when adapting it.
Only the root container has a standalone section tag. Do not also add root tags for its children; the slot renders them. The order of IDs in each slot array is the child render order. Create the example child at sections/editorial_text/index.liquid:
The child needs no slot-specific markup. Existing sections retain their own settings, blocks, and block ordering when placed inside a container. A hidden slotted child has "disabled": true on its section instance. Use the editor’s hide/show controls when moving between root and nested placements, so the saved visibility representation stays consistent.

Do not confuse the two slots shapes

Design a five-slot showcase

You control slot placement through ordinary HTML and CSS. This example gives you one large feature panel and four supporting panels. It uses container width, rather than viewport width, so the layout can also adapt when nested. Create sections/panel_showcase/index.liquid:
Create assets/section-panel-showcase.css:
The feature spans two columns and two rows at wide widths. At medium widths, it spans the first row above a two-column grid. At narrow widths, all five slots stack in source order. Use direct-child selectors, as above, to keep a parent container’s styles from selecting slots inside a nested container. Keep reading order meaningful without CSS, and check keyboard focus order when changing visual placement. Avoid fixed heights or clipping that could hide a child’s content.

Style the generated wrapper

The slot tag generates this wrapper; you do not write it yourself:
Use the slot attribute for scoped styling. The container attribute identifies the placement, not the reusable definition. Do not manufacture these attributes to create drop targets—use the Liquid tag and schema declaration together.

Reuse and nesting

You can place the same container definition more than once. Each placement has independent settings and child assignments. This is reusable layout code, not globally synchronized content. Publishing an updated shared definition changes the layout used by its placements. Changing one placement’s child settings does not update another placement. When adding a slot to an already-used definition, initialize its assignment array in every existing placement too—for example, "new_slot": []. Publishing the definition alone does not add that assignment to saved instances. Before removing a slot, move or deliberately remove its assigned children; do not leave them stranded in the page configuration. A slot can contain another container. Keep these limits in mind: Ordinary child sections can sit inside the fourth container level; a fifth container level is not supported. Use separate child instances if you need similar content in multiple slots. The renderer skips missing, disabled, invalid, or already-claimed child references. Do not rely on that behavior to repair a malformed template: validate ownership, IDs, and limits before saving generated content.

Install and publish safely

  1. Confirm that the environment supports both container rendering and editor authoring.
  2. Install the container definition, its stylesheet, and any new child definitions in the intended company’s theme. Use your existing theme development workflow.
  3. Verify that the editor is using that theme and that the required definitions are published for rendering.
  4. Add a container to a draft page. Test empty and populated slots, nested placements, and narrow widths.
  5. Save and reload. Confirm that child order, settings, and blocks persist.
  6. Preview and publish through your normal Page Editor workflow.
Adding a container definition to a root theme does not install it into an existing company’s cloned theme. Install and verify the required definitions and assets in that target theme. Avoid replacing an entire customized theme just to add a container.
Keep container rendering available while published pages use slots. Turning off new authoring is not a rollback of published content. Before removing rendering support, move children back to root placements or replace the affected pages and verify the published result.

Troubleshoot a container

Implementation checklist for coding agents

Treat this page as the section-slot contract. Read the target theme before editing it, and preserve its existing conventions and content.
  • Confirm feature availability; do not infer it from the presence of this guide.
  • Keep templates in Liquid. Do not introduce JSON template or section-group files.
  • Create an ordinary section definition with a schema slot array and matching literal slot tags.
  • Design responsive geometry in scoped CSS; use the target theme’s tokens where available.
  • Keep instances in the flat sections map. Store only ordered child IDs in instance slot assignments.
  • Emit root section tags only for root placements. Preserve child settings, blocks, and ordering when moving instances.
  • Generate unique instance IDs. Validate one-parent ownership, no cycles, and the documented limits.
  • Do not nest navbar or footer templates, or bypass page-type compatibility.
  • Do not rename existing slot IDs without migrating their assignments.
  • Test drag-and-drop, move-to-root, hide/show, duplicate/delete, undo/redo, save/reload, and published rendering.
  • Check an unchanged flat page and country-specific navbar/footer output for regressions.
  • Report which files changed and which checks ran. Installing files, publishing a theme, and publishing a page are separate actions; confirm the target and authorization before each remote change.

Copyable task brief

For smaller pieces of reusable content, see Blocks and components. For section controls and placement restrictions, see Schema components.