Skip to content

Passing an intial user from the server to <Auth0Provider user={session?.user}> with Pages Router #1916

Open
@florisdg

Description

@florisdg

Checklist

  • I have looked into the Readme, Examples, and FAQ and have not found a suitable solution or answer.
  • I have looked into the API documentation and have not found a suitable solution or answer.
  • I have searched the issues and have not found a suitable solution or answer.
  • I have searched the Auth0 Community forums and have not found a suitable solution or answer.
  • I agree to the terms within the Auth0 Code of Conduct.

Describe the problem you'd like to have solved

In v3 I used to have this in my Next.js app with Pages router, in the file src/pages/_app.tsx:

export function App({ Component, pageProps, router }: AppPropsWithLayout) {
  const getLayout = Component.getLayout ?? ((page: ReactNode) => page)

  return <UserProvider user={pageProps.user}>
...

Every page using getServerSideProps was wrapped with withPageAuthRequired, which from my understanding would populate this 'user' property in the pageProps shown above. This would make the 'user' object immediately available on first-render with pages that use getServerSideProps.

In v4 this is obviously gone, and the V4_MIGRATION_GUIDE.md (nearly all of the links in this guide are broken) points towards this in EXAMPLES.md:

import { Auth0Provider } from "@auth0/nextjs-auth0"

import { auth0 } from "@/lib/auth0"

export default async function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode
}>) {
  const session = await auth0.getSession()

  return (
    <html lang="en">
      <body>
        <Auth0Provider user={session?.user}>{children}</Auth0Provider>
      </body>
    </html>
  )
}

However, when I do what the example suggests in a _app.tsx file like this...:

export function App({ Component, pageProps, router }: AppPropsWithLayout) {
  const getLayout = Component.getLayout ?? ((page: ReactNode) => page)

  const session = await auth0.getSession()

  return <Auth0Provider user={session?.user}>
...

... it won't work because this file cannot be asynchronous. The same goes for when I attempt aynthing like it my Layout files. (Here in the Next.js docs you see no async in any of the layout files or _app.tsx)

I am clueless how else I can pass an initial user from the server. I need this back so users do not see a 'flash' of empty content until the useUser() hook has retrieved the user.

Describe the ideal solution

Get the same functionality from v3 back in v4's for apps with Page Router

Alternatives and current workarounds

The only thing I could think of is having to add this to all of our pages with getSeverSideProps:

export async function getServerSideProps(ctx: GetServerSidePropsContext) {
  const session =  await auth0.getSession(ctx.req)

  if(!session?.user) {
    return {
      redirect: {
        destination: '/auth/login',
        permanent: false,
      },
    }
  }

  return {
    props: {
      user: session.user,
    },
  }
}

export default function MyPage({user}: InferGetServerSidePropsType<typeof getServerSideProps>) {...}

But this does populate the the user returned by the useUser() hook...

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions