#Passing ServerSideProps to GetLayout Components
24 messages · Page 1 of 1 (latest)
For reference
_app.tsx
export default function MyApp({
Component,
pageProps,
}: MyAppProps<{ session: Session }>) {
if (Component.getLayout) {
return Component.getLayout(
<SessionProvider session={pageProps.session}>
{' '}
<Component {...pageProps} />{' '}
</SessionProvider>
);
}
return (
<SessionProvider session={pageProps.session}>
<Component {...pageProps} />
</SessionProvider>
);
}
The session provider is from next-auth
profile.tsx
const session = (await getSession({ req: context.req })) as UserSession;
// Obtains username from dynamic path
const username = context.params?.username;
let response = null;
try {
// Attempts to retrieve user data
response = await axios.get(`users/${username}`);
} catch (error) {
// Logs any caught errors
console.log(error);
// Redirect to 404 since the user could not be found
return {
redirect: {
destination: '/404',
permanent: false,
},
};
}
// Checks if the response data is not, or if the user exits
if (response.data === null || response.data.username === null) {
// Redirect to 404 since the user could not be found
return {
redirect: {
destination: '/404',
permanent: false,
},
};
}
console.log("Session ", session);
return {
props: {
user: response.data,
session: session,
},
};
}
function Posts() {
return <div>Posts Here</div>;
}
export default Posts;
Posts.getLayout = (page: ReactElement, session: UserSession): ReactNode => (
<UserProfileLayout session={session}> {page} </UserProfileLayout>
);
When trying to pass the session to the UserProfileLayout, even though it has a value in profile.tsx, it is always null in UserProfileLayout
Anyone have a fix?
So you see this sample getLayout set-up in the next.js documentation here
export default function MyApp({ Component, pageProps }) {
const getLayout = Component.getLayout || (page => page);
return getLayout(<Component {...pageProps} />);
}
the getLayout is a regular function that takes in a page. But it can take in other things as well
for example
export default function MyApp({ Component, pageProps }) {
const myState = 123;
const getLayout = Component.getLayout || (page => page);
return getLayout(<Component {...pageProps} />, myState);
}
///
Page.getLayout = (page, myState) => (
<MyLayout state={myState}>{page}</MyLayout>
)
now, the pageProps in your app holds the props object returned by getStaticProps and getServerSideProps
so you can pass it to getLayout also
export default function MyApp({ Component, pageProps }) {
const getLayout = Component.getLayout || (page => page);
return getLayout(<Component {...pageProps} />, pageProps);
}
///
export function getStaticProps() {
return {
props: {
title: "Hello world"
}
}
}
Page.getLayout = (page, props) => (
<MyLayout title={props.title}>{page}</MyLayout>
)
So in your code, you did pass the session to the getLayout function, however that session doesn't reach the getLayout call inside _app
So how to solve? If you fetch session with getServerSideProps, then the session prop is available inside pageProps, you can use this
if you fetch session with a hook inside _app, you can pass it directly as this
both are good
and to reduce code repetition i'd recommend the latter way
This way?
yes it's how you have the page props inside getLayout
Does that mean that me wrapping the component around the SessionProvider have no effect?
no, in that case you have to useSession inside your layout component
the getLayout call never cares about a second param, so your session param is simply ignored