Reputation: 55
I have the layout component imported in the _app.js file:
Layout.js:
const Layout = ({ children, webName, pageTitle }) => {
return (
<div>
<Head>
<meta charSet='utf-8' />
<meta
name='viewport'
content='width=device-width, initial-scale=1, shrink-to-fit=no'
/>
<meta name='description' content='' />
<meta name='author' content='Chris Achinga -> chrisdevcode.xyz' />
<title>Feet Of Colors Foundation</title>
</Head>
<PageHeader webName={webName} pageTitle={pageTitle} />
<NavBar webName={webName} />
<main>{children}</main>
<Footer />
</div>
)
}
export default Layout
The _app.js:
import Layout from '@/layout/Layout'
import '@/styles/globals.css'
export default function App({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
I have different pages that I would love to pass different values to webName and pageTitle props, without using the Layout
component in each file.
How do I achieve that?
Upvotes: 4
Views: 17626
Reputation: 144
pages/_app.tsx
:
import type { InferGetServerSidePropsType, NextPage } from 'next';
import type { AppProps } from 'next/app';
export type NextPageWithLayout<Props extends (args: any) => any> = NextPage<InferGetServerSidePropsType<Props>> & {
getLayout?: (page: React.ReactElement, props: InferGetServerSidePropsType<Props>) => React.ReactNode;
};
export type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout<any>;
};
export default function App({ Component, pageProps }: AppPropsWithLayout) {
const getLayout = Component.getLayout ?? (page => page);
return (
<div className="root">
{getLayout(<Component {...pageProps} />, pageProps)}
</div>
);
}
pages/index.tsx
:
import type { GetServerSideProps } from 'next';
import type { NextPageWithLayout } from '~/pages/_app';
import { Layout } from '~/layouts/custom-layout';
export const getServerSideProps = (async () => {
// ... query your data
return {
props: {
data,
},
};
}) satisfies GetServerSideProps;
const IndexPage: NextPageWithLayout<typeof getServerSideProps> = props => {};
IndexPage.getLayout = (page, props) => <Layout>{page}</Layout>;
export default IndexPage;
Upvotes: 3
Reputation: 16239
you can make use of getServerSideProps
to pass data to your Layout
The data returned by getServerSideProps
is passed as props to the page. And this same props is accessible in _app.js
, so you can pass it to the layout.
export default function MyApp({ Component, pageProps }) {
return (
// here you pass the pageProps to the layout
<Layout pageProps={pageProps}>
<Component {...pageProps} />
</Layout>
);
}
In your Layout
component :
export default function Layout({ pageProps, children }) {
console.log(pageProps); // see pageProps here
return (
<>
<main>{children}</main>
</>
);
}
Finally in your Page :
export async function getServerSideProps() {
return {
props: {
webName: "name",
pageTitle: "title"
},
};
}
Upvotes: 4