5

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?

2 Answers 2

4

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"
    },
  };
}
Sign up to request clarification or add additional context in comments.

1 Comment

how would this same Problem be solved with Next.js 13, 14 App router?
3

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;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.