NextJS Course (2/9) – Navigation, routing, and layouts in Next.js

Welcome back to part 2 of this tutorial series. In this part, we’ll first get started by looking at how to create and navigate between multiple pages in Next.js, as just having a single page is not very useful!

Routing in Next.js

Routing in Next.js is very easy and almost magical even. Where in every other framework you have to manually define routes, in Next.js, you just create a new folder with a specific file inside it and a new route will be created. So let’s have a look at how this works.

Our current πŸ“ app folder directory looks like this:

πŸ“ app
    πŸ“„ favicon.ico
    πŸ“„ globals.css
    πŸ“„ layout.tsx
    πŸ“„ page.tsx

The page.tsx simply refers to the main page of the website. All we have to do to create a new route and page for that route is to add a new folder and make sure it also has a page.tsx file inside, and then Next.js will automatically detect this and create a new route for us.

So add a new folder named blockbuster_chat inside the app folder and create a new file named page.tsx inside it. The directory structure should look like this:

πŸ“ app
    πŸ“ blockbuster_chat
        πŸ“„ page.tsx
    πŸ“„ favicon.ico
    πŸ“„ globals.css
    πŸ“„ layout.tsx
    πŸ“„ page.tsx

Now open up the page.tsx file inside the blockbuster_chat folder and let’s create and export a React component in here. As this uses a bunch of boilerplate code which will be the same for every page, we can use the shortcuts extension we installed in part 1 and just type rafce and hit enter to create a new React component.

Wait what?! rafce? Ok, I’ll make it easier to remember. Rambo’s Army Fights Criminal Easterbunnies:

You’re welcome. πŸ˜… So simply type rafce and hit enter and you will have the following boilerplate code:

import React from 'react'

const page = () => {
  return (
    <div>page</div>
  )
}

export default page

This is just the standard boilerplate code for a React component, importing React and exporting the component. The component itself is just a const (constant, or a variable that can’t be changed after declaration) named page.

This component uses an arrow function () => {} which is a shorthand way of writing a function in JavaScript. As the () is empty, this function doesn’t take any arguments for now and simply returns a div element with the text page inside it. If the syntax still looks a bit weird to you, don’t worry, you’ll get used to it soon enough. Now just make some slight edits like this:

import React from 'react'

const BlockBusterChat = () => {
  return (
    <div>Welcome to BlockBuster Chat!</div>
  )
}

export default BlockBusterChat

So all we return here is a single div element with the text Welcome to BlockBuster Chat! inside it. Make sure you still have your server running in the terminal or run npm run dev (while making sure you are in the project folder) to start it up. Now save the file, go back to your browser, and navigate to http://localhost:3000/blockbuster_chat. You should see the text Welcome to BlockBuster Chat! displayed on the page:

Tadaa! You just created a new page in Next.js. πŸŽ‰ Now I’ll be the first to admit that it doesn’t look very good right now, but we still have our http://localhost:3000/ page and have now added this separate route as well, without having to set up the usual server-side routing logic like you would have to do with frameworks like Django etc. That is really powerful!

Creating a navigation bar

The next thing we want is to have a navigation bar to allow the user to actually click and navigate between these pages. Since we want this navigation to always be visible on all pages we can use our layout.tsx file to define this, so it shows up everywhere.

We don’t want to make our layout.tsx file too big and complex though, remember the Single Responsibility Principle, or Separation of Concerns? So let’s create a new file named navbar.tsx inside the app folder and add the following code to it:

πŸ“ app
    πŸ“ blockbuster_chat
        πŸ“„ page.tsx
    πŸ“„ favicon.ico
    πŸ“„ globals.css
    πŸ“„ layout.tsx
    πŸ“„ navbar.tsx      ✨ New file
    πŸ“„ page.tsx

Now open up the navbar.tsx file and start with the imports up top:

import React from 'react';
import Link from 'next/link';

Obviously, our navbar will be a React component, so we need to import React. What is the Link import though? This is a special component provided by Next.js which allows us to create links between pages in our app.

If you’re familiar with HTML, you might know the <a href> tag which is used to create links. The problem with this tag is that it reloads the entire page when you click on it, which is not very efficient. The Link component provided by Next.js solves this problem by only loading the content that changes, and not the entire page. This gives us that SPA (Single Page Application) feel, where only the content changes and not the entire page.

Now let’s create a Navbar component. We’ll keep it simple and build one first by just listing what we need. If you notice the repetition, don’t worry, I’ll show you how to improve this afterward. Just like we’ve seen so far, we need a function that will return some JSX code containing the React elements we want to render:

const Navbar = () => {
  return (
    <nav className="bg-emerald-700 text-white p-4">
      <ul className="flex justify-between items-center">
        <li className="mx-4">
          <Link href="/" className="hover:text-gray-300">Home</Link>
        </li>
        <li className="mx-4">
          <Link href="/blockbuster_chat" className="hover:text-gray-300">Blockbuster Chat</Link>
        </li>
        <li className="mx-4">
          <Link href="/tbd" className="hover:text-gray-300">TBD</Link>
        </li>
        <li className="mx-4">
          <Link href="/tbd2" className="hover:text-gray-300">TBD2</Link>
        </li>
      </ul>
    </nav>
  );
}

export default Navbar

This is a simple Navbar component using the = () => {} arrow function syntax. It returns a nav element which is basically just a standard HTML block element for navigation. The className is why we installed tailwindcss in part 1, as it allows us to use these classes to style our elements.

The bg-emerald-700 class, where bg is simply background, gives the navigation bar a green background color, text-white makes the text white, and p-4 adds some padding around the content so it doesn’t go all the way to the edge.

These classes can be assigned to your liking by just changing the name, for instance:

  • bg-emerald-700 -> You can simply change the emerald part to any other color you like. As for the 700, this is the shade of the color, where 100 is the lightest and 900 is the darkest.
  • text-white -> This one is obvious now, you can change the color to any other color you like!
  • p-4 -> This is the padding, where 4 is the amount of padding, with lower numbers giving less padding and higher numbers giving more.

Using these classes is a very quick and easy way to style your elements without having to write a lot of CSS, which saves us a bunch of time and shows why tailwindcss is so popular.

Inside the nav element, we have an HTML ul element which stands for unordered list and serves to wrap the list of our navigation links together. The Tailwind classNames here are flex to activate flexbox, justify-between to space the items evenly with space in between, and items-center to center the items vertically.

If you’re not familiar with this, you’ll see how it works on the page in a moment. CSS flexbox is too big of a topic to cover here but also not very important for this tutorial series, so if you’re not sure about this part don’t get hung up on this one too much.

Inside that we have multiple li elements which stand for list items, using the mx-4 class to add some margin on the x-axis (left and right) to space the items out a bit. Inside each li element we have the Link component we imported at the top, which is used to create links between pages in our app.