[GH-ISSUE #960] useSession -> isPending Hydration Issues (Next.js SSR) #25844

Closed
opened 2026-04-17 16:07:09 -05:00 by GiteaMirror · 6 comments
Owner

Originally created by @daveycodez on GitHub (Dec 20, 2024).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/960

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

The isPending hook is used on the client side to show loading states, so when I do this:

const { data: session, isPending: sessionPending } = authClient.useSession()
 <DropdownMenuTrigger>
  {sessionPending ? (
      <Skeleton className="w-10 h-10 rounded-full" />
  ) : (
      <Avatar>
          <AvatarImage src={session ? "https://github.com/shadcn.png" : ""} alt="@shadcn" />

          <AvatarFallback>
              CN
          </AvatarFallback>
      </Avatar>
  )}
</DropdownMenuTrigger>

And then refresh the page, I get a hydration error.

Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used

This is because isPending is "false" in the initial SSR render. isPending should default to true so SSR always renders isPending as true, then we can use it to decide whether or not to show loading Skeletons for things like avatars on the Client without facing Hydration issues. Should be as simple as initializing isPending as true in the useSession hook.

Current vs. Expected behavior

isPending = true on SSR

What version of Better Auth are you using?

1.2.2

Provide environment information

Next.js Pages Router SSR

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

Client

Auth config (if applicable)

No response

Additional context

No response

Originally created by @daveycodez on GitHub (Dec 20, 2024). Original GitHub issue: https://github.com/better-auth/better-auth/issues/960 ### Is this suited for github? - [ ] Yes, this is suited for github ### To Reproduce The isPending hook is used on the client side to show loading states, so when I do this: ```ts const { data: session, isPending: sessionPending } = authClient.useSession() ``` ```tsx <DropdownMenuTrigger> {sessionPending ? ( <Skeleton className="w-10 h-10 rounded-full" /> ) : ( <Avatar> <AvatarImage src={session ? "https://github.com/shadcn.png" : ""} alt="@shadcn" /> <AvatarFallback> CN </AvatarFallback> </Avatar> )} </DropdownMenuTrigger> ``` And then refresh the page, I get a hydration error. `Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used` This is because isPending is "false" in the initial SSR render. isPending should default to true so SSR always renders isPending as true, then we can use it to decide whether or not to show loading Skeletons for things like avatars on the Client without facing Hydration issues. Should be as simple as initializing isPending as true in the useSession hook. ### Current vs. Expected behavior isPending = true on SSR ### What version of Better Auth are you using? 1.2.2 ### Provide environment information ```bash Next.js Pages Router SSR ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) _No response_ ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-17 16:07:09 -05:00
Author
Owner

@daveycodez commented on GitHub (Dec 20, 2024):

Here's the line

a1e6816d89/packages/better-auth/src/client/vue/index.ts (L82)

a1e6816d89/packages/better-auth/src/client/vanilla.ts (L82)

a1e6816d89/packages/better-auth/src/client/react/index.ts (L88)

Should be simple enough to set these to true unless there's somewhere else I'm missing.

Might want to address any other isPending states on other hooks as well

a1e6816d89/packages/better-auth/src/client/query.ts (L18)

<!-- gh-comment-id:2556423005 --> @daveycodez commented on GitHub (Dec 20, 2024): Here's the line https://github.com/better-auth/better-auth/blob/a1e6816d89e8e853858df715bae48db96e252906/packages/better-auth/src/client/vue/index.ts#L82 https://github.com/better-auth/better-auth/blob/a1e6816d89e8e853858df715bae48db96e252906/packages/better-auth/src/client/vanilla.ts#L82 https://github.com/better-auth/better-auth/blob/a1e6816d89e8e853858df715bae48db96e252906/packages/better-auth/src/client/react/index.ts#L88 Should be simple enough to set these to true unless there's somewhere else I'm missing. Might want to address any other isPending states on other hooks as well https://github.com/better-auth/better-auth/blob/a1e6816d89e8e853858df715bae48db96e252906/packages/better-auth/src/client/query.ts#L18
Author
Owner

@Bekacru commented on GitHub (Dec 20, 2024):

the vue client doesn't affect the beahvior but isPending is true on initialization as you see here a1e6816d89/packages/better-auth/src/client/query.ts (L30)

but I'll try to investigate the hydration error on my side and see what's causing it.

<!-- gh-comment-id:2556837789 --> @Bekacru commented on GitHub (Dec 20, 2024): the vue client doesn't affect the beahvior but `isPending` is `true` on initialization as you see here https://github.com/better-auth/better-auth/blob/a1e6816d89e8e853858df715bae48db96e252906/packages/better-auth/src/client/query.ts#L30 but I'll try to investigate the hydration error on my side and see what's causing it.
Author
Owner

@Bekacru commented on GitHub (Dec 20, 2024):

Hey @daveycodez if you're on discord please ping me there :)

<!-- gh-comment-id:2556854910 --> @Bekacru commented on GitHub (Dec 20, 2024): Hey @daveycodez if you're on discord please ping me there :)
Author
Owner

@jamesjulich commented on GitHub (Dec 20, 2024):

I am also experiencing this issue. If you need any details/want another case to reproduce this error, lmk.

<!-- gh-comment-id:2557711876 --> @jamesjulich commented on GitHub (Dec 20, 2024): I am also experiencing this issue. If you need any details/want another case to reproduce this error, lmk.
Author
Owner

@Bekacru commented on GitHub (Dec 21, 2024):

I am also experiencing this issue. If you need any details/want another case to reproduce this error, lmk.

yeah please do! I couldn't replicate it on my end

<!-- gh-comment-id:2558042366 --> @Bekacru commented on GitHub (Dec 21, 2024): > I am also experiencing this issue. If you need any details/want another case to reproduce this error, lmk. yeah please do! I couldn't replicate it on my end
Author
Owner

@daveycodez commented on GitHub (Dec 21, 2024):

@Bekacru

create-next-app with Pages Router then create this file ->

/src/pages/page.tsx

import { useSession } from "@/lib/auth-client"

export default function Page() {
    const { isPending } = useSession()

    if (isPending) {
        return (
            <div>
                Loading...
            </div>
        )
    }

    return (
        <div>
            <h1>
                Page
            </h1>
        </div>
    )
}

Then navigate to https://localhost:3000/page and refresh it to see hydration error

<!-- gh-comment-id:2558046821 --> @daveycodez commented on GitHub (Dec 21, 2024): @Bekacru create-next-app with Pages Router then create this file -> /src/pages/page.tsx ```tsx import { useSession } from "@/lib/auth-client" export default function Page() { const { isPending } = useSession() if (isPending) { return ( <div> Loading... </div> ) } return ( <div> <h1> Page </h1> </div> ) } ``` Then navigate to https://localhost:3000/page and refresh it to see hydration error
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#25844