t3-oss / create-t3-app

The best way to start a full-stack, typesafe Next.js app
https://create.t3.gg
MIT License
24.77k stars 1.14k forks source link

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

Open L-Steinmacher opened 10 months ago

L-Steinmacher commented 10 months ago

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.

c-ehrlich commented 10 months ago

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

L-Steinmacher commented 10 months ago

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.

c-ehrlich commented 10 months ago

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.

juliusmarminge commented 10 months ago

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

kristianeboe commented 10 months ago

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?

shoodey commented 10 months ago

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

juliusmarminge commented 10 months ago

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

inducingchaos commented 9 months ago

@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.

asrvd commented 7 months ago

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

ahkhanjani commented 6 months ago

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.

rudyorre commented 5 months ago

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.