Search code examples
next.jslayoutapp-router

Excluding one element from the layout on the current child route in Nextjs 13


In Nextjs 13, using the app router, how can I exclude one element from the root layout from being rendered in a child route. I specifically would like to exclude the aside with the Feed component and keep the rest of the code:

// Exlude this:

<aside className={styles.feed}>
    <Feed />
</aside>
// layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
   
      <html lang="en" className={`${outfit.className} ${styles.html}`}>
        <body className={styles.body}>
          <div className={styles.wrapper}>
            <aside className={styles.feed}>
              <Feed />
            </aside>
          <div className={styles.main}>
              <nav className={styles.nav}>
                <Navbar />
              </nav>
              <main className={styles.children}>{children}</main>
            </div>
          </div>

          <footer className={styles.footer}>
            <Footer />
          </footer>
        </body>
      </html>

  
  );
}
// page.tsx
const Listing = () => {

return (
 <section className={styles.gallery}>
   // code
 </section>   
  );
};

export default Listing;

Solution

  • There is two solutions

    1. Make your feed component 'use client' and add usePathname hook, and do not render at your route

    2. If you want to make it static you can create two sub group folder with different layouts

    baseLayout.tsx

    export default function BaseLayout({
      children,
      isFeed
    }: {
      children: React.ReactNode;
      isFeed?: boolean
    }) {
      return (
          <html lang="en" className={`${outfit.className} ${styles.html}`}>
            <body className={styles.body}>
              <div className={styles.wrapper}>
                {isFeed && (
                  <aside className={styles.feed}>
                    <Feed />
                  </aside>
                  )
                }
              <div className={styles.main}>
                  <nav className={styles.nav}>
                    <Navbar />
                  </nav>
                  <main className={styles.children}>{children}</main>
                </div>
              </div>
    
              <footer className={styles.footer}>
                <Footer />
              </footer>
            </body>
          </html>
      );
    }
    

    app/(with-feed)/layout.tsx

    export default function WithFeedLayout({
      children,
    }: {
      children: React.ReactNode;
    }) {
      return (
       <BaseLayout isFeed>
         {children}
       </BaseLayout>
      );
    }
    

    app/(no-feed)/layout.tsx

    export default function NoFeedLayout({
      children,
    }: {
      children: React.ReactNode;
    }) {
      return (
       <BaseLayout>
         {children}
       </BaseLayout>
      );
    }