Display instant products (Shopify Hydrogen)
Display instant products (Shopify Hydrogen)
Instant products enhance the search experience by displaying relevant products in real time as users type in the search box.

To display instant products, you can use the InstantProducts
controller.
To implement, first, define the controller:
// lib/commerce-engine-config.ts
import {
defineInstantProducts,
// ...
} from '@coveo/headless-react/ssr-commerce';
export default {
// ...
controllers: {
instantProducts: defineInstantProducts(),
// ...
},
} satisfies CommerceEngineDefinitionOptions;
Next, incorporate the controller into your existing search box component to seamlessly integrate instant product features into the search experience.
import {useEffect, useRef} from 'react';
import {useStandaloneSearchBox, useInstantProducts} from '~/lib/commerce-engine.ts';
import {useNavigate} from '@remix-run/react';
function useUpdateInstantProducts(
searchBox: ReturnType<typeof useStandaloneSearchBox>,
instantProducts: ReturnType<typeof useInstantProducts>,
) {
useEffect(() => {
if (searchBox.state.suggestions[0]) {
instantProducts.methods?.updateQuery(
searchBox.state.suggestions[0]?.rawValue,
);
}
}, [searchBox.state.suggestions, instantProducts.methods]);
}
export function StandaloneSearchBox() {
const searchBox = useStandaloneSearchBox();
const inputRef = useRef<HTMLInputElement>(null);
const navigate = useNavigate();
const instantProducts = useInstantProducts();
useUpdateInstantProducts(searchBox, instantProducts);
useEffect(() => {
inputRef.current?.focus();
}, []);
useEffect(() => {
if (searchBox.state.redirectTo === '/search') {
navigate(
`${searchBox.state.redirectTo}?q=${encodeURIComponent(
searchBox.state.value
)}`
);
}
}, [searchBox.state.redirectTo, searchBox.state.value]);
const handleSuggestionClick = (suggestion: string) => {
searchBox.methods?.updateText(suggestion);
inputRef.current!.value = suggestion;
searchBox.methods?.showSuggestions();
};
return (
<div>
<input
ref={inputRef}
aria-label="Search"
placeholder="Search"
onChange={(e) => searchBox.methods?.updateText(e.target.value)}
onFocus={() => searchBox.methods?.showSuggestions()}
/>
<button onClick={searchBox.methods?.submit}>Search</button>
{searchBox.state.suggestions.length > 0 && (
<div>
{searchBox.state.suggestions.map((suggestion) => (
<button
key={suggestion.rawValue}
onClick={() => handleSuggestionClick(suggestion.rawValue)}
dangerouslySetInnerHTML={{__html: suggestion.highlightedValue}}
/>
))}
</div>
)}
{searchBox.state.suggestions.length > 0 && instantProducts.state.products.length > 0 && (
<div>
{instantProducts.state.products.map((product) => (
<div key={product.ec_product_id}>
<h2>{product.ec_name}</h2>
</div>
))}
</div>
)}
</div>
);
}
Create a update the state of the InstantProducts controller via the updateQuery method whenever the state.suggestions value changes on the search box.
This occurs when the user types in the search box. |
|
Use the useInstantProducts hook to access the InstantProducts controller. |
|
Use the useUpdateInstantProducts hook defined above, to sync the state of the InstantProducts controller with the search box. |
|
Display the instant products by iterating through the instantProducts.state.products array. |
Was this article useful?
Thanks for your feedback!