shopify storefront search with graphql in Remix React
shopify storefront search with graphql in Remix React
I am new to Remix React projects, hence I'm having a difficult time understanding the structure of the project. I am trying to create a SearchBar Component in the Header and return the first 10 products related to user input. Here is my relevant Search Component code in the Header Component:
function SearchForm() {
const SEARCH_PRODUCTS_QUERY = `
query SearchProducts($query: String!) {
products(query: $query, first: 10) {
edges {
node {
id
title
handle
description
}
}
}
}
`;
const [searchTerm, setSearchTerm] = useState('');
const [searchResults, setSearchResults] = useState([]);
function handleSearch() {
// console.log('handle search', searchTerm);
}
return (
<div>
<input
type="text"
placeholder="search"
value={searchTerm}
onChange={(event) => setSearchTerm(event.target.value)}
/>
<button type="button" onClick={handleSearch}>
Search
</button>
<ul>
{searchResults.map((product) => (
<li key={product.node.id}>{product.node.title}</li>
))}
</ul>
</div>
);
}
I am just rendering this inside the Header Component. I am not sure if I should handle the query here. Cause I think I need the API endpoints and such to get the response body. How can I implement the handleSearch function to make it work? Is the query supposed to be in here?
You should probably consider using the Full Stack Component pattern. https://www.epicweb.dev/full-stack-components
Create a resource route, then export a loader that does the query and returns the results.
Export your SearchForm component that will call the resource endpoint and renders the UI.
Then you can import the SearchForm component in your Header.
// routes/resource.search-form.tsx
export async function loader({ request }: DataFunctionArgs) {
const url = new URL(request.url)
const query = url.searchParams.get('query')
const results = await doSearch(query)
return json(results)
}
export function SearchForm() {
const fetcher = useFetcher<typeof loader>()
return (
<div>
<fetcher.Form method="get" action="/resource/search-form">
<input type="text" name="query" placeholder="search" />
<button>Submit</button>
</fetcher.Form>
{fetcher.data && (
<ul>
{fetcher.data.map((product: any) => (
<li key={product.node.id}>{product.node.title}</li>
))}
</ul>
)}
</div>
)
}
December 30, 2023
Turbo Multi-language Translator
Make the better internet purchasing globaly
Turbosify SEO Speed Booster
5.0 (7)•Free plan available
Get better conversions by improving store loading speed
Installed
Turbo Multi-language Chat - AI Customer service in one hand
December 30, 2023