Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
What is file system routing?
3.
Linking pages
4.
Linking to dynamic paths
5.
Passing routing parameters
6.
Dynamic routes
7.
FAQs
8.
Key Takeaways
Last Updated: Mar 27, 2024

File System Routing

Author Toohina Barua
0 upvote

Introduction

Hyperlinks are what make the Internet what it is. While it can be used for things like linking across documents, its primary purpose is to refer to distinct online pages identified by a unique web address or URL.
As vital as hyperlinks are to the Web, routing is fundamental for every web application. It is a technique for routing requests to the code that will handle them. A unique URL path is used to refer to and identify Next.js pages.
In this article, you will read about file system routing in Next.js. Let’s dive in.

What is file system routing?

The file-system-based router in Next.js is based on the concept of pages. When you add a file to the pages directory, it becomes available as a route right away. That is, the file system is used by Next.js to facilitate routing in the app. Every file in the pages directory is automatically treated as a route by Next. In Next.js, a page is a React component with a route based on the file name. For instance, look at the following file structure:

Source

If the port your application is listening on is 3000, you can access the above pages like so:

  • Index.js is the home page accessible on http://localhost:3000
  • About.js is the contact page accessible on http://localhost:3000/about
  • Contact.js is the contact page accessible on http://localhost:3000/contact
  • blog-folder/index.js is the page located on the sub-folder Blog folder accessible on http://localhost:3000/blog-folder

So on and so forth.

Linking pages

Similar to a single-page application, the Next.js router allows you to conduct client-side route transitions between pages. This client-side route transition is handled by the Link React component.
For pages using Static Generation, any <Link /> in the viewport (initial or during a scroll) will be prefetched by default (with the appropriate data). For server-rendered routes, the associated data is not prefetched.
In the example below, we have used <Link /> to link all the pages. 
Home.js
In the following code, we first import the Link component. As you can see, the href attribute of Home is “/”. This means that when we click on the Home option, it will take us to the home page by fetching data from the home route (“/”). The url of this page will be  http://localhost:3000/ if it is listening on port 3000. Similarly, if the about option is clicked, it takes you to the about page by getting data from route /about. The address of this page would be http://localhost:3000/about. So on and so forth. 

import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link href="/">
          <a>Home</a>
        </Link>
      </li>
      <li>
        <Link href="/about">
          <a>About Us</a>
        </Link>
      </li>
      <li>
        <Link href="/contact">
          <a>Contact Us</a>
        </Link>
      </li>
      <li>
        <Link href="/blog/index">
          <a>Blogs</a>
        </Link>
      </li>
    </ul>
  )
}

export default Home

Linking to dynamic paths

Interpolation can also be used to generate the path, which is useful for dynamic route segments. For example, to display a list of posts that have been supplied to the component as a prop:
Posts.js
Instead of interpolation, we now utilize a URL object in href to build the path:

  • the name of the page in the pages directory is a pathname. In this situation, the URL is /blog/[slug].
  • query is a dynamically segmented object. In this case, it's a slug.
import Link from 'next/link'

function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          <Link
            href={{
              pathname: '/blog/[slug]',
              query: { slug: post.slug },
            }}
          >
            <a>{post.title}</a>
          </Link>
        </li>
      ))}
    </ul>
  )
}

export default Posts

Passing routing parameters

The useRouter hook or getInitialProps in Next.js allows you to pass route parameters and subsequently get the data back. It gives you access to the router object, which is where the params are stored.
Index.js
Instead of passing in a string to the href attribute, we pass in an object with a pathname field, as you can see here. This is the route, together with the data-holding query element.

import Link from "next/link"

function IndexPage() {
  return (
    <Link
      href={{
        pathname: "/about",
        query: { id: "01" },
      }}
    >
      <a>About page</a>
    </Link>
  )
}
export default IndexPage

About.js
To get the data sent in, we import the useRouter hook. Then, using destructuring, we extract it from the query object. Like so:

import { useRouter } from "next/router"

function About() {
  const router = useRouter()
  const {
    query: { id },
  } = router
  return <div>About us: {id}</div>
}

export default About

If you're utilising server-side rendering, you'll need to acquire the data using getInitialProps. Like so:

export default function About({ id }) {
    return <div>About us: {id}</div>
}
 
About.getInitialProps = ({ query: { id } }) => {
    return { id }
}

Dynamic routes

For complicated applications, defining routes using preset pathways is not always sufficient. To establish a dynamic route in Next.js, add brackets to a page ([param]). Take a look at this page: 
pages/post/[postid].js
Pages/post/[postid].js will match any route, such as /post/1, /post/xyz, and so on. The matching path parameter will be given to the page as a query parameter and combined with the other query parameters.

import { useRouter } from 'next/router'

const Post = () => {
  const router = useRouter()
  const { postid } = router.query

  return <p>Post: {postid}</p>
}

export default Post
The query object for the route /post/abc, for example, will be as follows:
{ "postid": "1234" }
Similarly, the query object for the route /post/1234?username=john will be as follows:
{ "username": "john", "postid": "1234" }

Next/link is used to handle client-side navigation to dynamic routes. If we wanted to link to the routes mentioned above, we'd do so as follows:
Home.js

function Home() {
    return (
      <ul>
        <li>
          <Link href="/post/1234">
            <a>Go to pages/post/[postid].js</a>
          </Link>
        </li>
        <li>
          <Link href="/post/1234?username=john">
            <a>Also goes to pages/post/[postid].js</a>
          </Link>
        </li>
        <li>
          <Link href="/post/1234/comment12">
            <a>Go to pages/post/[postid]/[comment].js</a>
          </Link>
        </li>
      </ul>
    )
  }
 
export default Home

FAQs

1. What happens if route parameters have the same name in dynamic routing?
Query parameters with the same name will be overridden by route parameters. The query object for the route /post/abc?pid=123, for example, will be as follows:

{ "pid": "abc" }

 

2. How do multiple route segments work?
If the page pages/post/[pid]/[comment].js will match the route /post/abc/a-comment and its query object will be:

{ "pid": "abc", "comment": "a-comment" }

This is how multiple route segments work.

 

3. What are dynamic route segments?
Dynamic route segments are dynamic routes (also known as url slugs, pretty urls, and other terms) that may be created in Next.js apps by utilizing brackets in the filename.

Key Takeaways

In this article, we learned about File System Routing, Linking pages, Linking to dynamic paths, Passing routing parameters, and Dynamic routes. 
But this is not enough; you need something extra to excel in web development truly. If you want to learn more about web development, you can read our articles or take our highly curated Web Development course.

Check out this article - File System Vs DBMS

Live masterclass