create-t3-app icon indicating copy to clipboard operation
create-t3-app copied to clipboard

feat: add `SessionProvider` so i can `useSession`

Open L-Steinmacher opened this issue 1 year ago • 12 comments

Provide environment information

"initVersion": "7.22.0"

Describe the bug

Session provider from Next auth not wrapping children in src/app/layout.tsx and must be added manually. Calling useSession from Next auth not available till this is done.

Reproduction repo

https://stackblitz.com/github/L-Steinmacher/t3-app-dir-next-auth?file=src%2Fapp%2Flayout.tsx

To reproduce

npm create t3-app@latest select options for Next Auth and app dir. Calling hook useSession not available till wrapping children in the provider.

Additional information

Not sure if it's a bug per se but thought I'd report this.

L-Steinmacher avatar Oct 18 '23 19:10 L-Steinmacher

this is actually a reasonable point - we (maintainers) tend to pass the session from the server nowadays, but useSession in a client component is still a legit way to do it, and we don't currently include the necessary providers for that. will reopen again for visibility, let's see if this is an issue for more people

c-ehrlich avatar Oct 19 '23 08:10 c-ehrlich

My specific use case I was using the session to check if the user was logged in and rendering either a login or submit button dynamically as well as displaying some user data. Using the pages router this was fine but now using the app router I can't easily do this the way I did before. I was thinking of making a TRPC endpoint to supply the session and user data to the client component but can't decide if that's jank/hacky. How would you suggest going about using the user session and user info in a client component? Pass as prop or TRPC endpoint? I'm asking from a JR dev point of view.

L-Steinmacher avatar Oct 19 '23 17:10 L-Steinmacher

in general the best way to do it now is to use getServerAuthSession in a server component, and pass it as props to a client component. But useSession is also still fine, you can add the provider in a layout, similar to how it's implemented in the pages dir version.

c-ehrlich avatar Oct 19 '23 19:10 c-ehrlich

I've been building with next-auth and appdir for a while now and never found myself missing useSession, it's easier to await it in a server component and pass it down as props, and not having to worry about the potential loading state when the hook is fetching.

If more report it as missing we might reconsider but this is a conscious decision for now

juliusmarminge avatar Oct 20 '23 07:10 juliusmarminge

If you get the serverSession in the root layout like this

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  const serverSession = await getServerAuthSession();

  return (
    <html >
      <head>
       ...
      </head>

      <body>
          <TRPCReactProvider headers={headers()}>
            <Providers serverSession={serverSession}>
              <main>
                {children}
                <Toaster />
                <Analytics />
              </main>
            </Providers>
          </TRPCReactProvider>
      </body>
    </html>
  );
}

You can then pass it into the "use client" Providers, which again passes it to SessionProvider. Now you can access session in client components with useSession without prop drilling and without loading state.

export function Providers(props: { children: React.ReactNode; serverSession: Session | null }) {
  return (
    <SessionProvider session={props.serverSession}>
            {props.children}
    </SessionProvider>
  );
}

What do you guys think?

kristianeboe avatar Oct 26 '23 12:10 kristianeboe

I'm highly interested in this as well, please consider adding the feature :)

My particular use case is updating the session on the client side when a user switches orgs, read from the url pathname

shoodey avatar Oct 27 '23 14:10 shoodey

With NextAuth v5 (which is in beta and will be out in the next couple of weeks) you'll do this using server actions

juliusmarminge avatar Oct 28 '23 16:10 juliusmarminge

@juliusmarminge You mentioned using server actions. How would you recommend doing so? For now, I'm just passing props from getServerAuthSession in a server component.

Use case is to conditionally render a sign in / sign out button and the content inside of it.

inducingchaos avatar Dec 09 '23 03:12 inducingchaos

https://authjs.dev/guides/upgrade-to-v5?authentication-method=client-component#authenticating-server-side

if you're using app router you won't need useSession for most use cases anymore afaik, see this - https://github.com/nextauthjs/next-auth-v5-example

asrvd avatar Jan 15 '24 05:01 asrvd

Considering how much easier it makes migrating from pages router, I'm also with adding the provider. Although making the migration easy might not be a priority for the maintainers.

ahkhanjani avatar Feb 25 '24 10:02 ahkhanjani

At first I thought this was an oversight but reading through this thread, I've changed my mind. Specifically this from Julius:

I've been building with next-auth and appdir for a while now and never found myself missing useSession, it's easier to await it in a server component and pass it down as props, and not having to worry about the potential loading state when the hook is fetching.

rudyorre avatar Apr 10 '24 06:04 rudyorre