Next.js using layouts to wrap sub-routes (or nested routes) is an effective way

In Next.js, using layouts to wrap sub-routes (or nested routes) is an effective way to apply consistent structure and style across various components of your application. Since Next.js does not natively support route-based layouts in the way that frameworks like Nuxt.js do, this functionality must be implemented manually. Here’s a straightforward way to achieve this using React components and Next.js’s file system routing.

Step 1: Define a Layout Component

A layout component is a React component that includes the common UI parts of your pages (e.g., header, footer, navbars). You can create multiple layouts for different parts of your app if needed.

Example Layout Component

Create a file named MainLayout.js in a components directory:

jsxCopy code

import React from 'react'; import Header from './Header'; import Footer from './Footer'; const MainLayout = ({ children }) => { return ( <div> <Header /> <main>{children}</main> <Footer /> </div> ); }; export default MainLayout;

This component includes a header and footer and a dynamic children section where sub-components will be rendered.

Step 2: Use the Layout in Page Components

In Next.js, every file under the pages directory (and subdirectories) corresponds to a route. To apply the layout, wrap the page’s content with the layout component.

Example Page Component Using MainLayout

Create a page profile.js in the pages directory:

jsxCopy code

import React from 'react'; import MainLayout from '../components/MainLayout'; const ProfilePage = () => { return ( <MainLayout> <h1>Profile Page</h1> <p>This is the profile page content.</p> </MainLayout> ); }; export default ProfilePage;

This setup uses the MainLayout for the profile page. You can apply the same layout to other pages or define new layouts for different sections of your application.

Step 3: Using Layouts for Nested Routes

If you have nested routes and want to use layouts, the approach is similar but organized differently. Suppose you have user settings pages under /user/settings with multiple sub-pages.

Organizing Nested Routes with a Specific Layout

  1. Create a Subdirectory for Nested Routes:Inside the pages directory, create a subdirectory for the main route:markdownCopy codepages/ ├── user/ └── settings/ ├── index.js ├── password.js ├── profile.js
  2. Apply Layout to Nested Routes:Each page inside the settings directory can use the MainLayout or another specific layout like SettingsLayout.jsxCopy code// pages/user/settings/profile.js import React from 'react'; import MainLayout from '../../../components/MainLayout'; const SettingsProfilePage = () => { return ( <MainLayout> <h1>Settings: Profile</h1> <p>Change your profile settings here.</p> </MainLayout> ); }; export default SettingsProfilePage;

Using a Global Layout with a Condition for Specific Pages

To apply a global layout or specific layouts based on routes conditionally:

  1. Create a _app.js File:This is where you can wrap your application in a global layout.jsxCopy code// pages/_app.js import React from 'react'; import MainLayout from '../components/MainLayout'; import App from 'next/app'; class MyApp extends App { render() { const { Component, pageProps } = this.props; return ( <MainLayout> <Component {...pageProps} /> </MainLayout> ); } } export default MyApp;
  2. Conditionally Change Layouts:If you need different layouts for different parts of your app, you can modify _app.js to include logic that selects a layout based on the pathname.jsxCopy code// pages/_app.js import React from 'react'; import MainLayout from '../components/MainLayout'; import AnotherLayout from '../components/AnotherLayout'; import App, { Container } from 'next/app'; import { useRouter } from 'next/router'; function MyApp({ Component, pageProps }) { const router = useRouter(); const getLayout = Component.getLayout || ((page) => <MainLayout>{page}</MainLayout>); return getLayout(<Component {...pageProps} />); } export default MyApp; In your page components:jsxCopy code// pages/someSpecialPage.js const SomeSpecialPage = () => <div>Special Content Here</div>; SomeSpecialPage.getLayout = function getLayout(page) { return ( <AnotherLayout> {page} </AnotherLayout> ); } export default SomeSpecialPage;

This setup offers flexibility, allowing you to specify which layout to use on a per-page basis while maintaining the ability to apply a default layout across the site. This is particularly useful for complex applications with varying UI requirements across different sections.