Skip to content

How to Use Multiple Layouts in Next.js

Next.js/

In Next.js you can wrap your pages in a component to share a common layout. But, what if you want to use many layouts?

It is possible to change the layout per page individually. In this post you will learn how to change the default layout in a page of your choice.

Using Multiple Layouts

First things first, you will need a default layout.

Create a component for shared layout.

export default function Layout({ children }) {
  return (
    <>
      <header>Website</header>
      <main>{children}</main>
      <footer>&copy; Website</footer>
    </>
  );
}

Here, the header and footer will remain the same on every page that uses this layout. The children prop will contain the actual content of the page. You can wrap it in any HTML element you want and style according to your needs.

Now, update your _app.jsx to use your Layout component in all pages.

import Layout from 'src/components/Layout/Layout';

export default function MyApp({ Component, pageProps }) {
  return (
    <>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </>
  );
}

Any page you create will be put inside your Layout component where you placed the children prop.

Creating Alternative Layout

Now, create another layout component that you want to use as an alternative to your default one.

export default function LayoutWithSidebar({ children }) {
  return (
    <>
      <header>Website</header>
      <main>{children}</main>
      <aside>Sidebar</aside>
      <footer>&copy; Website</footer>
    </>
  );
}

Next, use the alternative layout in one of your pages.

import LayoutWithSidebar from 'src/components/Layout/LayoutWithSidebar';

export default function AlternativeLayoutPage() {
  return <>Page with a sidebar</>;
}

AlternativeLayoutPage.getLayout = function(page) {
  return <LayoutWithSidebar>{page}</LayoutWithSidebar>;
};

A couple things are happening here:

  • Define a getLayout function on your layout component (or choose a name you want)
  • Next.js passes this function current page through its first parameter, in this case — page.
  • The JSX you return from this function is used as the layout for this page. This is how you can wrap the page in another layout — LayoutWithSidebar.

But, this won’t be enough to override the default layout.

You need to update your _app.jsx file to use the layout defined on a page component, if it has one.

import Layout from '../components/Layout/Layout';

export default function MyApp({ Component, pageProps }) {
  const renderWithLayout =
    Component.getLayout ||
    function (page) {
      return <Layout>{page}</Layout>;
    };

  return renderWithLayout(<Component {...pageProps} />);
}

Again, here’s the explanation:

  • You save the component’s getLayout function inside renderWithLayout variable
  • If a component doesn’t have a getLayout function, you save a function that returns the default layout instead
  • Finally, you call the function saved in renderWithLayout to either render the page with its custom layout or the default one

Nesting Layouts

Let’s say you want to use a default layout component for the page structure and another layout for the content.

You can use composition to achieve exactly that.

import Layout from 'src/components/Layout/Layout';
import ContentLayout from 'src/components/Layout/ContentLayout';

export default function AlternativeLayoutPage() {
  return <>Component wrapped in two layouts</>;
}

AlternativeLayoutPage.getLayout = function(page) {
  return (
    <Layout>
      <ContentLayout>
        {page}
      </ContentLayout>
    </Layout>
  );
};

This way you can combine all of your layouts in any imaginable way.