Search

Suggested keywords:
  • Java
  • Docker
  • Git
  • React
  • NextJs
  • Spring boot
  • Laravel

Layouts and Routing in Next.js

  • Share this:

post-title

NextJSis a React framework for production-based full-stack web applications, As React is just a JavaScript library for building UI, it needs 3rd party libraries for extra features such as routing, authentication, etc. Next.js solves this problem by providing these features, so we no longer need these 3rd party libraries anymore. Although we still write react code, Next.js just fills the voids in a react app, making it production-ready.

To get started with NextJS, refer to our previous article which helps to setup and get started with NextJS. In the blog, you will learn about File based routing, Route groups and Layouts.

App vs Pages Router

While creating the next app, we have 2 possible options, app router and pages router. The recommended way is app router, as it was made stable in the next 13.4 version.

In the app router, we have an app directory that contains all the pages and routes, while in the case of the pages router, we have a pages directory, which contains the files corresponding to its route,  for example

In addition to that app, routers have extra features such as React Server Components, nested layout, etc.

File-based Routing (App Router)

When a user navigates to a route in our application, the App Router will look for the corresponding file in your project's file system and render it.

To enable routing in Next.js, we can create folders in the app directory to represent our routes with a page component inside of it. The name of each folder should correspond to the route that it represents.We can also define a nested route, by creating a folder inside another. This makes it easy to define routes without writing any code, unlike React 18.

The page.js file in the app directory itself represents the home route of our application, which is accessible at localhost:3000/.

Note- Routes with no nested routes within them are called leaf segments.

 

Defining Routes

Let's create this folder structure, which corresponds to its route

File: app->page.jsx (home route)

export default function Home() {

  return <main>Dashboard Page</main>;

}

 

File: about-> page.jsx

export default function About() {

  return <h1>About Page</h1>;

}

 

File: contact-> page.jsx

export default function Contact() {

  return <div>Contact</div>;

}

 

File: main-> page.jsx

export default function Main() {

  return <div>Main page</div>;

}

 

File: main->product->page.jsx

export default function Product() {

  return <div>Product Page</div>;

}

 

For example, if user enters

http://localhost:3000/main/product

Next is going to find the main folder in the root app directory, then it will find the product folder, and render the page.jsx within the corresponding folder, if it doesn't find such folder, next will render a 404 page not found page.

Dynamic Routes

These are routes which are based on different data, for example for a product page, the content on it will be dynamic, and we can't make a product page for all the products, in order to fulfil that route must be dynamic based on some id.

We can create a dynamic route by creating a folder named as the dynamic Id enclosed in square brackets, and we create the page file inside the folder as usual. We can access this dynamic id directly in the functional component and display content based on this id.

It is a common convention to name these folders [slug] , representing a dynamic route.

http://localhost:3000/main/product/[productId]

We can extract this id using params, it is a property received in the parameter list of the component.

export default function ProductPage({ params }) {

  return <div>{params.slug}</div>;

}

 

Navigation

In order to navigate between routes, next.js provides two methods, using

  1. Link Component (<Link>)
  2. useRouter hook 

 

Link Component

The Link Component is provided by the next/Link Module which allows us to facilitate client-side navigation by linking routes. It directs to the route without hard reload.

Step 1: Import the Link Component

import Link from 'next/link';

Step 2: In the JSX, wrap the text with Link Component and provide the target route in the href attribute

<Link href="/about">About</Link>

Let's create a navbar component

File: app->Components->NavBar.jsx

import Link from 'next/link';

export default  function NavBar() {

  return (

    <nav>

      <ul className="flex space-x-20 p-4 bg-blue-300">

        <li> <Link href="/">Dashboard</Link></li>

        <li> <Link href="/about">About</Link> </li>

        <li><Link href="/contact">Contact</Link></li>

        <li> <Link href="/main">Main</Link></li>

        <li><Link href="/main/product">Product</Link></li>

      </ul>

    </nav>

  );

}

Now call this component in the layout.js file, so the navbar consistent on each route

useRouter Hook

This hook allows programmatic navigation between routes. Since components in next are server rendered by default, functionalities like hooks are not available on server, so we need to make the client component.

Step 1:Make the component client side by typing at the top of the page

