NextJS Nested Routes: 5-Step Implementation Guide

published on 28 April 2024

Nested routes in NextJS provide a structured way to organize complex web applications, improving navigation and URL structure for better user experience and SEO. This 5-step guide covers:

  1. Setting Up the Pages Directory: Create files and directories in the pages folder to represent different routes, with nested directories for nested routes.

  2. Building Nested Routes: Use static file names for static nested routes, and dynamic routes with square brackets for dynamic nested routes.

  3. Linking Nested Routes: Use the Link component to create links between nested routes, and useParams to access dynamic route parameters.

  4. Creating Layout Components: Build shared layout components for consistent UI, and nested layouts for specific sections of your app.

  5. Advanced Nested Routing: Implement error handling with custom error pages, and secure nested routes using middleware for authentication and data validation.

Key Benefits of Nested Routes
Easier navigation
Cleaner URL structure
Improved SEO
Easier maintenance

Quick Comparison

Feature Static Nested Routes Dynamic Nested Routes
File Structure pages/about/team.js pages/blog/[category]/[post].js
Route Pattern /about/team /blog/category/post
Accessing Parameters N/A useParams hook

Step 1: Set Up the Pages Directory

Create Route Files

To set up nested routes in Next.js, you need to create new files in the pages directory that correspond to different routes. For example, if you want to create a route for /about/team, you would create a file called team.js inside an about directory within the pages directory.

Here's an example of what your pages directory structure might look like:

Directory/File Description
pages Root of your application's routing system
about Directory for /about route
team.js File for /about/team route
index.js File for /about route
index.js File for root route (/)

Nested Directory Structure

To create nested routes, you need to create a hierarchical structure within the pages directory. For example, if you want to create a route for /blog/category/post, you would create a directory called category inside the blog directory, and then create a file called post.js inside the category directory.

Here's an example of what your pages directory structure might look like:

Directory/File Description
pages Root of your application's routing system
blog Directory for /blog route
category Directory for /blog/category route
post.js File for /blog/category/post route
index.js File for /blog route
index.js File for root route (/)

By following this structure, you can create complex nested routes that are easy to manage and maintain. In the next step, we'll explore how to build nested routes using Next.js.

Step 2: Build Nested Routes

Static Nested Routes

To create a static nested route, create a new file in the pages directory that corresponds to the desired route. For example, to create a route for /about/team, create a file called team.js inside an about directory within the pages directory.

Here's an example of what your pages directory structure might look like:

Directory/File Description
pages Root of your application's routing system
about Directory for /about route
team.js File for /about/team route
index.js File for /about route
index.js File for root route (/)

In this example, the team.js file would contain the content for the /about/team route.

Dynamic Nested Routes

To create a dynamic nested route, use square bracket notation in your file names. For example, to create a route for /blog/category/post, create a file called [category].js inside a blog directory, and then create a file called [post].js inside the [category] directory.

Here's an example of what your pages directory structure might look like:

Directory/File Description
pages Root of your application's routing system
blog Directory for /blog route
[category] Directory for /blog/category route
[post].js File for /blog/category/post route
index.js File for /blog route
index.js File for root route (/)

To access the dynamic parameters, use the useParams hook from Next.js. For example:

import { useParams } from 'next/router';

function PostPage() {
  const { category, post } = useParams();

  return (
    <div>
      <h1>{post} in {category}</h1>
    </div>
  );
}

In this example, the useParams hook is used to access the category and post parameters from the URL.

To navigate between pages in Next.js, use the Link component from next/link. This component creates navigational links between pages. Here's an example of how to create a link to a nested route:

import Link from 'next/link';

function TeamPage() {
  return (
    <div>
      <h1>Team Page</h1>
      <Link href="/about/team/members">
        <a>View Team Members</a>
      </Link>
    </div>
  );
}

In this example, the Link component is used to create a link to the /about/team/members route.

Passing Data Between Routes

When using nested routes, you often need to pass data from one route to another. Next.js provides a way to do this using route parameters. Route parameters are values that are passed in the URL and can be accessed using the useParams hook.

Here's an example of how to pass data between routes:

import { useParams } from 'next/router';

function PostPage() {
  const { category, post } = useParams();

  return (
    <div>
      <h1>{post} in {category}</h1>
    </div>
  );
}

In this example, the useParams hook is used to access the category and post parameters from the URL. You can then use these parameters to fetch data or render dynamic content.

By using the Link component and route parameters, you can create complex navigation structures with nested routes in Next.js.

sbb-itb-5683811

Step 4: Create Layout Components

Shared Layout Components

In Next.js, you can create shared layout components to maintain a consistent UI across multiple pages. These components can include headers, footers, sidebars, or any other reusable UI elements.

Here's an example of how to create a shared layout component:

// components/Layout.js
import Header from './Header';
import Footer from './Footer';

const Layout = ({ children }) => (
  <div>
    <Header />
    <main>{children}</main>
    <Footer />
  </div>
);

export default Layout;

You can then use this layout component in your pages like this:

// pages/index.js
import Layout from '../components/Layout';

