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:
instantProducts: defineInstantProducts(), 
The instantProducts controller displays relevant products in real time as users type in the search box. |
Next, incorporate the controller into your existing search box component to seamlessly integrate instant product features into the search experience.
// app/components/StandaloneSearchBoxWithInstantProducts.tsx
import {useNavigate} from '@remix-run/react';
import {useEffect, useRef} from 'react';
import {
useInstantProducts,
useStandaloneSearchBox,
} from '~/lib/commerce-engine';
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 StandaloneSearchBoxWithInstantProducts() {
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, navigate]);
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 type="button" onClick={searchBox.methods?.submit}>
Search
</button>
{searchBox.state.suggestions.length > 0 && (
<div>
{searchBox.state.suggestions.map((suggestion) => (
<button
type="button"
key={suggestion.rawValue}
onClick={() => handleSuggestionClick(suggestion.rawValue)}
>
{suggestion.highlightedValue}
</button>
))}
</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>
);
}
Instant products annotations
Create a custom hook to update the InstantProducts controller state whenever the search box suggestions change. This occurs when the user types in the search box. |
|
Use the useInstantProducts hook to access the InstantProducts controller. |
|
Use the custom hook to sync the InstantProducts controller with the search box. |
|
Display the instant products by iterating through the instantProducts.state.products array. |