Skip to content

Examples

Simple

Intercepting clicks on links, displaying a loader and updating the targets' content.

Fetch from any element

Fetch normally reads its URL from an <a href> or <form action>, but the src option lets it be driven from any element and triggered programmatically. In the following example the panel is a <div>: it combines Fetch with the InViewOnce and Action components so that its content is lazy-loaded the first time it scrolls into view, with a bare Fetch.fetch() call that resolves the src URL on its own.

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.

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 by adding the comma-separated sections parameter (up to five) to the URL:

html
<a
  href="{{ collection.url }}?sort_by=price-ascending&sections=main-collection-product-grid,collection-results-count"
  data-component="Fetch"
  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 form data is automatically appended to the URL, so you only need to add a hidden <input name="sections">.