API requests

Learn how to make requests to your Remix API in Makerkit

To make requests to the API functions in the api folder, we provide a custom hook useApiRequest, a wrapper around fetch.

It has the following functionality:

  1. Uses an internal state to keep track of the state of the request, like loading, error and success. This helps you write fetch requests the "hooks way"
  2. Automatically adds a Firebase AppCheck Token to the request headers if you enabled Firebase AppCheck
  3. Automatically adds a CSRF token to the request headers

Similarly to making Firestore Requests, it's a convention to create a custom hook for each request for readability/reusability reasons.

import useApiRequest from '~/core/hooks/use-api';
interface Body {
  idToken: string;
export function useCreateSession() {
  return useApiRequest<void, Body>('/api/session/sign-in');

The hook returns an array with:

  1. the callback to make the request
  2. the state object of the request
const [createSession, createSessionState] = useCreateSession();

The state object internally uses useApiRequest, and has the following interface:

  success: boolean;
  loading: boolean;
  error: string;
  data: T | undefined;

When success is true, the property data is inferred with its correct type.

You can use this hook in your components:

import { useCreateSession } from '~/core/hooks/use-create-session';
function Component() {
  const [createSession, createSessionState] = useCreateSession();
  return (
      { createSessionState.loading ? `Loading...` : null }
      { createSessionState.error ? `Error :(` : null }
      { createSessionState.success ? `Yay, success!` : null }
      <SignInForm onSignIn={(idToken) => createSession({ idToken })} />

Similarly, you can also use it to fetch data:

import { useCreateSession } from '~/core/hooks/use-create-session';
function Component() {
  const [fetchMembers, { loading, error, data }]
    = useFetchMembers();
  // fetch data when the component mounts
  useEffect(() => {
  }, [fetchMembers]);
  if (loading) {
    return <div>Fetching members...</div>;
  if (error) {
    return <div>{error}</div>;
  return (
      {data.map(member => <MemberItem member={member} />)}

Subscribe to our Newsletter
Get the latest updates about React, Remix, Next.js, Firebase, Supabase and Tailwind CSS