‘use client’

Step 2: Import useRouter hook from next/navigation

Import {useRouter} from ‘next/navigation’

Step 3: Inside a component instance of this hook is created

const router=useRouter();

Step 4: To a click event  pass a function, which calls the push method of router and the target route is passed as parameter.

'use client';

import { useRouter } from 'next/navigation’;

export default function Home() {

  const router = useRouter();

  return (

    <main>

      Dashboard Page

      <button onClick={() => router.push('/main/product')}>

        To product page

      </button>

    </main>

  );

}

Testing our routes

http://localhost:3000

http://localhost:3000/about

http://localhost:3000/contact

http://localhost:3000/main

http://localhost:3000/main/product

http://localhost:3000/main/product/[slug]

If we had to do the same thing in react, it would not only be time consuming but also complicated

 

Layout File

Layout files allow sharing of UI components between routes, the layout file in the root app folder is called root layout, its content is shared across the whole app, and it must contain an HTML and body tag.This file exports a react component called RootLayout, which takes in a children property, children represents all the content within the directory, it wraps content of nested routes, and returns it.

Navbar and Footer Components are added in layout files so that we manually don't need to add that component in each page. Global css is imported in this page, so it can be applied to the entire app.

It also exports metadata object,

export const metadata = {

  title: 'eCommerce app',

  description: 'Generated by create next app',

};

This title directly changes the title

Also each route folder can have a loading and error file

Nested Layout

We can have a specific layout for each of the routes,we can have layout in each route folder, these components are shared in the corresponding routes and sub-routes..

Step 1: Create a layout file in the route folder

Step 2: create RootLayout react component which takes in the children prop, and wrapped in the layout.

export const metadata = {

  title: 'eCommerce app',

  description: 'Generated by create next app',

};

export default function RootLayout({ children }) {

  return (

    <div>

      <h3>Product Layout</h3>

      {children}

    </div>

  );

}

Now this layout file will be inherited by page files in the same directory as the layout file  as well as any nested routes, it will not be applied to parent folders.

Note-Each layout can have it own set of metadata too, for example we can change the title of product route and nested route to ‘eCommerce app | Products’

http://localhost:3000/main/product

 

http://localhost:3000/main/product/[slug]

This layout file is inherited by the product and its nested dynamic route

 

Route Group

A Route Group is like a special folder for organising different routes in a web application. It's a way to group routes together without changing how the web addresses (URLs) for those routes look to users.

Some important points

1. Create a Route Group by making a folder and giving it a name in parentheses, like "(productDetails)". Inside this folder, you can put specific routes related to product details.

 

2. The name you put in parentheses doesn't change how the web addresses (URLs) work. So, if you have a route for displaying product details at http://localhost:3000/main/product/[slug], it will still be accessible at that address and won't become http://localhost:3000/main/product/(productDetails)/[slug].

 

3. Route Groups is often used when we want some routes in that group to have a different layout or design without changing the URL. For instance, if you move the layout design for the product details page into the "(productDetails)" group, it won't affect the layout of the main product page. This helps in keeping the different parts of a website organised and visually consistent without messing up the URLs.

Other Files

Loading File

Each route and nested routes can have a separate loading file, a file named loading.jsx (or .tsx) is reserved in Next 13, inside which a Loading component  is exported, inside which a loading JSX is returned, spinner or some text.

File: loading.jsx

export default function Loading() {

  return <div>Loading...</div>;

}

When the content in the page file is rendered this Loading component will be displayed automatically

Custom 404

Suppose, we try to access a route which does not exist, Next provides its own 404 page not found page,

We create a file named not-found.jsx (or .tsx) and return accordingly, also can be scoped to different sections of our app, just like the layout file.

 

Conclusion

Next.js is a framework that simplifies web application development, making them faster and more efficient. It's great for React-based projects due to its server-side rendering, automatic code splitting, smart file organisation, and instant code updates. In the future, Next.js is expected to be used for various web applications, offering improved integration with other technologies. Using Next.js today ensures a fast, SEO-friendly website that's ready for future web development trends.

Atif Ali

About author
Transitioning from front-end to full-stack web development, I'm eager to share my insights through articles. My constant drive is to explore new technologies and continually push my boundaries.