DEV Community

Cover image for Beginner's Guide to Understand Next.js App Routing
Varshith V Hegde
Varshith V Hegde

Posted on

Beginner's Guide to Understand Next.js App Routing

Hello Everyone, hope you’re all doing awesome!

Today, I’ve brought you a new topic to discuss: App Routing in Next.js.

If you've clicked on this blog, it likely means you’ve either started working with Next.js or are looking to start. Without further ado, let’s dive in!

We’ll create an example webpage, routing-example, to better understand routing.

Why Do You Need Routing?

When you visit a website, there's usually a navbar at the top, allowing you to navigate to various pages of the site. Even for a static page like a landing page, this is a common practice. It makes it easier for the user to directly access the page they want.

Different Types of Routing in Next.js

There are basically two types of routing in Next.js:

  1. App Routing (a very common and standard practice)
  2. Page Routing

In Page Routing, the app doesn't have an app folder structure but instead uses a pages folder where each route is represented by a file. For example, if you want a route /about, you would create a folder named pages and inside it, an about.tsx or about.jsx file.

But this method is now outdated and has been replaced by App Router.

Let's explore App Router with an example.

Project Structure For Next.Js

Setting Up a Next.js Application

Make sure you have Node.js and npm installed on your system, and ensure they’re updated to the latest versions.

To create a new Next.js application, run the following command:
First Install the create-next-app package:

npm i create-next-app@latest
Enter fullscreen mode Exit fullscreen mode

Then to create a new next application use below command

npx create-next-app@latest routing-example
Enter fullscreen mode Exit fullscreen mode

During the setup, select these options:

  • TypeScript: Yes
  • ESLint: Yes
  • Tailwind CSS: Yes (if required)
  • src/ directory: Yes
  • App Router: Yes (this is important for using App Router) Just like below image

Project Setup

Now, open the application in VS Code (just because I love this editor 😂).

In the terminal, navigate to your project folder:

cd routing-example
Enter fullscreen mode Exit fullscreen mode

Start the application by running:

npm run dev
Enter fullscreen mode Exit fullscreen mode

You can check the boilerplate app by visiting localhost:3000.

First, remove the unwanted code in page.tsx of the main folder and replace it with the following:

src/app/page.tsx:

