How to Execute Server Action on Each Route Visit?
I have a home component (code in comments)
In summary, what this component does is it calls a server action to check if the user is authenticated. If the user is authenticated, it redirects the user to the dashboard route. Otherwise, it redirects the user to the login route.
Now, here's my question. What I want to do is perform this verification every time the home route is visited (even from a client-side redirect). From my logs however, it doesn't look like the server action is being called in subsequent visits to this route (i.e. after the account setup process is complete. The reason I know this is because "Executing checks to determine redirect" is being printed on my console. But, none of the other logs that would be printed if the action completed are. In other words
authenticatedUser.result
is always falsy. How would I go about doing what I am trying to do? Is there a different approach I should be taking to accomplish what I am trying to do?
Thanks. Like I said, component code is in the first comment of this thread.9 Replies
Here's the code:
For clarification: The action is being executed on the initial page load. However, it isn’t being executed in subsequent visits to the route. Like if you directly enter “my site.com” this route would load and the action would execute. However, if you
navigate(“/“)
from some other component, the action doesn’t execute.
What I am trying to accomplish is to get the action to execute event when the route is loaded via a navigate()
call from some other part of my app.Did you review how the example does it?
The only "downside" is that the user information is considered fresh for 10 seconds but I believe that could be mitigated by feeding the server function directly to the
createAsync
.
To me using an action for this feels like using POST
when I should be using GET
.GitHub
solid-start/examples/with-auth/src/routes/index.tsx at 678d9acbc0bb...
SolidStart, the Solid app framework. Contribute to solidjs/solid-start development by creating an account on GitHub.
GitHub
solid-start/examples/with-auth/src/lib/index.ts at 678d9acbc0bb669f...
SolidStart, the Solid app framework. Contribute to solidjs/solid-start development by creating an account on GitHub.
These examples use data loaders. The reason I am using
action()
is because Data loaders only load on the server once then rely on useResource()
to refresh subsequent data. Since I am using a server session, I opted to use Actions instead.
In short: No access to useSession() if I were to do this on a createResource()
https://docs.solidjs.com/solid-router/concepts/actions
Is there a way to run a server function in useResource()? The docs don’t mention it.
Either that, or get the data loader to run on every route visit instead of just the initial server-rendered load."user server"
means it runs on the server; doesn't matter if it appears in the route loader.
Where is useResource
coming from? (maybe you mean createResource
?)
And route loaders run on the client side as well. However these days they exist to warm the cache, so if you don't want to use that you should be able to wrap the server function in a createAsync
inside the route component.From the Data Loading section of the docs. Under caveats. “The load function is called once per route, which is the first time the user comes to that route. Following that, the fine-grained resources that remain alive synchronize with state/url changes to refetch data when needed. If the data needs a refresh, the refetch function returned in the createResource can be used.”.
I need the loader to run every single time the route is visited, not just on the first load.
useResource()
is client-side only, meaning I cannot access the server session to get auth tokens to check if the user is authenticated (or do anything requiring access to the session for that matter).
This is why I opted to use an Action. With action, my thinking was I can call it so it loads every time. At least, that was the idea.which is the first time the user comes to that route.to my knowledge that should read
whenever the user navigates to that route.Route loaders are also called when the user just hovers over a link to the route to start warming the cache (which is considered stale after 10secs, 5min for bfcache) even before the navigation starts. However to achieve preloading you have to use
cache
and createAsync
.So, for clarification, suppose this scenario. The user visits the home route where that loader is called (initially). The effect runs, the user isn’t authenticated. So, it redirects the user to the login route. After authenticating, the login route redirects the user back to the home route via
navigate(“/“)
(meaning, the home route is visited a second time). Will the loader run again on that second visit?
My initial solution was to use a data loader. However, it wasn’t running in subsequent visits to the home route. So, I switched to an action.Example
If you open the browser's developer console you will see
loading quotes
whenever you even threaten to navigate to /quotes
.
So there must have been something else going on with your setup.peerreynders
StackBlitz
Quick fetch example - StackBlitz
A Solid TypeScript project based on @solidjs/meta, @solidjs/router, solid-js, typescript, vite and vite-plugin-solid
Hmm. Alright. Let me see what else is going on.