PresentationInteractive, narrated presentation of the section content.

ContentDetailed description of the section content.

Creating Layouts and Pages in Next.js

1. Introduction or Motivation

Hey everyone! In this section, we're diving into a crucial aspect of web development: creating layouts and pages. Why is this important? Well, imagine building a website without any structure. It'd be like trying to find a specific book in a library with no shelves or organisation – a complete mess! Next.js provides a fantastic solution using a file-system-based routing system, making it incredibly easy to organise our web applications. Think of it as creating a well-organized library where every book (page) has its designated place, and shared sections (layouts) like the library's reception area or cafe are consistent across different sections. We'll use a blog website as our running example throughout this lesson. We want to be able to filter blog posts based on the properties of the blog post.

2. Lecture: Building Our Blog with Next.js Layouts and Pages

Let's start by understanding the fundamental building blocks: pages and layouts.

2.1 Pages: The Content of Our Blog

A page is simply the user interface displayed at a specific URL. It's the actual content of our blog posts, the "books" in our library analogy. In Next.js, creating a page is as easy as creating a file inside the app directory and exporting a React component.

Simple Example

Let's create our homepage (app/page.tsx):

export default function Page() {
  return <h1>Welcome to My Blog!</h1>;
}

This simple component renders "Welcome to My Blog!" when a user visits the root URL (/).

Advanced Example

Now, let's create a page for all blog posts (app/blog/page.tsx):

import { getPosts } from '@/lib/posts'
import { Post } from '@/ui/post'

export default async function Page() {
  const posts = await getPosts()

  return (
    <ul>
      {posts.map((post) => (
        <Post key={post.id} post={post} />
      ))}
    </ul>
  )
}

This page fetches blog post data (we'll assume getPosts is a function that retrieves this data) and renders a list of Postcomponents, each representing a single blog post.

2.2 Layouts: The Shared Structure of Our Blog

A layout is UI shared across multiple pages. Think of it as the consistent header, footer, or sidebar of our blog. Layouts help maintain a consistent look and feel and prevent code duplication. In Next.js, we create a layout by exporting a React component from a layout.tsx file.

Simple Example

Let's create a root layout (app/layout.tsx):

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

This layout provides the basic HTML structure, a header, a main content area (where our pages will be rendered), and a footer. The children prop is crucial; it's where Next.js injects the content of the current page.

  • Advanced Example: Let's add a layout specifically for our blog section (app/blog/layout.tsx):

TypeScript

 

export default function BlogLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <section>
      <h2>Blog Posts</h2>
      {children}
    </section>
  );
}

This layout adds a title ("Blog Posts") above the actual blog post content. Now, when a user visits /blog, they'll see the root layout (header, footer) and the blog layout (title).

2.3 Nested Routes: Organizing Our Blog Content

As our blog grows, we might want to organize posts into categories or have individual pages for each post. This is where nested routes come in. In Next.js, we use folders to create nested routes.

  • Simple Example: To create a page for individual blog posts (e.g., /blog/my-first-post), we create a folder [slug] inside app/blog/ and add a page.tsx file:

TypeScript

 

// app/blog/[slug]/page.tsx
export default function PostPage() {
  return <h1>Individual Blog Post</h1>;
}

The [slug] is a dynamic route segment. It means Next.js will create a page for every possible value of slug (e.g., "my-first-post", "another-post").

  • Advanced Example: Let's display the actual content.

TypeScript

 

// app/blog/[slug]/page.tsx
import { getPostBySlug } from '@/lib/posts';

export default async function PostPage({ params }: { params: { slug: string } }) {
  const post = await getPostBySlug(params.slug);
  return (
      <div>
          <h1>{post.title}</h1>
          <p>{post.content}</p>
      </div>
  );
}

We fetch the specific post based on the slug and display its title and content.

2.4 Linking Between Pages: Navigating Our Blog

Finally, we need a way to navigate between pages. Next.js provides the <Link> component for this.

  • Simple Example: In our Post component (app/ui/post.tsx):

TypeScript

 

import Link from 'next/link';

export default function Post({ post }) {
  return (
    <li>
      <Link href={`/blog/${post.slug}`}>{post.title}</Link>
    </li>
  );
}

This creates a link to the individual blog post page.

  • Advanced Example: Let's imagine we want to filter our blog posts by category. We can create a dynamic route like /blog/category/[categoryName] and use the router to access the category.

TypeScript

 

// app/blog/category/[categoryName]/page.tsx
import { useRouter } from 'next/router';
import { getPostsByCategory } from '@/lib/posts';

export default async function CategoryPage() {
    const router = useRouter();
    const { categoryName } = router.query;
    const posts = await getPostsByCategory(categoryName);
    return (
        <ul>
            {posts.map((post) => (<Post key={post.id} post={post} />))}
        </ul>
    );
}

3. Conclusion

Today, we learned how to create layouts and pages in Next.js using its file-system routing. We explored pages, layouts, nested routes, and linking between pages. Remember, layouts provide shared UI, while pages display specific content. Nested routes allow for complex URL structures, and the <Link> component enables smooth navigation. By structuring our blog with layouts and pages, we ensure a well-organized, user-friendly, and maintainable website. Understanding these concepts is fundamental to building any Next.js application.

No hints available.

Discuss with OthersAsk questions, share your thoughts, and discuss with other learners.

Loading discussion ...