export default function Home() {
  return (
    <div>
      Hello world 
      Main Page
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Adding a Simple Navbar

Let’s add a simple navbar to navigate between pages.

Create a Components folder inside src/app, and inside that folder, add a new file named Navbar.tsx. The folder structure will look like this:

src/app/Components/Navbar.tsx:

"use client";
import Link from 'next/link';

const Navbar: React.FC = () => {
  return (
    <nav style={styles.navbar}>
      <ul style={styles.navList}>
        <li><Link href="/" legacyBehavior><a style={styles.link}>Home</a></Link></li>
        <li><Link href="/about" legacyBehavior><a style={styles.link}>About</a></Link></li>
        <li><Link href="/contact" legacyBehavior><a style={styles.link}>Contact</a></Link></li>
        <li><Link href="/input" legacyBehavior><a style={styles.link}>Input Name</a></Link></li>
      </ul>
    </nav>
  );
};

const styles = {
  navbar: { padding: '1rem', backgroundColor: '#333' },
  navList: { listStyleType: 'none', display: 'flex', gap: '1rem' },
  link: { color: '#fff', textDecoration: 'none' },
};

export default Navbar;
Enter fullscreen mode Exit fullscreen mode

Now, add the Navbar to all pages by updating the layout in src/app/layout.tsx:

src/app/layout.tsx:

import type { Metadata } from "next";
import localFont from "next/font/local";
import "./globals.css";
import Navbar from "./Components/Navbar";

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

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

Main Page

When you visit localhost:3000, the navbar will be visible. However, clicking any of the navbar options will result in a 404 Error because we haven’t yet created those pages.

Page Not Found

Let’s start with the Contact Page.

App Routing for Contact Page

To create a route like localhost:3000/contact, we need to create a folder inside src/app named contact, and inside it, create a page.tsx file.

The folder structure should look like this:

src
 |-> app
      |-> contact
             |-> page.tsx
Enter fullscreen mode Exit fullscreen mode

Contact Folder Structure

Inside page.tsx, add the following code:

src/app/contact/page.tsx:

export default function Contact() {
  return (
    <div>This is the Contact Page</div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Now you can test the contact page.

Go to localhost:3000 and click on the Contact item in the navbar. It will load the contact page with the message "This is the Contact Page." If it's not loading properly, double-check the folder structure.

Repeat for the About Page

You can follow the same steps to create the About page:

  1. Create a folder about inside src/app.
  2. Inside the about folder, create a page.tsx file with this content:
export default function About() {
  return (
    <div>This is the About Page</div>
  );
}
Enter fullscreen mode Exit fullscreen mode

With these steps, you’ve now set up basic static pages using Next.js App Routing.

Dynamic App Routing in Next.js

What if we want to create dynamic routes, like profile pages where the URL changes based on a username? For example, GitHub profile URLs like https://github.com/Varshithvhegde, where /Varshithvhegde is a dynamic part of the URL.

Next.js allows us to handle such dynamic routes easily. Let’s walk through an example of creating a dynamic route that shows a welcome message based on a user’s name.

We’ll first create an Input Name page where a user can type their name, and on submission, it will dynamically generate a URL like localhost:3000/input/name.

Url Access Structure

Step 1: Create the Input Page

Create a folder input inside src/app, and then inside the input folder, create a page.tsx file.

src/app/input/page.tsx:

"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";

const NamePage: React.FC = () => {
  const [name, setName] = useState<string>("");
  const router = useRouter();

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setName(e.target.value);
  };

  const handleSubmit = () => {
    router.push("/input/" + name);
  };

  return (
    <div style={styles.container}>
      <h1 style={styles.heading}>Enter Your Name</h1>
      <input
        type="text"
        value={name}
        onChange={handleInputChange}
        placeholder="Type your name"
        style={styles.input}
      />
      <button type="button" onClick={handleSubmit} style={styles.button}>
        Submit
      </button>
    </div>
  );
};

const styles = {
  container: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'center',
    height: "100vh",
    backgroundColor: "#f4f4f4",
  },
  heading: {
    marginBottom: "1rem",
    fontSize: "24px",
    color: "#333",
  },
  input: {
    padding: "0.5rem 1rem",
    fontSize: "16px",
    borderRadius: "5px",
    border: "1px solid #ccc",
    width: "200px",
    marginBottom: "1rem",
  },
  button: {
    padding: "0.5rem 1rem",
    fontSize: "16px",
    backgroundColor: "#0070f3",
    color: "#fff",
    border: "none",
    borderRadius: "5px",
    cursor: "pointer",
    transition: "background-color 0.3s ease",
  },
};

export default NamePage;
Enter fullscreen mode Exit fullscreen mode

No need to worry about the code . It has a input for entering the name and then a submit button . And instead of using <Link/> we are using useRouter() to handle the navigation programmatically. useState() is used to hold the value of the name .

But still it is not completed we havn't created page to get the value of the name that you submitted .

Input Page

Step 2: Create the Dynamic Route Page

To handle dynamic routes, we need to create a folder for the dynamic segment of the URL. In our case, it will be the user’s name. To achieve this, create a folder named [name] inside the input folder, and inside it, create a page.tsx file.

The folder structure will now look like this:

src
 |-> app
      |-> input
             |-> page.tsx
             |-> [name]
                    |-> page.tsx
Enter fullscreen mode Exit fullscreen mode

Dynamic Routing Project Structure

Inside src/app/input/[name]/page.tsx, add the following code:

export default function Name({ params }: { params: { name: string } }) {
  return (
    <div style={styles.container}>
      <div style={styles.card}>
        <h1 style={styles.heading}>Hello, {params.name}!</h1>
      </div>
    </div>
  );
}

const styles = {
  container: {
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '90vh',
    backgroundColor: '#f0f0f5',
  },
  card: {
    padding: '2rem 3rem',
    backgroundColor: '#fff',
    borderRadius: '10px',
    boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)',
    textAlign: 'center',
  },
  heading: {
    fontSize: '36px',
    fontWeight: 'bold',
    color: '#333',
    margin: 0,
  },
};
Enter fullscreen mode Exit fullscreen mode

In this dynamic page, we’re accessing the name parameter from the route using params.name. The name is dynamically pulled from the URL and displayed on the page.

So to get the value from the route we are using params so in the code name : string the name should be same as the folder name [name] . So for example , if you create folder as [username] then in the code you need to change it as username : string keep this in mind .

Step 3: Testing Dynamic Routing

Now, you can test the dynamic routing:

  1. Go to localhost:3000/input.
  2. Enter a name in the input field (e.g., "Varshith").
  3. Click Submit.

You’ll be redirected to localhost:3000/input/Varshith, and the page will greet you with "Hello, Varshith!"

Welcome Hello Page

Conclusion

Next.js App Routing provides an efficient and organized way to handle both static and dynamic routes. By using folder structures that map directly to routes, it makes setting up navigation simple and intuitive. With dynamic routes, you can easily create pages that respond to user-specific input, like profiles or custom data views.

That’s it for now! I hope this tutorial helped you get a better understanding of routing in Next.js. You can find the complete code on GitHub: https://github.com/Varshithvhegde/routing-example.

Feel free to leave your feedback or questions in the comments. Until next time, happy coding!

Quick Links

Top comments (0)