javascripttypescriptreact-routersingle-page-applicationremix

API route in react-router v7 SPA always throws an error


I currently have a React Router v7 application running in SPA mode. I wanted to make an API route that uses a clientAction to submit data to an endpoint. If I use the useSubmit hook, I can successfully POST to that client action. But if I use the native fetch api then I get an error from react-i18next reading TypeError: i18n.dir is not a function. In my logs I see Error: You made a POST request to "/api-sammi" but did not provide an action for route "routes/api-sammi", If I include logging, I can confirm that the clientAction is never reached.

I think this might be a limitation to SPA mode but I can't find anything in the docs that support that theory. If anyone can point me in the right direction please let me know!

**_app/projects/test/route.tsx**

export default function Component() {
  return (
    <>
      <Button
        onPress={() => {
          void fetch(`/api-test`, {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
              message: "Hello, world!",
            }),
          });
        }}
      >
        {"Validate Data"}
      </Button>
    </>
  );
}
**api-test/route.ts**

export async function clientAction({ request }: ClientActionFunctionArgs) {
  console.log("Received request:", request);
  const body = await request.json();
  console.log("Received request body:", body);

  return Response.json({
    message: "Hello, world!",
    received: body,
    success: true,
  });
}

Solution

  • In SPA mode, React Router v7 does not create actual network API endpoints for clientAction or clientLoader.

    Those functions only exist inside the client-side router, so they can only be triggered with React Router’s data APIs (<Form>, useSubmit, fetcher.submit).

    The regular fetch would work only for your RESTAPIs and not the routes in React Router v7. When you call fetch("/api-test") in SPA mode, the browser makes a real network request. There’s no server route at /api-test, so React Router falls back to trying to match a route and throws the error.

    You can only use any of the following (<Form>, useSubmit, fetcher.submit).