Search code examples
javascriptreactjsnext.jsserver-side-rendering

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;

Solution

  • 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`))