Help Understanding Better-auth
Using Nextjs
Ive just started messing around with better auth to understand the fundamentals of how it works.
My question is around if auth and authClient are designed to be used interchangeably.
I'm testing out organizations and as expected using authClient hooks like useActiveOrganization() react to changes from the auth client like authClient.organization.setActive().
When using auth like auth.api.getFullOrganization() in server components this only revalidates when using auth.api.setActiveOrganization() and im assuming this happens due to headers being passed in, i could be wrong but it is somehow being revalidated/rerun.
The problem i see is if they are used interchangeably like fetching data based off the active org which uses auth.api, and i set a new active org using authClient.organization.setActive() this will cause components using authClient.useActiveOrganization() to react but the data that was fetched using auth.api would still be returning data from the old organization.
The only workaround i see is using one or the other consistently but since i do all my data fetching in server components id have to use auth.
Maybe i have this completely wrong but would be much appreciated if someone could give me insight on this? Thanks
9 Replies
As far as I am concerned you should use auth.api on the server, and authClient on the client (as the names suggest).
Most api functions provide a way to identify things you deal with. So If you have a more complex operation that should be kind of "atomic", you can define a server action that executes the functions usign the provided api instance by specifically identifying the subjects/objects you interact with (I havent used organization plugin myself but I assume there is a way to provide the identification using the body paramters)
When you are on the client and want to do simple operations arleady directly supported by the plugin, which are already "atomic", you can directly invoke the functions of the authClient on the client side, which then in turn sends a request to your API routes defined through better-auth.
So in short:
Server -> API
Client -> AuthClient
(At least this is how I understood it whilst using better-auth so far, but I may be mistaken)
https://www.better-auth.com/docs/concepts/api
https://www.better-auth.com/docs/concepts/client
API | Better Auth
Better Auth API.
Client | Better Auth
Better Auth client library for authentication.
e.g. here the plugin page shows that you can identify organization and user using the userId and organizationId property. I would assume equal parameters being applied to all other functions provided in the authClient.

if you are on Next.js I mean it kinda pushes you to go server first anyways
so i'd be using auth.api.getSession() on top level server component and then go from there
When i say interchangeably i mean fetching in server components using auth.api and setting in client components using authClient
"As far as I am concerned you should use auth.api on the server, and authClient on the client (as the names suggest)."
This is obvious and gives the impression to use interchangeably as needed. The problem im seeing though is fetching with auth.api and setting with authClient causes UI to be out of sync which is a problem. If i set with auth.api inside of a server action then this does revalidate the auth.api fetch somehow, if through headers changing im not sure.
This comes back to my question, are they meant to be used interchangeably
I mean that is just a typical issue of getting data on inital load vs. refreshing it on the client
You are free to use them how you like, one can be executed on the client, one on the server
If you were to update your clients company using a server action and the api object, your ui also wouldn't refresh unless you trigger a rerender of the page
To make it clearer all my data fetching is done in server components which means there is no way to pass the active org id from the client to server, so i need to use auth.api to get the active org id. now lets say im on a jobs page which has the jobs displayed using the active org id. If i have my org switcher in the sidebar and use the authClient to switch orgs, client components that use authClient to get active org will be reactive to the change but the jobs wont be reactive as they use auth.api to get the org id so youll have a new active org with jobs from the previous active org. The is easily fixed by using a server action instead to change org. But this situation is why im asking if they should be used together
In this case unless you use a context or some other state that tells the components to refetch on client side, yes using authClient is not suitable for that. Using interchangeably however for first populating on server, and then refetching on client is what I do mostly
Thats the thing though it does revalidate using the auth.api without any revalidation logic or caching. Im assuming this is because of next headers which is dynamic and can only be dynamic. Im assuming theres some type of revalidation happening because of headers but im not sure
Thanks for your help. My question was basically trying to understand how they should be used together and really if there state is in sync. When a project gets massive and im using many plugins with different api's, i want to avoid out of sync UI
in your case yes will revalidate everytime since in next if you pass down a dynamic prop like header it will always re-execute