Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Next.js Opt out of Layout Component for specific pages from _app.js

How to not wrap a specific page with Layout component in _app.js?

For example, I have two pages as pages/home and pages/about, now how can I not wrap my pages/home page with Layout component?

pages/_app.js

import "../styles/globals.css";
import Layout from "../components/Layout";

function MyApp({ Component, pageProps }) {

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

export default MyApp;

What I have tried:

pages/_app.js

function MyApp({ Component, pageProps }) {
  console.log(typeof Component); // gives me a function

  switch (Component) {
    case Home():
      return <Component {...pageProps} />;
    default:
      return (
        <Layout>
          <Component {...pageProps} />{" "}
        </Layout>
      );
  }
}

pages/home.js

import React from 'react';
 
const Home= () => {
  return (<div>Hello</div>);
};
 
export default Home;
like image 838
Shreyas Jadhav Avatar asked Dec 31 '22 15:12

Shreyas Jadhav


2 Answers

by checking the appProps.router.pathname property passed to it.

way 1

function MyApp({ Component, pageProps, ...appProps }: AppProps) {

  // make function that will return the children based on router.pathname

  const getContent = () => {
    // array of all the paths that doesn't need layout
    if ([`/dashboard`].includes(appProps.router.pathname))
      return <Component {...pageProps} />;

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

  return <ApplicationWrapper>{getContent()}</ApplicationWrapper>;
}

way 2

function MyApp({ Component, pageProps, ...appProps }: AppProps) {

    // use a LayoutComponent variable 
   // that switches to actual Layout or React.Fragment (no layout) 
   //accordingly to pathname


    const isLayoutNeeded = [`/dashboard`].includes(appProps.router.pathname);

    const LayoutComponent = isLayoutNeeded ? Layout : React.Fragment;

    


  return (<ApplicationWrapper> 
    <LayoutComponent>
        <Component />
    </LayoutCompnent>
    </ApplicationWrapper>);
}

TIP:

you can use path.startsWith to check all the paths, example

if(router.pathname.startsWith(`/dashboard`))
like image 154
Shreyas Jadhav Avatar answered Jan 02 '23 04:01

Shreyas Jadhav


I think there is cleaner way of doing this with Per-Page Layouts. I'm currently doing this simple by creating a default layout for all pages and override it for the pages that require specific layout, for example in my login and registration pages.

    export default function LoginPage() {
      return {
        /** Some JSX */
      }
    }
    // Return the page without additional layout.
    LoginPage.getLayout = (page) => page

    export default function MyApp({ Component, pageProps }) {
      // Use the specified page layout or fallback to the default one.
      const getLayout = Component.getLayout ?? defaultPageLayout

      return getLayout(<Component {...pageProps} />)
    }
like image 41
Ivan Nakov Avatar answered Jan 02 '23 06:01

Ivan Nakov