[GH-ISSUE #3608] Server-side auth actions (sign-up, sign-in, sign-out) that modify the session do not trigger useSession state updates #26984

Closed
opened 2026-04-17 17:45:29 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @SorooshGb on GitHub (Jul 25, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3608

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Set up Better Auth in a Next.js app using betterAuth() with the nextCookies() plugin
  2. Enable emailAndPassword authentication
  3. Set up the auth client using createAuthClient() from better-auth/react
  4. Use the useSession() hook in a client component, such as a Navbar, which is included in the root layout and displays session status (e.g., user name or sign-in button).
  5. Use a server action to call any of the following:
    • await auth.api.signUpEmail({ body: { ...signUpData } })
    • await auth.api.signInEmail({ body: { ...signInData } })
    • await auth.signOut()
  6. Observe that useSession() does not react to the session change

Current vs. Expected behavior

Expected: When a server-side auth action like sign-in or sign-out is performed, the useSession hook should automatically reflect the new session state on the client (just like it does when working with client side auth instance).

Actual: The session cookie is updated correctly, but useSession does not detect or react to the change until a full page refresh.

Note: This issue does not occur with social sign-ins, since they trigger a full-page redirect to the provider and back, which naturally refreshes the session state. The issue only arises with email/password server-side actions, which update the session cookie without causing a page reload or triggering a client-side session update.

So when testing, keep in mind:
Social logins work correctly due to automatic page reloads.
⚠️ Email/password flows require a manual refresh or a client-side workaround to reflect the updated session state.


🧠 Important insights:

  • 🔍 After reviewing the source code, there appears to be no built-in logic to automatically revalidate the session on the client after server-side auth actions (e.g. sign-in or sign-out).
    This is unexpected and unlike most established auth libraries (e.g. NextAuth.js, Clerk), which somehow manage this state sync.

  • 🛠️ Additionally, for social logins, you must manually handle the redirect to the provider’s URL from the server.
    There is no automatic redirect or helper built-in to trigger this behavior.


🔗 CodeSandbox for testing:
https://codesandbox.io/p/devbox/yl73mj

⚠️ Update the .env file with the correct BASE_URL based on your preview URL.
To test Google login, also provide your GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.

💾 GitHub repo:
https://github.com/SorooshGb/better-auth-test


🧱 Project Structure

  • The root layout.tsx includes a navbar client component that uses the useSession hook to display the current session state. This layout is shared across all pages.

📄 Pages

  1. /Server-side test page

    • All actions (sign up, sign in, sign out) are server-side via form actions and the server auth instance.
    • The navbar reads session state using useSession but doesn’t auto-update after actions.
  2. /client-testClient-side test page

    • All actions are triggered using authClient on the client.
    • Session state updates instantly and reflects changes without a reload.

📌 Behavior to Observe

  • 🐛 On the server-side test page, after signing in, signing up, or signing out, the session shown in the navbar remains outdated until you:

    • Refresh the page, or
    • Click the “Refetch Session” button.
  • On the client-side test page, session state updates instantly and correctly with every action—no manual refresh needed.

What version of Better Auth are you using?

1.3.3

Provide environment information

- OS: Windows 11
- Browser: Chrome (latest), Firefox (latest), Brave (latest)

Which area(s) are affected? (Select all that apply)

Backend, Client

Originally created by @SorooshGb on GitHub (Jul 25, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3608 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Set up Better Auth in a Next.js app using `betterAuth()` with the `nextCookies()` plugin 2. Enable `emailAndPassword` authentication 3. Set up the auth client using `createAuthClient()` from `better-auth/react` 4. Use the `useSession()` hook in a client component, such as a Navbar, which is included in the root layout and displays session status (e.g., user name or sign-in button). 5. Use a **server action** to call any of the following: - `await auth.api.signUpEmail({ body: { ...signUpData } })` - `await auth.api.signInEmail({ body: { ...signInData } })` - `await auth.signOut()` 6. Observe that `useSession()` does **not** react to the session change ### Current vs. Expected behavior **Expected**: When a server-side auth action like sign-in or sign-out is performed, the `useSession` hook should automatically reflect the new session state on the client (just like it does when working with client side auth instance). **Actual**: The session cookie is updated correctly, but `useSession` does not detect or react to the change until a full page refresh. **Note:** This issue does *not* occur with social sign-ins, since they trigger a full-page redirect to the provider and back, which naturally refreshes the session state. The issue only arises with **email/password server-side actions**, which update the session cookie *without* causing a page reload or triggering a client-side session update. So when testing, keep in mind: ✅ **Social logins work correctly** due to automatic page reloads. ⚠️ **Email/password flows require a manual refresh** or a client-side workaround to reflect the updated session state. --- 🧠 **Important insights:** - 🔍 After reviewing the source code, there appears to be **no built-in logic** to automatically revalidate the session on the client after server-side auth actions (e.g. sign-in or sign-out). This is unexpected and **unlike most established auth libraries** (e.g. NextAuth.js, Clerk), which somehow manage this state sync. - 🛠️ Additionally, for **social logins**, you must **manually handle the redirect** to the provider’s URL from the server. There is no automatic redirect or helper built-in to trigger this behavior. --- 🔗 **CodeSandbox for testing:** [https://codesandbox.io/p/devbox/yl73mj](https://codesandbox.io/p/devbox/yl73mj) > ⚠️ Update the `.env` file with the correct `BASE_URL` based on your preview URL. > To test Google login, also provide your `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET`. 💾 **GitHub repo:** [https://github.com/SorooshGb/better-auth-test](https://github.com/SorooshGb/better-auth-test) --- ### 🧱 Project Structure - The root `layout.tsx` includes a **navbar** client component that uses the `useSession` hook to display the current session state. This layout is shared across all pages. --- ### 📄 Pages 1. `/` → **Server-side test page** - All actions (sign up, sign in, sign out) are server-side via form actions and the `server auth instance`. - The **navbar** reads session state using `useSession` but doesn’t auto-update after actions. 2. `/client-test` → **Client-side test page** - All actions are triggered using `authClient` on the client. - Session state updates instantly and reflects changes without a reload. --- ### 📌 Behavior to Observe - 🐛 On the **server-side test page**, after signing in, signing up, or signing out, the session shown in the navbar **remains outdated** until you: - Refresh the page, or - Click the **“Refetch Session”** button. - ✅ On the **client-side test page**, session state updates **instantly and correctly** with every action—no manual refresh needed. ### What version of Better Auth are you using? 1.3.3 ### Provide environment information ```bash - OS: Windows 11 - Browser: Chrome (latest), Firefox (latest), Brave (latest) ``` ### Which area(s) are affected? (Select all that apply) Backend, Client
GiteaMirror added the locked label 2026-04-17 17:45:29 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jul 25, 2025):

Hi @SorooshGb! I'm Dosu and I’m helping the better-auth team.

This is a known architectural gap in Better Auth v1.3.3: server-side auth actions (like sign-up, sign-in, sign-out) update the session cookie, but there’s no built-in mechanism to notify the client or trigger a useSession update. As a result, the session state in client components remains stale until you manually refresh the page or call the refetch method from useSession—unlike libraries such as NextAuth.js, which use a provider pattern to keep session state in sync automatically [source].

The codebase confirms that session state is managed via a nanostore and updated by fetching /get-session, but server actions don’t trigger the necessary signal for the client to refresh session state [source]. Social logins work because the redirect causes a full reload, which naturally updates the session.

Current workarounds: after a server-side auth action, trigger a client-side navigation, reload, or call the refetch method from useSession to update the session state. There are ongoing discussions about introducing a provider pattern or allowing initial session data to be passed to the client, which would improve this experience in the future [source].

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

<!-- gh-comment-id:3117479417 --> @dosubot[bot] commented on GitHub (Jul 25, 2025): <!-- Greeting --> Hi @SorooshGb! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a known architectural gap in Better Auth v1.3.3: server-side auth actions (like sign-up, sign-in, sign-out) update the session cookie, but there’s no built-in mechanism to notify the client or trigger a `useSession` update. As a result, the session state in client components remains stale until you manually refresh the page or call the `refetch` method from `useSession`—unlike libraries such as NextAuth.js, which use a provider pattern to keep session state in sync automatically [[source](https://github.com/better-auth/better-auth/issues/2768)]. The codebase confirms that session state is managed via a nanostore and updated by fetching `/get-session`, but server actions don’t trigger the necessary signal for the client to refresh session state [[source](https://github.com/better-auth/better-auth/blob/f99305b29eb096186a0f85100e01f721d208f2f0/packages/better-auth/src/client/react/index.ts)]. Social logins work because the redirect causes a full reload, which naturally updates the session. Current workarounds: after a server-side auth action, trigger a client-side navigation, reload, or call the `refetch` method from `useSession` to update the session state. There are ongoing discussions about introducing a provider pattern or allowing initial session data to be passed to the client, which would improve this experience in the future [[source](https://github.com/better-auth/better-auth/issues/2768)]. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/57e71054-4462-419c-afe1-e608decd4114?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/57e71054-4462-419c-afe1-e608decd4114?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/57e71054-4462-419c-afe1-e608decd4114?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/57e71054-4462-419c-afe1-e608decd4114?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/57e71054-4462-419c-afe1-e608decd4114?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/57e71054-4462-419c-afe1-e608decd4114?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/57e71054-4462-419c-afe1-e608decd4114?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/3608)
Author
Owner

@ping-maxwell commented on GitHub (Aug 11, 2025):

Closing this as duplicate of https://github.com/better-auth/better-auth/issues/1006#issuecomment-3166246173

<!-- gh-comment-id:3175863750 --> @ping-maxwell commented on GitHub (Aug 11, 2025): Closing this as duplicate of https://github.com/better-auth/better-auth/issues/1006#issuecomment-3166246173
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#26984