Examples
Simple
Intercepting clicks on links, displaying a loader and updating the targets' content.
Fetch from any element
A link or a form gives Fetch its destination. Any other element requests the endpoint of the src option when fetch() is called. In the following example the panel is a <div>: it combines Fetch with the InViewOnce and Action components, so its content is loaded the first time it scrolls into view, with a bare Fetch.fetch() call.
Form
In the following example, we intercept a form submission, display a loader and use a custom view transition to animate only the updated content once the request is finished.
Pagination
A set of submit buttons is a paginator with no script of its own: each button sends its own page value, and the hidden orderby field travels with every submission. The params option adds the template of the results to every request, so it never reaches the address bar. With the history option, each page is a history entry that back and forward restore. See forms.
Back and forward
The preview runs in a frame with no address of its own, so Fetch writes no history entry there. On a page, the second button writes ?orderby=title&page=2, and back requests page 1 again with the same params.
Modes
Modes are configured with the data-option-mode attribute.
Add to cart / Quickbuy
Error handling
Cancelling a request
Use the abort method to cancel a request. In the following example, we use the Action component to cancel any pending request from any mounted Fetch component.
TIP
In this example, we could use a more specific version of the data-option-target attribute of the Action component to target a single Fetch instance.
Shopify Section Rendering API
Shopify's Section Rendering API returns the rendered HTML of specific theme sections as a JSON object: each key is a requested section ID and each value is that section's HTML — or null when the section fails to render. Because every section is wrapped in a <div id="shopify-section-{id}"> element both on the page and inside the API response, the Fetch component can consume it without any extra code: parse the JSON with the response option and let the default [id] selector swap each section in place.
TIP
The FetchShopifySection component wraps this pattern: it declares the sections through a sections option (keeping them out of the href for a working no-JS fallback) and ships the JSON extraction below as its default, so you don't repeat it on every element.
Request the sections to update with the comma-separated sections parameter (up to five). Set it with the params option, so the href stays a working link without JavaScript and the parameter never reaches the address bar:
<a
href="{{ collection.url }}?sort_by=price-ascending"
data-component="Fetch"
data-option-params='{"sections": "main-collection-product-grid,collection-results-count"}'
data-option-response="response.json().then((sections) => Object.values(sections).filter(Boolean).join(''))">
Sort by price
</a>
{% comment %} These wrappers, rendered by Shopify, are what Fetch swaps by id. {% endcomment %}
<div id="shopify-section-main-collection-product-grid">…</div>
<div id="shopify-section-collection-results-count">…</div>{
"main-collection-product-grid": "<div id=\"shopify-section-main-collection-product-grid\" class=\"shopify-section\">…</div>",
"collection-results-count": "<div id=\"shopify-section-collection-results-count\" class=\"shopify-section\">…</div>"
}filter(Boolean)drops any section returned asnull(for example a section absent from the published theme) so the parser only receives valid HTML.- The JSON keys are ignored:
Fetchmatches each section by theidof itsshopify-section-*wrapper, so there is never a key/id mismatch. - Keep the default
replacemode(or usemorph) so each section is swapped in place —appendandprependinsert the new markup inside the existingshopify-section-{id}wrapper and would duplicate its content. This works together with thehistoryandviewTransitionoptions.
TIP
Use a <form method="get"> instead of a link when the parameters come from user input (facet filters, a sort <select>, a search field): the fields become the query of the request, and the params option adds sections to it. No hidden <input name="sections"> is needed.