How can I add a new property to Component in _app.tsx in Next.js with Typescript?
Asked Answered
M

3

13

I'm developing some protected pages using Next.js, NextAuth.js and Typescript. The following code from my _app.tsx was taken from the NextAuth.js official website but that includes a property auth that does not exist for Component which has the type var Component: NextComponentType<NextPageContext, any, {}>, so TS is displaying an error for that:

function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
  return (
    <>
      <SessionProvider session={session}>
        {Component.auth ? (
          <Auth>
            <Component {...pageProps} />
          </Auth>
        ) : (
          <Component {...pageProps} />
        )}
      </SessionProvider>
    </>
  );
}

I'm not a Typescript expert, so my question is how can I add/extend that auth property to the Component with TS?

Magnolia answered 9/1, 2022 at 19:12 Comment(0)
C
28

You need to extend AppProp and add your custom attributes

import type { NextComponentType  } from 'next' //Import Component type

//Add custom appProp type then use union to add it
type CustomAppProps = AppProps & {
  Component: NextComponentType & {auth?: boolean} // add auth type
}

function MyApp({ Component, pageProps: { session, ...pageProps } }: CustomAppProps) {
...
}
Cheney answered 9/1, 2022 at 20:24 Comment(1)
That worked fine, thank you!Magnolia
C
0

To support the addition of auth property on an arbitrary component I made the NextAuthComponentType:

import { AppPropsType } from 'next/dist/shared/lib/utils';

export type NextAuthComponentType = AppPropsType['Component'] & { auth?: boolean;};

In the _app.tsx it can be used as:

const MyApp: AppType<Props> = ({ Component, pageProps: {...} }) => {
  const AuthComponent = Component as NextAuthComponentType;
  return (
    ...
    {AuthComponent.auth ? (
      <Auth>
        <AuthComponent {...pageProps} />
      </Auth>
    ) : (
      <Component {...pageProps} />
    )}
    ...

And the the auth can be assigned to the component using:

const AuthPreview: NextAuthComponentType = Preview;
AuthPreview.auth = true;

export default AuthPreview;

P.S. Changing Component in the Props that are passed to the AppType doesn't help and TS doesn't recognise the auth prop

Conduit answered 4/3, 2023 at 14:14 Comment(0)
W
0

if some looks for Auth component

import { useRouter } from 'next/router'
import { useSession } from 'next-auth/react'
import { useEffect } from 'react'


  const Auth = ({children}: { children: React.ReactNode }) =>{
     const router = useRouter()
     const {status, data} = useSession()
     const isUser = !data?.user
     const loading = status === "loading"

  useEffect(()=>{
    if(!loading){
      if(!isUser){
        router.push("/signin")
      }
    }
  },[isUser, loading])

  if(!loading && isUser){
    return <>{children}</>
  }

  return null;
}
Whitaker answered 27/5, 2023 at 17:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.