Elevate your Next.js 13 application by utilizing improved routing features, flexible layout options, and optimized links
Tags: nextjs, routing, layouts, links
Published: 2023-04-04 12:09:10

In this series, we’re continuing through the basics of learning the new features of the static site generator, [Next.js 13](https://nextjs.org/).

## Introduction

In the previous lesson, we learned how to start a new [Next.js 13](https://nextjs.org/) project and reviewed all the files you get.

Today we'll dig deeper and look at how we can construct pages and layouts in the new [Next.js 13](https://nextjs.org/) **app directory**, and we'll also look at some basic **routing**.

![0](https://cdn.hashnode.com/res/hashnode/image/upload/v1680598308584/cc7b01eb-0670-4fda-be32-3f6e269d82af.png)

### Prerequisites

If you intend to follow along with this tutorial on your system, please ensure you have the following:

- A basic understanding of working with the terminal.
- A Laptop or PC with Windows installed
- An Internet connection
- [Git](https://git-scm.com/) is installed on your local machine (optional). For more details on accomplishing this, review [Installing & Setting Up Git on Windows](https://creativelightbox.net/how-to-install-git-bash-for-windows-to-your-local-system).
- A [GitHub](https://github.com/) account. For more details on accomplishing this, review [How to get started with Git and GitHub](https://creativelightbox.net/how-to-get-started-with-git-and-github)
- The latest version of [Visual Studio Code](https://code.visualstudio.com/) is installed on your machine.
- Basic knowledge of [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML), [CSS](https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/CSS_basics), [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript), and [React](https://react.dev/).

> **Note:** This is a follow-up tutorial, it does require you to have created the "1. Getting Started" tutorial, as covered in the article [Getting Started with Next.js: A Comprehensive Guide to Building Your First Application](https://creativelightbox.net/getting-started-with-nextjs-a-comprehensive-guide-to-building-your-first-application#heading-creating-a-nextjs-13-project) to make the most of it.

**Let’s get started!**

## Creating a Starter Project

You can see we've got [Visual Studio Code](https://code.visualstudio.com/) open, where our completed code for the previous part **nextjs-one** of this beginner series is, which is essentially the starter project that you get after you install [Next.js 13](https://nextjs.org/).

![1](https://cdn.hashnode.com/res/hashnode/image/upload/v1680598420661/b9742803-b20e-4461-b708-61c363552dfc.png)

Let's get started by making a copy of **nextjs-one** and renaming the file to **nextjs-two** inside our **nextjs-series** directory.

![2](https://cdn.hashnode.com/res/hashnode/image/upload/v1680598448470/886fb1e0-36cc-49f7-8869-0240079fecc2.png)

I'm going to open up this **nextjs-two** directory with [Visual Studio Code](https://code.visualstudio.com/) and we can see everything that was installed from **nextjs-one** is over here in the file tree, but we need to change some of the contents of the `package.json` file,

![3](https://cdn.hashnode.com/res/hashnode/image/upload/v1680598458697/29ef8372-07af-4885-8627-6c27f5cc1906.png)

and the `packages.lock.json` file as well.

![4](https://cdn.hashnode.com/res/hashnode/image/upload/v1680598468479/df761a04-83b6-4085-8cde-085160893d3c.png)

## Routing between pages

Now, just to recap quickly, we changed the contents of the home page, the `page.tsx` file, the default page, and if you followed along with part one, that's in the new **app directory** for [Next.js 13](https://nextjs.org/).

![5](https://cdn.hashnode.com/res/hashnode/image/upload/v1680598483148/9bfee431-30db-475d-ba9d-645dd3d66853.png)

In this app directory, let's create another directory inside of it, and let's call this directory **about.** Inside the **about directory** let's create another `page.tsx` file.

To create a new `page.tsx` file here and put that inside a directory called **about**, rather than first creating the **about** directory and then creating the new file inside of that, we can just click the new file button and then type `about/page.tsx` and hit enter. We can see when that file within that directory was created.

![6](https://cdn.hashnode.com/res/hashnode/image/upload/v1680598495000/bd7cc799-1f17-4395-be9f-0a68df191afe.png)

If we type **RFC** for **react functional component** and see that choice right there, we're going to select that.

![7](https://cdn.hashnode.com/res/hashnode/image/upload/v1680598505463/dd1bbfe9-7e72-4636-8190-7d1699fa4b67.png)

> **Note** that's not part of [Next.js 13](https://nextjs.org/) -that is an **ES7 react Snippets extension** that we can use, we just need to head over **Extensions** and we're going to search for **VS Code ES7+ React/Redux/React-Native/JS snippets**

![8](https://cdn.hashnode.com/res/hashnode/image/upload/v1680598695503/da4d0639-17b5-4699-9cbe-0423a736fa9e.png)

This extension is very good with those snippets, so you can type those abbreviations and complete those functional components very easily.

If we go back to the project, we have our basic functional component for the page, but we could name it **About** with a capital letter.

```javascript
import React from "react";

export default function About() {
  return <div>page</div>;
}
```

If we look back at the older `page.tsx` file notice they didn't name this page either; it's named **Home** so we want to name the functional component what it actually is, **about** however the page itself is named `page.tsx`. We go ahead and save the page.

This is how basic routing and pages are created in [Next.js 13](https://nextjs.org/).

### Accessing the Development Site

So let's go ahead and open a terminal window, and I'm going to type in the following:

```bash
npm run dev
```

In the meantime, when we want to have a different page that we could link to or navigate to, we want to create a directory for that page. Now, if we look at our page, you can see we're just returning a `<div>` that says: **page.**

![9](https://cdn.hashnode.com/res/hashnode/image/upload/v1680599042551/d09966ba-815e-41e7-b957-55e54a3c2ccd.png)

We would go to `http://localhost:3000` and then navigate to `/about`, and if we press **enter**, we have the word **page** displaying there (it's very small) at the top left corner.

![10](https://cdn.hashnode.com/res/hashnode/image/upload/v1680599064222/17f4219b-47ed-4e8b-9473-85ccff1ba0db.png)

We could change what we have in here; maybe we make it a little bit bigger, maybe even apply just some CSS, but we know we do have a second page now, and we can navigate to it with `/about`.

If we go back to the home page, we're going to make one simple change here, and that is to turn this `<div>` into a header `<h1>`, it's a little bit bigger and easier to see, and then we going to turn the word **page** into the word **About**, with capital letter ‘A’, so we know we're on the about page.

```javascript
import React from "react";

export default function About() {
  return <h1>About</h1>;
}
```

## Creating a root layout component

Let's look at the `layout.tsx` file that's in the parent **app directory** and for this `layout.tsx` applies to the entire site or the entire application, so anything we would put there, would be affected on every other page as well.

![11](https://cdn.hashnode.com/res/hashnode/image/upload/v1680599109531/51e68b3e-2566-4bd4-af5c-490c20a11f8f.png)

For example, we could add an `<nav>` element, not by creating a separate component but just inside the `<body>` here, and if we look better, the body returns all of the child components inside of the application, but then we could have a component above that we defined, so if we created a _navbar_ element in a separate component, we could import that and that would work as well, but for now we're just going to use the `<nav>` element and then inside of the `<nav>` element we're going to add an `h1` and with the text **Navbar** and **save**.

```html
return (
  <html lang="en">
    <body>
      <nav>Navbar</nav>
      {children}
    </body>
  </html>
);
```

If we can look at the application running on `http://localhost:3000` we have **Navbar** there at the top left corner of our **Home page**

![12](https://cdn.hashnode.com/res/hashnode/image/upload/v1680599225416/314bf70c-84bd-4767-9230-9774ce8c91c9.png)

but if we click forward to `/about` page, we also have that **Navbar** on the `/about` page, so this **parent** `layout.tsx` applies to all the pages on the application.

![13](https://cdn.hashnode.com/res/hashnode/image/upload/v1680599254053/fac2d32a-b80e-42f0-9ea4-6482158c3be9.png)

## Creating a nested layout component

We want to create another **layout**, that will only apply to anything in the **about folder** or better yet, the **about tree**, which means it will only apply to any pages that start with the `/about,` and of course, we could have **sub-directories** and **other pages** that follow that path. For example, we could have a **sub-page** or **directory** in the **about directory**.

We're going to create another `layout.tsx` file inside of the **about directory**.

Let's start again by typing **RFC**, If we notice the function is not going to have the name **layout**, but that's not what we want, right?

![14](https://cdn.hashnode.com/res/hashnode/image/upload/v1680599290255/2b138a70-4af7-401c-8ede-5429a036e16b.png)

Let's look back at what we were given from our earlier starter files, and we can see this was named **RootLayout**.

We're copying (Ctrl + C) from the beginning of the **RootLayout** and going down to the return with the parentheses included.

```javascript
RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
```

We head over to our newly created ´layout.tsx`, and we'll return something different, but we need the same types, and we'll need to change the name to **AboutLayout**.

Let's paste (Ctrl + V) the code we copied above in there and Rename it to **AboutLayout**.

~~~javascript
export default function AboutLayout({
  children,
}: {
  children: React.ReactNode,
}) {
  return <div>layout</div>;
}
~~~

Notice in the return of the parent directory for **app,** that the starter file `layout.tsx` it has the `<html lang="en">`. We only want one of those per page, and really per site because this applies to everything. Anything we have below is considered a child `{children}` and it's right here in our HTML structure.

~~~html
return (
<html lang="en">
  {/*
  <head />
  will contain the components returned by the nearest parent head.tsx. Find out
  more at https://beta.nextjs.org/docs/api-reference/file-conventions/head */}
  <head />
  <body>
    <nav>
      <h1>Navbar</h1>
    </nav>
    {children}
  </body>
</html>
)
~~~

Going back to our new `layout.tsx` inside the **about directory**, we could just start with a fragment.

~~~javascript
export default function AboutLayout({
  children,
}: {
  children: React.ReactNode,
}) {
  return (
    // FRAGMENT
    <></>
  );
}
~~~

Now we put a _nav element_ and we can call this the **About Navbar** After this `<nav>About Navbar</nav>`, let's go ahead and put a `<main></main>` element inside. The `<main></main>` element is where we'll put the `{children}` for this **AboutLayout**.

To finish this, we'll go ahead and save that file.

The file `layout.tsx` will look like this:

~~~javascript
export default function AboutLayout({
  children,
}: {
  children: React.ReactNode,
}) {
  return (
    <>
      <nav>About Navbar</nav>
      <main>{children}</main>
    </>
  );
}
~~~

In our browser again, looking at the **home page**, let's go to the URL and add `/about`.

~~~markdown
http://localhost:3000/about
~~~

Now we have the **Navbar** that applies to the entire application, then we have the **About Navbar** under that, and lastly, we have the word **About** underneath.

![15](https://cdn.hashnode.com/res/hashnode/image/upload/v1680599331071/27eab565-7117-44a9-ab61-f14260a284ca.png)

> **Note:** We can use the forward and back buttons to navigate between pages.

## Adding links to pages

Let's go and add some **links** to our pages to navigate between the two as well, so I'll come back to Visual Studio Code. Let's visit the page inside of the **about directory** and we'll add a link there first, so at the top of the page I need to add:

~~~javascript
import Link from "next/link";
~~~

> If you're familiar with [react-router](https://reactrouter.com/en/main), this is a lot like using react-router when we import a link there from that library.

After we add the **import** we're going to add a fragment here and put an `<h>` inside of that fragment.

~~~html
<>
  <h1>About</h1>
</>
~~~

I'm just going to `<Link>` this back to the home page, so that's just the `"/"` for the root directory, and then we'll have a link to the home page just for the text.

~~~html
<Link href="/">Link to Home Page</Link>
~~~

The `about/page.tsx` file should now look like the following:

~~~javascript
import Link from "next/link";

export default function About() {
  return (
    <>
      <h1>About</h1>
      <Link href="/">Link to Home Page</Link>
    </>
  );
}
~~~

When we **save** the file, we can see in the browser if that **link** has been added, so we need to go forward to our **/about**, and there it says: **Link to Home Page** and yes, we get a pointer with our cursor, and when we click that, we go back to the **home page**.

![16](https://cdn.hashnode.com/res/hashnode/image/upload/v1680599357859/0eb0a17e-8780-4448-8b3a-814d53b5be20.png)

Now let's do the same for the **home page**. When we come back to the `page.tsx` in the app directory `app/page.tsx`, notice **not inside** the **about directory**,

and here we can import a link as well.

~~~javascript
import Link from "next/link";
~~~

Just underneath the **Hello, welcome** we'll put another link there.

~~~javascript
<h1 className={inter.className}>Hello</h1>

<h2 className={inter.className}>Welcome to...</h2>
~~~

I am going to add a **line break** and type **Go to About Page** between **Link** and **save** the file.

~~~javascript
<br />
<Link href="/about">Go to About Page</Link>
~~~

The `app/page.tsx` file should now look like the following:

![17](https://cdn.hashnode.com/res/hashnode/image/upload/v1680599406780/496af9f9-6272-41d6-ba1a-cb7214aae5fb.png)

After saving, we can see in the browser that the **Go to About Page** link has been added, so we need to go forward to our **/about**, and there it says: **Link back to Home Page** as we saw before, and yes, we also get a pointer with our cursor, and when we click that, we go forward to the **about page**.

## Conclusion

In this article, we learned how to use the new experimental app directory in [Next.js 13](https://nextjs.org/). We also saw how we create new pages within the app folder and how we create another folder within the app directory where we can create more pages, route them, and link to them.

The patterns and conventions we learned in this article are still experimental features that [Next.js 13](https://nextjs.org/) is implementing while moving forward, however, they are already very useful, and we can already start using them in our projects

[Next.js 13](https://nextjs.org/) is constantly incrementing these new features and adding some new ones, so I'll try to cover those if they continue during this beginner series; however, I prefer to publish the new features rather than the previous ones, because this is the direction that [Next.js 13](https://nextjs.org/) is headed in the future.

## What's next?

During our upcoming part 3, we will delve into the topics of CSS modules, adjustments with metadata, and loading. It is important to prioritize progress rather than perfection, as even small advancements made each day can lead to significant results.

**Thanks for the read! Now go practice & build something awesome!**