Skip to main content

Collection provider

The CollectionProvider component holds the customer's filter and sort choices for a collection page in React and Vue apps, and keeps the choices in sync with the URL. Read the choices with useCollection, change filters and sort with useCollectionActions, and handle filter form submissions with useCollectionForm.

In frameworks without a Hydrogen binding, use createCollectionStore.

Import CollectionProvider, useCollection, useCollectionActions, and useCollectionForm from @shopify/hydrogen/react or @shopify/hydrogen/vue.


Props for CollectionProvider.

required

The collection handle and the search string that your loader fetched products for.

Anchor to children
children
ReactNode

Content that reads and changes collection state through the collection hooks.

Anchor to onChange
onChange
(searchString: string) => void

Receives the new search string after the customer changes filters or sort. Navigate to the search string with your router.

The search string starts with ?, or is empty when no params remain.

Anchor to urlSearch
urlSearch
string

Current URL search string from your router, with or without a leading ?. Defaults to an empty string. The provider reads the starting filters and sort from the string. When the string changes, including on back and forward navigation, the provider updates the filters and sort.

Examples

React

import { CollectionProvider } from "@shopify/hydrogen/react";
import type { ReactNode } from "react";
import { useNavigate, useSearchParams } from "react-router";

export function CollectionRoute({
handle,
dataSearch,
children,
}: {
handle: string;
dataSearch: string;
children: ReactNode;
}) {
const navigate = useNavigate();
const [searchParams] = useSearchParams();

return (
<CollectionProvider
data={{ handle, dataSearch }}
urlSearch={searchParams.toString()}
onChange={(search) =>
navigate({ search }, { replace: searchParams.size > 0, preventScrollReset: true })
}
>
{children}
</CollectionProvider>
);
}

Anchor to Filter and sort stateFilter and sort state

Returns the customer's filter and sort choices and the loading status, and re-renders the component when the state changes. The hook throws outside CollectionProvider.

With a selector, the hook returns the selected value and re-renders the component when the selected value changes. Pass an isEqual comparator to skip re-renders for equal values. The hook throws outside CollectionProvider.

Anchor to selector
selector
(state: ) => S

The function that derives the returned value from the collection state.

Anchor to isEqual
isEqual
(a: S, b: S) => boolean

The comparator that skips a re-render when it returns true for two derived values.

| S

The collection state, or the selector's value when you pass a selector.


Anchor to Filter and sort actionsFilter and sort actions

Anchor to useCollectionActions
useCollectionActions()

Returns methods that change the filters and sort. After each change, CollectionProvider passes the new search string to its onChange callback.

The hook throws outside CollectionProvider.

Methods that set, toggle, and reset filters, change the sort, and apply submitted filter forms.

Examples

React

import { useCollectionActions } from "@shopify/hydrogen/react";

export function BrowseControls() {
const { setSortByValue, toggleFilter, reset } = useCollectionActions();

return (
<div>
<button type="button" onClick={() => setSortByValue("price-descending")}>
Price, high to low
</button>
<button type="button" onClick={() => toggleFilter({ tag: "sale" })}>
On sale
</button>
<button type="button" onClick={() => reset()}>
Clear all
</button>
</div>
);
}

Anchor to useCollectionForm
useCollectionForm()

Returns props that make a collection filter form update the results without a full page load.

Spread the result of formProps() on the form. On submit, the props cancel the browser submission and apply the form's filter and sort fields. The beforeSubmit callback runs first, and calling preventDefault() in beforeSubmit skips the update. The afterSubmit callback runs after the update.

Render the form with method="get" and an explicit action, which keeps the form working before JavaScript loads. On search pages, keep q as a hidden input inside the form. The hook throws outside CollectionProvider.

Examples

React

import { useCollection, useCollectionForm } from "@shopify/hydrogen/react";

export function FilterForm({ collectionPath }: { collectionPath: string }) {
const state = useCollection();
const { formProps } = useCollectionForm();

return (
<form {...formProps()} method="get" action={collectionPath}>
<label>
<input
type="checkbox"
name="filter.p.tag"
value="sale"
checked={state.filters.some((filter) => filter.tag === "sale")}
onChange={(event) => event.currentTarget.form?.requestSubmit()}
/>
On sale
</label>
<noscript>
<button type="submit">Apply</button>
</noscript>
</form>
);
}

  • The provider takes a url-search prop, emits a change event with the search string, and renders its default slot.
  • useCollection returns a read-only shallow ref. The ref keeps updating when the customer moves to another collection.
  • The beforeSubmit and afterSubmit callbacks of useCollectionForm receive the native submit event.

Was this page helpful?