Use the Section Rendering API for dynamic updates
Use the Section Rendering API to fetch and update specific theme sections through Ajax without a full page reload.
Without the Section Rendering API, updating page content requires a full page reload, which redownloads and re-renders the entire page. This wastes bandwidth and creates slow, jerky user experiences. The Section Rendering API requests only the sections that changed, allowing targeted updates that feel instant and improving metrics for subsequent pages.
Anchor to Basic usageBasic usage
Request sections using the sections query parameter on any page URL:
Requesting more than five sections returns 400 Bad Request and renders nothing.
Response format:
Anchor to Find section IDsFind section IDs
You can find section IDs in two ways.
Using Liquid:
From the section wrapper in HTML:
Static sections use their filename as the ID: header.liquid maps to header, and footer.liquid maps to footer.
Sections in JSON templates and section groups get a dynamic ID instead, such as template--123__product-info. Requesting one of those by filename doesn't return the configured section. If a section file with that name exists, then the server renders it statically with default settings, and if it doesn't, then the request fails. On a typical Online Store 2.0 product or collection template, that means a filename-style ID replaces configured page content with default markup or nothing at all. Read the ID from {{ section.id }} or from the section wrapper instead of hardcoding it.
Anchor to Render sections in different contextsRender sections in different contexts
Sections render in the context of the page URL. You can specify any page context. Read the rendered section ID from the section element rather than hardcoding a filename. Each of the following examples runs on a page that already renders the section it requests:
The section ID must exist in the template that renders for the URL you request. A product section ID works for another product that uses the same template, but it doesn't work against a collection or search URL.
Anchor to Optimistic cart renderingOptimistic cart rendering
When a customer adds a product to the cart, the cart drawer typically opens but shows nothing until the server responds with the Section Rendering API result. You can make add-to-cart feel instant by rendering the cart drawer optimistically with data already available on the product page.
The approach: immediately insert the added item into the cart drawer using product data from the PDP (title, variant, price, image, quantity), then reconcile when the server response arrives. This decouples perceived UI responsiveness from server processing time.
The server response reconciles any differences, such as discount pricing, stock changes, or cart-level promotions that only the server knows about.
Anchor to Bundled section rendering with the Cart APIBundled section rendering with the Cart API
The Cart API supports bundled section rendering, so that you can update multiple sections after cart modifications:
Anchor to Use locale-aware URLsUse locale-aware URLs
When building Section Rendering API requests, use locale-aware URLs to maintain the customer's selected language and region:
Anchor to Single section request (alternative)Single section request (alternative)
For a single section, you can use the section_id parameter. It returns HTML directly instead of JSON:
This returns a 404 if the section doesn't exist. The 404 applies only to the section_id path. A nonexistent section ID inside ?sections= is null in an otherwise successful 200 response, so requesting several sections at once never fails outright because of one bad ID.
<script> tags in the returned HTML don't execute when you insert them with innerHTML, DOMParser, or replaceWith. You must bind any behavior that the section needs outside the replaced markup, either by delegating events from an ancestor that's never replaced, or by wrapping the section in a custom element and re-initializing in connectedCallback().
<script> tags in the returned HTML don't execute when you insert them with innerHTML, DOMParser, or replaceWith. You must bind any behavior that the section needs outside the replaced markup, either by delegating events from an ancestor that's never replaced, or by wrapping the section in a custom element and re-initializing in connectedCallback().
Anchor to ExamplesExamples
Anchor to Variant selectionVariant selection
Update product details when a customer selects a different variant:
sections/product-info.liquid
Scope every query to the section container. A bare document.querySelectorAll('input[name]') also matches search, newsletter, and quantity inputs elsewhere on the page.
For a component-based alternative, see how Dawn's variant-selects custom element binds its change listener in connectedCallback(), so the listener re-attaches automatically each time the element is replaced.
Anchor to Error handlingError handling
In a ?sections= request, sections that fail to render or don't exist come back as null inside a 200 response. Always account for this:
Anchor to TestingTesting
- Browser DevTools Network tab: Verify that only sections are fetched, not full pages.
- Compare sizes: Check the network payload. The section response should be smaller than a full page.
- User experience: Interactions should feel instant with no page flash.
Anchor to ReferencesReferences
section.idproduct.titleproduct.selected_or_first_available_variantproduct.options_with_valuesproduct_option_valueobjectmoneyfilterescapefilterfortagiftag- Section Rendering API
- Ajax API
- Bundled section rendering with Cart API
- Avoid over-fetching product variants
- Defer child product loading in combined listings
- Limit pagination depth