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,
});
}
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)
.