'How to add a shared layout when using NextJS and Auth0?

I've followed the Next docs to set up my layouts, which is working fine. However, the NextJS Auth0 SDK has a withPageAuthRequired wrapped that breaks this pattern.

The pattern I'm using is from these docs. For example, here is a page component:

function Page(): ReactElement {
  return <DashboardLayout>"Code Detail Page"</DashboardLayout>
}

Page.getLayout = function getLayout(page: ReactElement) {
  return <DashboardLayout>{page}</DashboardLayout>
}

export default withPageAuthRequired(Page)

And then in my _app.tsx:

type NextPageWithLayout = NextPage & {
  getLayout?: (page: ReactElement) => ReactNode
}

type AppPropsWithLayout = AppProps & {
  Component: NextPageWithLayout
}

function MyApp({ Component, pageProps }: AppPropsWithLayout) {
  const getLayout = Component.getLayout || ((page) => page)

  return (
    <UserProvider>
        {getLayout(<Component {...pageProps} />)}
    </UserProvider>
  )
}

export default MyApp

The problem I have with this is that my layout is no longer pulled, which I'm assuming is because of the Auth0 wrapper.

If I do the following, I'm able to render the layout, but I need to add a // @ts-ignore before the AuthWrapper.getLayout assignment.

const AuthWrapper = withPageAuthRequired(Page)

AuthWrapper.getLayout = function getLayout(page: ReactElement) {
  return <DashboardLayout>{page}</DashboardLayout>
}
export default AuthWrapper

Is there an alternative way to use layouts with this pattern that doesn't require adding // @ts-ignore to all of my authenticated pages?



Solution 1:[1]

I think you are using withPageAuthRequired wrong. It is used to wrap the getServerSideProps, not the page.

If you wrap your getServerSideProps with WithPageAuthRequired your props object will be augmented with the user property, which will be the user's Claims

export const getServerSideProps = withPageAuthRequired({
  getServerSideProps: async ({ req, res }) => {
    const auth0User = getSession(req, res);
    ... add logic here

    return {
      props: {
        myProp,
      },
    };
  },
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yilmaz