Skip to content

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:

html
<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>
json
{
  "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 as null (for example a section absent from the published theme) so the parser only receives valid HTML.
  • The JSON keys are ignored: Fetch matches each section by the id of its shopify-section-* wrapper, so there is never a key/id mismatch.
  • Keep the default replace mode (or use morph) so each section is swapped in place — append and prepend insert the new markup inside the existing shopify-section-{id} wrapper and would duplicate its content. This works together with the history and viewTransition options.

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.