Made in Builder.io

Join us for an AI launch event by

Builder.io and Figma
Talk to Us
Product
Developers
Talk to Us

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 13

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 Next.js version 13, achieving this 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. In 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, Next.js 13 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 Next.js 13, 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.

Don't miss our AI launch event on Oct. 12 

Claim your ticket

Share

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

We are launching something exciting soon...

Claim your ticket

Like our content?

Join Our Newsletter

Continue Reading
Newsletters15 MIN
Bun vs. Node.js, A first look at HTMX, Visual Headless CMS why and how + Builder Velocity
WRITTEN BYYoav Ganbar
September 22, 2023
Web Development25 MIN
Bun vs Node.js: Everything you need to know
WRITTEN BYVishwas Gopinath
September 19, 2023
Web Development15 MIN
A First Look at HTMX and How it Compares to React
WRITTEN BYYoav Ganbar
September 15, 2023