Throw redirects in data APIs with "use server" at the top of the file not working.
Hi everyone! 👋
I'm working on a Solid Start project and have a question about query behavior and redirects.
I have a query called getIdentity, which fetches user identity from cookies and db. The goal is to call this query on the /account page to check the user's identity. If no identity is found, I throw a redirect to /signin.
Here's the issue:
When I use "use server" in the query, the redirects work perfectly.
However, when I try to move the "use server"; to the top of the file (to prevent the identity-fetching logic from being bundled to the client), the redirects stop working.
I’d like to keep this logic at the top of the file, but I can’t figure out how to ensure the redirect still works.
Any ideas on how to handle this better? Is there a recommended pattern for managing such server-only logic and redirects in Solid Start?
Thanks in advance for your help! 🙏
4 Replies
I'm having a hard time visualizing what you are changing.
But just to get started: there isn't anything server side about
query
; it's an entirely client side mechanism (SSR aside). So
"use server"
acts on the function that is wrapped by query
:
query
is still calling a client side function but that function happens to be an RPC and the "use server" section only runs and exists on the server side as an RPC function (which short of a compilation bug should not appear in the client side bundle).
Given that I'm unsure what you mean by
I try to move the query to the top of the fileBecause I'm just imagining you moving the whole block which wouldn't move the
redirect
s inside the "use server"
block.I think I incorrectly explained it, I'll fix the initial post, I mean when I put the "use server"; at the top of the file, the redirect does not occur but when I put in in the function itself the redirect occurs.
I notice that on the client, the /_server route is called with some headers that point to the wrapped function, but that call does not return a redirect but a 200.
ie.
Redirect works in SSR and on client interactions but bundle all my private function and it dependencies in the cliente, I don't want that code to land on the client.
Redirect do not work on SSR and client interaction call /_server and return a
200
no private code is bundled.
I imagine now that I think more of this, that because I'm marking the entire module as server, the query itself also is being executed in the server when is intended to occur on the client. How do I do redirect in code I want only to run on the server without bundling dependencies of that code to the client.
If throw redirects in the route.load/preload functions the system just crash.I notice that on the client, the /_server route is called with some headers that point to the wrapped function, but that call does not return a redirect but a 200.That is the "use server" RPC request; you won't see an HTTP redirect there. Seroval serializes a
redirect
result. That is then thrown on the client side so that the router can catch it and initiate the navigation to the specified route.
I don't want that code to land on the client.The reason they are bundled is because you defined them in the "client space" of the module. To get around that move them to a server-only module (which doesn't need "use server" anywhere) and
import
them.
During the build process the functions with "use server"
wrapped by query
/action
are replaced, making it easy for the bundler to tree shake the unnecessary server import
s out.
"use server"
at the top of the file is generally discouraged even though it can be made to work-but you are correct; when "use server"
is at the top there shouldn't be any query
/action
in the module as those are strictly client-side concepts.This is helpful, thanks for the answers!