Learn why Gartner just named Builder a Cool Vendor

Announcing Visual Copilot - Figma to production in half the time

Builder.io logo
Contact Sales
Contact Sales

Blog

Home

Resources

Blog

Forum

Github

Login

Signup

×

Visual CMS

Drag-and-drop visual editor and headless CMS for any tech stack

Theme Studio for Shopify

Build and optimize your Shopify-hosted storefront, no coding required

Resources

Blog

Get StartedLogin

‹ Back to blog

Web Development

A Visual Guide to Layouts in Next.js 14

June 15, 2023

Written By Vishwas Gopinath

In our previous article on routing, we explored the concept of pages in Next.js. We learned that a page represents a unique UI for a specific route. However, in many cases, we want to have a consistent layout across multiple pages in our application, such as a header at the top and a footer at the bottom. With the introduction of layouts in the app router, achieving this in Next.js becomes much easier and more flexible.

Layouts in Next.js

So, what exactly are layouts? A layout in Next.js is a UI component that is shared between multiple pages in an application. It allows us to define a common structure and appearance for a group of pages, reducing redundancy and promoting code reusability. Since version 13, Next.js provides built-in support for layouts, making it simpler to create and manage them.

To create a layout, we need to define a React component that exports as the default from a file named layout.js or layout.tsx (if you’re using TypeScript). This component should accept a children prop, which will be populated with the content of the child page during rendering. This way, the child page becomes a part of the layout, and we can design a consistent UI around it.

With create-next-app, Next.js also automatically generates a special layout file called layout.tsx in the app folder.

// app/layout.tsx

export const metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

This file serves as the top-most layout, often referred to as the Root layout, and is mandatory for every Next.js application. Even if you delete the layout.tsx file, Next.js regenerates it based on the default layout.

Let's take a closer look at the code within the generated layout.tsx file. The layout component contains a children prop, which represents the child page component rendered within the layout. In the browser's HTML structure, there’s an <html> tag with the lang="english" attribute, followed by a <body> tag. Inside the <body> tag, the page corresponding to the route is rendered.

Here’s the same layout with a Header and Footer component.

// app/layout.tsx

import Header from './header'
import Footer from './footer'

export const metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <Header />
        {children}
        <Footer />
      </body>
    </html>
  );
}

The header and footer can be customized according to our needs, providing the desired layout structure and styles. It's important to note that since the layout is applied to every page, the header and footer will be visible regardless of the current route. This means that if we navigate to different pages like /about or /products, the header and footer sections will remain consistent.

In addition to the Root layout, the app router also introduces the concept of nested layouts. This feature allows us to define layouts specific to certain areas of our application.

Consider a product details page that dynamically reads the product ID from the route parameters. Here is the folder structure for the dynamic route:

The app folder contains a layout file and the products folder. The products folder, in turn, contains the dynamic [productId] folder.

Frame 360 (2).png

The page.tsx file in the [productId] folder contains the ProductDetails component. This component receives route parameters as a prop, which is used to display the product ID in the JSX.

export default function ProductDetails({
  params,
}: {
  params: { productId: string };
}) {
  return <h1>Details about product {params.productId}</h1>;
}

If we want to create a layout specifically for the product details page, we can create a separate layout.tsx file within the [productId] folder. The nested layout file can have its own structure and content, tailored specifically to enhance the display of product details pages. Here’s the code for product details layout file:

// app/products/[productId]/layout.tsx

export default function ProductDetailLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      {children}
      <h2>Featured products</h2>
      {/* Carousel of featured products */}
    </>
  );
}

We define the nested layout as a React component, similar to the Root layout, and it should also accept a children prop. In this case, the children prop represents the content of the product details page. As part of the layout, we render a carousel of featured products.

By nesting layouts, we can create a hierarchy of shared UI components that apply only to specific areas of our application. For instance, the Root layout can contain the main structure, such as the header and footer, while the nested layout within the productId folder can focus on displaying featured products related to that specific product.

With the introduction of layouts in the app router, we gain tremendous flexibility and customization options. We can define consistent UI structures across multiple pages, reduce code duplication, and easily manage the shared components. Nested layouts take this concept even further, enabling us to create specialized layouts for different sections of our application.

Introducing Visual Copilot: convert Figma designs to high quality code in a single click.

Try Visual Copilot

Share

Twitter
LinkedIn
Facebook
Hand written text that says "A drag and drop headless CMS?"

Introducing Visual Copilot:

A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot
Newsletter

Like our content?

Join Our Newsletter

Continue Reading
AI8 MIN
Generate Figma Designs with AI
November 25, 2024
Design to code5 MIN
Builder.io Named a Cool Vendor in the 2024 Gartner® Cool Vendors™ in Software Engineering: User Experience
November 21, 2024
AI8 MIN
How to Build Reliable AI Tools
November 15, 2024