Theme slots
Slots are named injection points in the storefront layout where plugins contribute UI blocks. The full list of well-known slot names is exported as SLOT_NAMES from app/core/themes/index.server.js.
SLOT_NAMES
Section titled “SLOT_NAMES”| Slot name | Location in the storefront |
|---|---|
home.hero |
Hero area at the top of the home page, above main content |
home.featured |
Featured section on the home page, below the hero |
product.afterDescription |
Below the product description on the product detail page |
product.sidebar |
Sidebar column on the product detail page |
category.top |
Above the product grid on category listing pages |
cart.summary |
Inside the cart summary panel |
checkout.afterPayment |
Below the payment fields in the checkout flow |
account.dashboard |
Inside the customer account dashboard |
layout.header |
Inside the global site header (rendered by theme Layout) |
layout.footer |
Inside the global site footer (rendered by theme Layout) |
The default theme renders all 10 of these slots. Route loaders fetch blocks server-side and pass a slotBlocks map into the theme component or shell that owns the slot. Storefront _layout.jsx loads layout.header and layout.footer for theme chrome; page-owned slots are loaded in the corresponding page loaders.
Rendering slot blocks
Section titled “Rendering slot blocks”Themes render slots by calling getSlotBlocks(slotName) or getSlotBlocksMap(slotNames) and mounting each returned { pluginId, component } entry. The shared SlotBlocks component in app/components/slot-blocks/index.jsx accepts optional slotProps, which are spread into every plugin block so blocks can receive page-specific data like product, cart, category, or checkout state.
import SlotBlocks from '#/components/slot-blocks';
<SlotBlocks blocks={slotBlocks['product.afterDescription']} slotProps={{ product, locale, currency }}/>Blocks only render when the contributing plugin is enabled. Order follows pluginOrder ∩ enabledPlugins. See getSlotBlocks and getSlotBlocksMap in the theme API.
Page context
Section titled “Page context”Prefer loadStorefrontPageContext(request) from #/core/storefront/page-context.server. It returns { themeId, locale, currency, themeSettings } by resolving the active theme (preloadStorefrontTheme), request locale, and request currency in parallel, then loading persisted settings for the active theme manifest (loadThemeSettings). When the theme has no settings schema (or is unregistered), themeSettings is {}.
Pass themeId into getStorefrontComponent(name, themeId). Pass themeSettings (and other loader fields) as props to the theme page component. Do not resolve the active theme again in the route component.
import { loadStorefrontPageContext } from '#/core/storefront/page-context.server';import { getStorefrontComponent } from '#/core/themes/storefront-components';
export async function loader({ request }) { const { themeId, locale, currency, themeSettings } = await loadStorefrontPageContext(request); return { themeId, locale, currency, themeSettings /* … */ };}
export default function SomeRoute() { const { themeId, ...data } = useLoaderData(); const HomePage = getStorefrontComponent('HomePage', themeId); if (!HomePage) throw new Error('HomePage theme component not found'); return <HomePage {...data} />;}