undefined session in _app.tsx file

I want to get the session in the app file but undefined always appears, however the hooks work and return the session
10 Replies
amargoCactus
amargoCactus16mo ago
I'm missing something?
deforestor
deforestor16mo ago
Show your _app But I recommend debugging by logging the _app props Like:
const App = (...props) => {...
const App = (...props) => {...
amargoCactus
amargoCactus16mo ago
import { type ReactNode, type ReactElement } from 'react';
import { type NextComponentType, type NextPage } from 'next';
import {
type AppContextType,
type AppInitialProps,
} from 'next/dist/shared/lib/utils';
import { type Session } from 'next-auth';
import { SessionProvider } from 'next-auth/react';
import { ToastContainer } from 'react-toastify';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import NextNProgress from 'nextjs-progressbar';

import { api } from '~/utils/api';

import Layout from '~/layouts';
import { defineAbility } from '~/config/ability';
import { AbilityContext } from '~/components/can/can.component';

import '~/styles/globals.css';

type NextPageWithLayout<P = Record<string, never>, IP = P> = NextPage<P, IP> & {
getLayout?: (page: ReactElement) => ReactNode;
};

type AppPropsWithLayout<P> = AppInitialProps<P> & {
Component: NextPageWithLayout;
};

type AppWithLayout<P = Record<string, never>> = NextComponentType<
AppContextType,
P,
AppPropsWithLayout<P>
>;

const MyApp: AppWithLayout<{ session: Session | null }> = ({
Component,
pageProps: { session, ...pageProps },
}) => {
const ability = defineAbility({
userId: session?.user?.id ?? '',
role: session?.user?.role?.identifier ?? '',
});

const getLayout = Component.getLayout ?? ((page) => <Layout>{page}</Layout>);

return (
<>
<ReactQueryDevtools />
<NextNProgress />
<ToastContainer autoClose={3000} />
<SessionProvider session={session}>
<AbilityContext.Provider value={ability}>
{getLayout(<Component {...pageProps} />)}
</AbilityContext.Provider>
</SessionProvider>
</>
);
};

export default api.withTRPC(MyApp);
import { type ReactNode, type ReactElement } from 'react';
import { type NextComponentType, type NextPage } from 'next';
import {
type AppContextType,
type AppInitialProps,
} from 'next/dist/shared/lib/utils';
import { type Session } from 'next-auth';
import { SessionProvider } from 'next-auth/react';
import { ToastContainer } from 'react-toastify';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import NextNProgress from 'nextjs-progressbar';

import { api } from '~/utils/api';

import Layout from '~/layouts';
import { defineAbility } from '~/config/ability';
import { AbilityContext } from '~/components/can/can.component';

import '~/styles/globals.css';

type NextPageWithLayout<P = Record<string, never>, IP = P> = NextPage<P, IP> & {
getLayout?: (page: ReactElement) => ReactNode;
};

type AppPropsWithLayout<P> = AppInitialProps<P> & {
Component: NextPageWithLayout;
};

type AppWithLayout<P = Record<string, never>> = NextComponentType<
AppContextType,
P,
AppPropsWithLayout<P>
>;

const MyApp: AppWithLayout<{ session: Session | null }> = ({
Component,
pageProps: { session, ...pageProps },
}) => {
const ability = defineAbility({
userId: session?.user?.id ?? '',
role: session?.user?.role?.identifier ?? '',
});

const getLayout = Component.getLayout ?? ((page) => <Layout>{page}</Layout>);

return (
<>
<ReactQueryDevtools />
<NextNProgress />
<ToastContainer autoClose={3000} />
<SessionProvider session={session}>
<AbilityContext.Provider value={ability}>
{getLayout(<Component {...pageProps} />)}
</AbilityContext.Provider>
</SessionProvider>
</>
);
};

export default api.withTRPC(MyApp);
i'm trying to use defineAbility function, to define RBAC but I think I’ll create a component that wraps AbilityContext.Provider and children, as useSession hook are working
deforestor
deforestor16mo ago
Yo Sorry for the delay, I got really busy
deforestor
deforestor16mo ago
I think it really isn't possible to pass down the props to the Component, but what you can and probably should do, is get it on the server side, for example:
deforestor
deforestor16mo ago
you could do a step further and abstract that, if your getServerSideProps are repeated all the time:
deforestor
deforestor16mo ago
and to have full type safety, I did it like this: create a src/types/next.d.ts file and have this:
import type { Session } from 'next-auth';

declare module "next/app" {
type AppProps<P = Record<string, unknown>> = {
Component: NextComponentType<NextPageContext, any, P>;
router: Router;
__N_SSG?: boolean;
__N_SSP?: boolean;
pageProps: P & PageProps;
};
type PageProps = {
session?: Session;
};
}
import type { Session } from 'next-auth';

declare module "next/app" {
type AppProps<P = Record<string, unknown>> = {
Component: NextComponentType<NextPageContext, any, P>;
router: Router;
__N_SSG?: boolean;
__N_SSP?: boolean;
pageProps: P & PageProps;
};
type PageProps = {
session?: Session;
};
}
deforestor
deforestor16mo ago
Then type the _app like this:
deforestor
deforestor16mo ago
and the pages like this:
deforestor
deforestor16mo ago
the next.d.ts is what I remember finding on my research so that the PageProps and AppProps remained consistent by just adding into the existent one from next