6

Is there a way to remove the base layout for a specific page in NextJS 13 ? I have a general layout for mosts of my views, but some of them require a separated layout, I don't find any solution now.

I've tried to make "groups" of folders with the same layout at the app/ root, but this way is really annoying and kills the project files arborescence.


SOLUTION :

The answer solution is great, but I advise you doing so for general purpose :

https://stackoverflow.com/a/76251557/21820614

Personally, for my project structure, I needed a route which contains a layout, with a header etc, and another route which has no layout at all. I used the link provided above and I made ghost groups for my "root" routes.

BUT, I also needed differents contents in the header (contained in the layout), depending on the route I was in. For doing so, I used the LayoutProvider, with the answer below, and it works great !

Qunther
  • 117
  • 1
  • 5
  • 2
    Does this answer your question? [Exclude a page from the Next.js root layout in the app folder](https://stackoverflow.com/questions/76251099/exclude-a-page-from-the-next-js-root-layout-in-the-app-folder) – Youssouf Oumar May 18 '23 at 17:50

3 Answers3

10

With Next.js <13, the Root Layout can not be set to a Client Component. This means that a shared layout is not re-rendered during navigation. Therefore, you need to create a layout page, similar to a provider, that can wrap the Root Layout. The layout page has to be client component.

  1. Create a layout page in your root directory (/app):
 // Use the client directive for using usePathname hook.
'use client'

// Use usePathname for catching route name.
import { usePathname } from 'next/navigation';

export const LayoutProvider = ({ children }) => {
    const pathname = usePathname();
    return (
        <>
            {pathname === "/posts" && <h1>Welcome to Posts page!</h1>}
            {children}
        </>
    )
};
  1. Wrap your Root Layout (/app/layout.js):
// Import your layout page
import { LayoutProvider } from './LayoutProvider'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <LayoutProvider>
          {children}
        </LayoutProvider>
      </body>
    </html>
  )
}

Further reading:

Emre
  • 723
  • 6
  • 14
6

NextJS 13 way to achieve this is by using Routing Groups

in short, ONLY include layout elements that all children need, and use grouping to share layout in common sections

example of the app directory file structure:

-- (auth)/                   # only for grouping, does not add to url
         /signin/page.tsx
         /singout/page.tsx
         /singup/page.tsx
         /layout.tsx         # shared between auth group only

-- (dashboard)/
              /page.tsx      # home page
              /layout.tsx

-- layout.tsx                # main layout, used in ALL pages
         

for more info, take a look at these two example projects:

Ali80
  • 6,333
  • 2
  • 43
  • 33
  • 1
    This should be marked as the correct answer. By adding `use client` to the layout, we'll not take advantage of server-side components or features such as dynamic metadata. Separating pages in route groups and handling each layout individually as this answer proposes seems to be the correct pattern for me. – soutot Aug 09 '23 at 18:44
0
  • you can check if path then apply component or not on layout
  • you can access path from header:
    • const headersList = headers();
    • const pathname = headersList.get("x-invoke-path") || "";
  • apply condition to display component or not

#Full example layout.jsx:

export default async function RootLayout({children}) {
   const headersList = headers();
   const pathname = headersList.get("x-invoke-path") || "";
   const specificRoute = "/resume";  // exclude specific router

   return (
       <html>
         <body>
           {pathname !== specificRoute && <Navbar />}
           {children}
           {pathname !== specificRoute && <Footer />}
         </body>
       </html>
  );
}

This way make you can apply or not apply your layout or part of your layout without change your component to client component

I hope that help you.

me react
  • 1
  • 2