October 30, 2026 · Muhammad Umar · More by Muhammad Umar
Shopify's Section Rendering API: The Null-in-200 Trap
Shopify's Section Rendering API caps requests at five sections and can return a failed section as null inside an HTTP 200 — here's how to handle both correctly.

A Lighter Way to Update Part of a Page
Shopify's Section Rendering API lets a theme request the rendered HTML of specific sections through a plain AJAX request, so a page can update its search results or a filtered collection grid without a full reload. It's a lighter-weight alternative to pulling in Hydrogen or a client-side framework for cases that don't need one — you request a page URL with a sections query parameter, and get back the rendered markup for just the sections you asked for. The reference documents a few constraints that are easy to miss until they surface as a production bug.
The Five-Section Cap
The sections parameter — passed as a comma-separated list or an array — renders up to five sections per request, identified by their section IDs. The response is a JSON object keyed by each section ID, with that section's rendered HTML as the value. There's no documented way to raise that limit: if a pagination or filtering flow needs to refresh more than five independent sections at once, it needs multiple requests or a different mechanism.
Section IDs come from one of two places: a static section's file name (a social.liquid section has the ID social), or a dynamic ID assigned when the section lives inside a JSON template or section group — shaped like sections--1234__header or template--5678__image_banner — generated so that no two sections of the same type collide.
Null Inside a 200, and a Different Story for section_id
This is the failure mode worth designing around: a section that fails to render — including one that simply doesn't exist on the published theme — comes back as null inside the JSON response, not as an error status. The HTTP response can be a clean 200 while one or more of the requested sections silently failed. Checking the status code alone doesn't tell you the request worked; the caller has to inspect each key in the response body for null.
The section_id parameter, used to request a single section, behaves differently in both directions. It returns the section's HTML directly instead of a JSON object, and if the requested section doesn't exist on the theme, the server responds with an actual 404 — not a 200 with a null payload. Code written against one parameter's failure semantics will mishandle the other if reused without changes.
One more limit applies to both: neither parameter lets you pass section setting values through the request. If the section already exists in a template or is statically rendered, its existing settings apply; otherwise, the section's schema defaults are used. There's no override path.
Building Locale-Aware Requests
Sections render in the Liquid context of whatever page URL they're attached to, including a product or collection page's own data. For stores selling in multiple languages or countries, that URL should never be hardcoded — Shopify exposes window.Shopify.routes.root as a locale-aware base for building the request in JavaScript, or window.location.pathname to render in the context of the current page. Either gives visitors a result consistent with the language and country they've already chosen, which a fixed path can silently break for anyone outside the store's default locale.