DEV Community

Alex Spinov
Alex Spinov

Posted on

Remix Has a Free API That Makes Web Standards the Best Framework Feature

Remix is the React framework that embraces web standards. Forms, cookies, headers, streams — everything uses the platform APIs you already know.

Loaders: Server-Side Data

import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";

export async function loader({ request }) {
  const url = new URL(request.url);
  const search = url.searchParams.get("q");
  const products = await db.product.findMany({
    where: search ? { title: { contains: search } } : {},
    take: 20,
  });
  return json({ products, search });
}

export default function Products() {
  const { products, search } = useLoaderData();
  return (
    <Form method="get">
      <input name="q" defaultValue={search} />
      {products.map(p => <div key={p.id}>{p.title}</div>)}
    </Form>
  );
}
Enter fullscreen mode Exit fullscreen mode

Actions: Mutations via Forms

export async function action({ request }) {
  const formData = await request.formData();
  await db.product.create({
    data: {
      title: formData.get("title"),
      price: Number(formData.get("price")),
    },
  });
  return redirect("/products");
}
Enter fullscreen mode Exit fullscreen mode

No useState. No useEffect. No client-side state management. Just forms.

Nested Routes: Parallel Loading

Routes are files. Nested routes load data in parallel:

app/routes/
  _index.tsx
  products.tsx         (layout)
  products._index.tsx  (list)
  products.$id.tsx     (detail)
Enter fullscreen mode Exit fullscreen mode

Streaming with defer

import { defer } from "@remix-run/node";
import { Await } from "@remix-run/react";

export async function loader() {
  return defer({
    critical: await db.product.findFirst(),
    slow: db.analytics.getReport(), // Not awaited!
  });
}
Enter fullscreen mode Exit fullscreen mode

Error Boundaries per Route

export function ErrorBoundary() {
  const error = useRouteError();
  if (isRouteErrorResponse(error)) {
    return <div>{error.status}: {error.statusText}</div>;
  }
  return <div>Something went wrong</div>;
}
Enter fullscreen mode Exit fullscreen mode

Build data-driven Remix apps? My Apify tools feed scraped data into your loaders.

Custom solution? Email spinov001@gmail.com

Top comments (0)