> ## Documentation Index
> Fetch the complete documentation index at: https://docs.supercycle.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Availability search

> Let customers filter a collection by rental dates or method, and drive the filter from your own code

<Info>
  The Availability search app block needs the [Supercycle Engine app embed](/documentation/setup/theme-setup) turned on in your theme. If your theme doesn't support app blocks on collection pages, add the filter with the Liquid snippet at the end of this page.
</Info>

The Availability search app block lets customers filter a collection page by the dates they want, or by method. It works with Shopify's [Search & Discovery](https://help.shopify.com/en/manual/online-store/search-and-discovery) app, using Supercycle's metafields and the browser's session storage to decide which products show. For the merchant setup, see [Filter by availability](/documentation/online-store/search).

<Frame type="glass" caption="The block's three layouts: a Search button, a round search icon, and an extra Size field">
  <img src="https://mintcdn.com/supercycle/XbKBsdX_PulItpyX/images/app-blocks/availability/availability-search.png?fit=max&auto=format&n=XbKBsdX_PulItpyX&q=85&s=a123f8d6abd6b4b6c3bec04ee807d505" alt="The Availability search app block in three layouts: start and end date fields with a Search button, the same fields with a round search icon, and a version with an extra Size field" width="1794" height="1190" data-path="images/app-blocks/availability/availability-search.png" />
</Frame>

***

## How it works

The block writes its state to session storage and re-renders the collection section from it. Your own code can read and write the same keys, so a date picker anywhere on the site can drive the filter.

### Session storage keys

<ParamField path="filterMode" type="string | null">
  The active filter. One of `"calendar"`, `"membership"`, `"subscription"`, or `"resale"`. Set it to `null` to clear every filter and show all products.
</ParamField>

<ParamField path="scaf-dates" type="object | null">
  The selected date range for calendar mode. Only read when `filterMode` is `"calendar"`.

  <Expandable title="properties">
    <ParamField path="start_date" type="string" required>
      An ISO 8601 date string, for example `"2025-06-01T00:00:00.000Z"`.
    </ParamField>

    <ParamField path="end_date" type="string" required>
      An ISO 8601 date string, for example `"2025-06-07T00:00:00.000Z"`.
    </ParamField>
  </Expandable>
</ParamField>

### Write filter state from your own code

Values are stored as JSON strings. Use this helper to write a key and notify the block. You can inspect the current values in your browser's developer tools under **Application > Session Storage**.

```javascript Set filter state theme={null}
function setFilterState(key, value) {
  const serialized = JSON.stringify(value);
  sessionStorage.setItem(key, serialized);
  window.dispatchEvent(new StorageEvent("storage", {
    key: key,
    newValue: serialized,
    storageArea: sessionStorage
  }));
}

// Activate a mode
setFilterState("filterMode", "membership");
setFilterState("filterMode", "subscription");
setFilterState("filterMode", "resale");
setFilterState("filterMode", "calendar");

// Clear all filters
setFilterState("filterMode", null);
```

### Set a date range

Calendar mode reads the range from `scaf-dates`:

```javascript Set a date range theme={null}
setFilterState("scaf-dates", {
  start_date: new Date("2025-06-01").toISOString(),
  end_date: new Date("2025-06-07").toISOString()
});
setFilterState("filterMode", "calendar");
```

### Read the current state

```javascript Read filter state theme={null}
const mode = JSON.parse(sessionStorage.getItem("filterMode"));
// "calendar" | "membership" | "subscription" | "resale" | null

const dates = JSON.parse(sessionStorage.getItem("scaf-dates"));
// { start_date: "2025-06-01T00:00:00.000Z", end_date: "2025-06-07T00:00:00.000Z" } | null
```

### JavaScript hooks

<ParamField path="window.supercycleAfterSectionRender" type="function">
  Called each time the collection section re-renders after a filter is applied. Use it to re-initialize third-party scripts or sync a custom UI to the current state. Define it before the block initializes.
</ParamField>

```javascript After each render theme={null}
window.supercycleAfterSectionRender = function() {
  const mode = JSON.parse(sessionStorage.getItem("filterMode"));
  // Re-initialize your UI here
};
```

### Metafields the filter reads

Supercycle sets these [metafields](/developers/metafields) automatically. You can inspect them under <Icon icon="shopify" iconType="solid" /> **[Custom data](https://admin.shopify.com/settings/custom_data)** in the Shopify admin.

* **`supercycle.methods`.** The product's methods: `Calendar`, `Membership`, `Subscription`, or `Resale`. Filters products by method.
* **`supercycle.uncommitted_inventory`.** Set when a variant has stock not committed to an active rental. Used by the membership, subscription, and resale filters.
* **`supercycle.future_availability_inventory`.** Set when a variant has availability on future dates. Used by the calendar filter.

### Drive the filter from a home page date picker

A date picker in a home page hero that sends customers to the collection page with calendar mode already active. The block on the collection page reads the saved session storage on load and applies the filter.

```html Home page hero theme={null}
<div id="sc-hero-search">
  <label>
    From
    <input type="date" id="sc-start" />
  </label>
  <label>
    To
    <input type="date" id="sc-end" />
  </label>
  <button id="sc-search">Check availability</button>
</div>

<script>
  var today = new Date().toISOString().slice(0, 10);
  document.getElementById("sc-start").min = today;
  document.getElementById("sc-end").min = today;

  document.getElementById("sc-start").addEventListener("change", function() {
    document.getElementById("sc-end").min = this.value;
    if (document.getElementById("sc-end").value < this.value) {
      document.getElementById("sc-end").value = "";
    }
  });

  document.getElementById("sc-search").addEventListener("click", function() {
    var start = document.getElementById("sc-start").value;
    var end = document.getElementById("sc-end").value;
    if (!start || !end) return;

    sessionStorage.setItem("filterMode", JSON.stringify("calendar"));
    sessionStorage.setItem("scaf-dates", JSON.stringify({
      start_date: new Date(start).toISOString(),
      end_date: new Date(end).toISOString()
    }));

    // Change this URL to your store's collection
    window.location.href = "/collections/all";
  });
</script>
```

***

## Add the filter to a custom or legacy theme

If your theme doesn't support app blocks on collection pages, add the filter to the collection template.

<Steps>
  <Step title="Open the collection template">
    On <Icon icon="shopify" iconType="solid" /> **[Themes](https://admin.shopify.com/themes)**, open your theme's **... > Edit code** menu, then open the file your theme uses for collections: `sections/main-collection.liquid`, `sections/collection-template.liquid`, or `templates/collection.liquid`.
  </Step>

  <Step title="Paste the filter component">
    Add the snippet wherever you want the filter to appear, usually above the product grid.

    ```liquid Collection template theme={null}
    <x-availability-filter data-settings='{
      "enable_calendar": true,
      "enable_membership": true,
      "enable_subscription": true,
      "enable_resale": true,
      "collections_section_id": "",
      "custom_css": ""
    }'></x-availability-filter>

    {% render 'vite-tag' with 'methods-filter.jsx' %}
    ```
  </Step>

  <Step title="Set the collection section ID">
    Paste your collection section's ID into `collections_section_id`. It lets the filter re-render the product grid without a full page reload. See [Filter by availability](/documentation/online-store/search#find-your-collection-section-id) for how to find it.
  </Step>

  <Step title="Turn off methods you don't offer (optional)">
    Set any of `enable_calendar`, `enable_membership`, `enable_subscription`, or `enable_resale` to `false` to hide that filter.
  </Step>

  <Step title="Save and test">
    Save, then preview a collection that contains products with methods turned on to confirm the filter appears and filters the grid.
  </Step>
</Steps>
