FoxrFoxr

Full layout

Rearrange the whole builder — decide where the tabs, grid, and sidebar sit instead of using the built-in arrangement.

Full layout is the one custom template that's different in kind from the other four. They change what a piece looks like; Full layout changes where the pieces go.

Reach for it when the built-in arrangement is the problem — you want the sidebar above the grid instead of beside it, or a section per category, or your own grid container around the cards.

What you get

Every piece of the builder arrives ready-made on props.slots, already wired to data, pricing, and the cart. You place them; the app keeps running them.

<div className="foxr-bb-layout-root">
  {props.slots.tabs}
  {props.slots.categoryTitle}
 
  <div className="foxr-bundle-builder-layout">
    <div className="foxr-bb-products-section">
      {props.slots.productGrid}
    </div>
 
    {props.slots.sidebar}
  </div>
</div>

That's the starting template the editor gives you — it reproduces the built-in arrangement exactly, so you edit working markup rather than starting from a blank box.

Note the help text under the editor: it repeats the wrapper rule below, so you have it in front of you while you write.

The one class that controls everything

This is the mechanic that makes Full layout click, and it's worth reading twice:

Where the sidebar sitsWhat it does
Inside an foxr-bundle-builder-layout wrapperThe built-in side-by-side row, with a sticky 320px sidebar that follows the shopper down the page.
Outside that wrapperThe sidebar automatically becomes a normal full-width, non-sticky block — ready to sit above or below the grid.

So moving the kit panel from beside the grid to above it isn't a CSS job. You just move the element out of that wrapper, and the sidebar reshapes itself.

Your Design-tab settings keep working

Your markup renders inside foxr-bundle-builder-container, so all the color, spacing, and typography settings still apply — and so does your Custom CSS.

The slots

SlotWhat it is
props.slots.tabsThe category switcher. null when the merchant turned tabs off.
props.slots.categoryTitleThe heading above the products. null when that setting is off.
props.slots.productGridThe full grid, including loading placeholders and the "no products" message.
props.slots.productCardsThe same cards as a bare array, for when you want your own grid element around them.
props.slots.sidebarThe kit panel. Includes the Buy Box (Sidebar Widget → Template 3) when that template is selected.

Guard the nullable slots

tabs and categoryTitle are null when the merchant switched those settings off. Placing a null is harmless — but don't wrap one in your own decorative container, or you'll render an empty box.

The other props

PropWhat it is
props.productsThe products on screen, in grid order, each with its rendered card. Empty while isLoadingProducts is true.
props.categoriesThe same products regrouped per category, each with rendered cards and a ready-made grid element that carries the same columns and styling as the main grid.
props.tabsPropsThe Category tabs props bag — exactly what that template receives, for writing the switcher inline instead of placing props.slots.tabs.
props.sidebarPropsThe Sidebar props bag, for writing the panel inline instead of placing props.slots.sidebar.
props.activeCategoryId / props.onCategoryChangeThe selected category, and a function to switch it.
props.categoryTitleDisplay name of the active category, as a plain string.
props.isLoadingProductsTrue while availability is still resolving. Don't paint prices or counts off products yet.
props.hasProductsFalse when the active category has nothing to show.
props.formatPriceFormat any number in the store's currency.

Recipe — sidebar above the products, full width

The kit panel is the thing shoppers watch fill up, so it often belongs at the top. No new CSS needed: outside the foxr-bundle-builder-layout wrapper, the sidebar becomes a full-width block on its own.

<div className="foxr-bb-layout-root">
  {props.slots.tabs}
 
  {props.slots.sidebar}
 
  {props.slots.categoryTitle}
  {props.slots.productGrid}
</div>

Move the sidebar line after productGrid for the bottom variant.

Recipe — your own grid around our cards

Keeps every card's behavior — variants, live pricing, stock, add and remove — while you own the container it sits in.

<div className="foxr-bb-layout-root">
  {props.slots.tabs}
 
  <div className="my-masonry">
    {props.slots.productCards}
  </div>
 
  {props.slots.sidebar}
</div>

Use props.slots.productCards rather than props.slots.productGrid — the latter brings our grid element with it. The cards are already keyed, so render the array as-is.

Recipe — one section per category

The sectioned page: every category under its own heading, each with a real products grid. category.grid carries the same columns and styling as the main one, so there's no grid CSS to write.

<div className="foxr-bb-layout-root">
  {props.categories.map((category) => (
    <React.Fragment key={category.id}>
      {category.name && (
        <h3 className="my-category-heading">{category.name}</h3>
      )}
      {category.grid}
    </React.Fragment>
  ))}
 
  {props.slots.sidebar}
</div>

Two things to set up alongside it: stay on the All products tab so every category is on screen, and hide the tab bar with Custom CSS (.foxr-bb-tabs { display: none; }) if your sections replace it.

What Full layout doesn't change

The toastAlways rendered outside the layout, so a layout that never places it still shows add-to-bundle confirmations. It has its own template for markup changes.
What each piece looks likeThe Product card, Category tabs, and Sidebar templates still decide that. Full layout only decides where they go — and it picks up those templates automatically when they're active.
Per-product behaviorVariant selection, live pricing, and stock stay inside the card. You get the rendered element, not a copy of its state.

Combine it with the other templates

Full layout and the other four are independent. A common setup is Full layout to move the sidebar up top, plus Product card to restyle the cards — each doing the job it's built for.

On this page