const HomePage = () => (
  <Layout>
    <h1>Welcome to the Home Page</h1>
    {/* Page content */}
  </Layout>
);

export default HomePage;

Nested Layouts

Next.js also supports nested layouts, allowing you to create more specific layouts for certain routes or sections of your application.

To create a nested layout, you can use the getLayout function in your page component. This function should return the desired layout component, which can then be nested within another layout component if needed.

Here's an example of how to create a nested layout for a dashboard section of your app:

// components/DashboardLayout.js
import Sidebar from './Sidebar';

const DashboardLayout = ({ children }) => (
  <div>
    <Sidebar />
    <main>{children}</main>
  </div>
);

export default DashboardLayout;
// pages/dashboard/index.js
import Layout from '../../components/Layout';
import DashboardLayout from '../../components/DashboardLayout';

const DashboardPage = () => (
  <div>
    <h1>Dashboard</h1>
    {/* Dashboard content */}
  </div>
);

DashboardPage.getLayout = (page) => (
  <Layout>
    <DashboardLayout>{page}</DashboardLayout>
  </Layout>
);

export default DashboardPage;

By using shared and nested layout components, you can maintain a consistent UI across your Next.js application while also providing flexibility for different sections or routes that require distinct layouts.

Step 5: Advanced Nested Routing

Error Handling

When working with nested routes, error handling is crucial to ensure a seamless user experience. In Next.js, you can leverage built-in error handling mechanisms to manage 404 and other error states within your nested route structures.

One approach is to create a custom error page component that will be rendered when an error occurs. You can do this by creating a pages/_error.js file:

// pages/_error.js
import ErrorPage from '../components/ErrorPage';

export default ErrorPage;

Then, in your components/ErrorPage.js file, you can define the error page layout and content:

// components/ErrorPage.js
import Head from 'next/head';

const ErrorPage = ({ statusCode, err }) => {
  return (
    <div>
      <Head>
        <title>{statusCode} Error</title>
      </Head>
      <h1>{statusCode} Error</h1>
      <p>{err.message}</p>
    </div>
  );
};

export default ErrorPage;

Next.js will automatically render this error page component when an error occurs, passing the statusCode and err props to the component.

Another approach is to use the getStaticProps method to catch errors and redirect to a custom error page. For example:

// pages/dashboard/[id].js
import { getStaticProps } from 'next';
import ErrorPage from '../../components/ErrorPage';

export const getStaticProps = async ({ params }) => {
  try {
    // Fetch data from API or database
    const data = await fetchData(params.id);
    return {
      props: { data },
    };
  } catch (err) {
    return {
      redirect: {
        destination: '/error',
        permanent: false,
      },
    };
  }
};

In this example, if an error occurs while fetching data, the getStaticProps method will catch the error and redirect to the custom error page at /error.

Secure Nested Routes

To add an extra layer of security to your nested routes, you can use middleware to validate user authentication or data before allowing access to certain routes. In Next.js, you can create a middleware function that checks for authentication or data validation before rendering the page.

For example, let's create a middleware function that checks for user authentication:

// middleware/auth.js
import { NextApiRequest, NextApiResponse } from 'next';

const authMiddleware = async (req: NextApiRequest, res: NextApiResponse) => {
  const token = req.cookies.token;
  if (!token) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  // Verify token and return user data
  const userData = await verifyToken(token);
  return userData;
};

export default authMiddleware;

Then, in your page component, you can use the getServerSideProps method to call the middleware function and validate the user authentication:

// pages/dashboard/[id].js
import { getServerSideProps } from 'next';
import authMiddleware from '../../middleware/auth';

export const getServerSideProps = async ({ req, res }) => {
  const userData = await authMiddleware(req, res);
  if (!userData) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }
  // Render page with user data
  return {
    props: { userData },
  };
};

In this example, the getServerSideProps method calls the authMiddleware function to validate the user authentication. If the user is not authenticated, the middleware function returns a 401 error and redirects to the login page. If the user is authenticated, the middleware function returns the user data, which is then passed as props to the page component.

By using middleware to validate user authentication or data, you can add an extra layer of security to your nested routes and ensure that only authorized users can access certain pages.

Conclusion

Mastering nested routes is crucial for building complex Next.js applications. By following the 5-step guide in this article, you can create organized, SEO-friendly, and complex URL structures that enhance the user experience.

Key Takeaways

  • Nested routes allow you to create complex navigation structures by nesting routes inside each other.
  • Next.js provides a flexible way to handle nested routes using the pages directory and file structure.
  • Using layouts, modularity, and reusability helps create maintainable and efficient codebases.
  • Error handling and security are essential considerations when working with nested routes.
  • Experiment with nested routes in your own Next.js projects to unlock their full potential.

Further Reading

For a deeper dive into Next.js routing and layouts, explore the official Next.js documentation and tutorials. You can also check out online resources such as blogs, forums, and GitHub repositories to learn from other developers and stay up-to-date with the latest best practices and trends.

Related posts

Read more

Make your website with
Unicorn Platform Badge icon