Add a search form in Remix with data fetching

Let's learn how to add a search form in Remix with data fetching.

import type { LoaderArgs } from "@remix-run/node";
import { Form, useLoaderData } from "@remix-run/react";
import { json } from "@remix-run/node";

type Product = {
  id: number;
  title: string;
  price: number;
  category: string;
};

export const loader = async ({ request }: LoaderArgs) => {
  // Fetch products from fakestoreapi.com
  const response = await fetch("https://fakestoreapi.com/products?limit=6");
  const products: Product[] = await response.json();

  // Get the query string from the request
  // query can be string or null
  const url = new URL(request.url);
  const query = url.searchParams.get("query");

  // Filter products if query is not null
  // In real world, you should use a database to filter products
  const productsFiltered = query
    ? products.filter((product) =>
        product.title.toLowerCase().includes(query?.toLowerCase() || "")
      )
    : products;

  // Return the filtered products
  return json({ products: productsFiltered, query });
};

export default function Products() {
  // Get the products from the loader
  const { products, query } = useLoaderData<typeof loader>();

  return (
    <>
      <h1>Products</h1>

      {/* Add a search form */}
      <Form method="get">
        <input type="text" name="query" defaultValue={query || ""} />
        <button type="submit">Search</button>
      </Form>

      {/* Display the products */}
      <ul>
        {products.map((product) => (
          <li key={product.id}>
            <h2>{product.title}</h2>
            <p>{product.price}</p>
            <p>{product.category}</p>
          </li>
        ))}
      </ul>
    </>
  );
}

Let's break down important parts of the code.

The loader function is responsible for fetching data from the API and returning it to the component.

When user submits the search form, the query string is added to the URL.

For example http://localhost:3000/products?query=shirt.

We can access the query string from the loader function using the request object like this.

export const loader = async ({ request }: LoaderArgs) => {
  const url = new URL(request.url);
  const query = url.searchParams.get("query");
  ...
};

Now you can use the query string to filter products based on the search query.

More Articles

  1. Use Remix Action to handle form submission
  2. Use Remix Loader to fetch data from an external API
  3. Validating form data in Remix using Zod and Action function
  4. Add a search form in Remix with data fetching
  5. Show a flash message in Remix after form submission
  6. Discover the best SaaS Starter Kits based on Remix