How to implement routing in a Next.js app?

How to implement routing in a Next.js app?

Implementing routing in a Next.js application is a straightforward process, thanks to the framework's file-based routing system. Next.js, a popular React framework, offers both static generation (SSG) and server-side rendering (SSR) capabilities for building highly performant and scalable web applications. In this article, we'll delve into how to implement routing in a Next.js app, covering the basics, dynamic routes, nested routes, and programmatic navigation.

Prerequisites

Before diving into routing, ensure you have the following prerequisites:

  • Node.js installed on your machine.
  • Basic knowledge of React.
  • A new or existing Next.js project. If you're starting a new project, create one by running npx create-next-app@latest.

Basic Routing

Basic Routing

Next.js uses a file-based routing system, where the routes are determined by the file structure within the pages directory. Here's how to implement basic routing:

  1. Creating Pages: Every .js, .jsx, .ts, or .tsx file inside the pages directory (except pages/_app.js and pages/_document.js) automatically becomes a route.

    For example, creating pages/about.js makes the /about route available.

  2. Linking Pages: Use the Link component from next/link to navigate between pages without a full page reload.

    Example:

    import Link from "next/link";
    
    function HomePage() {
      return (
        <div>
          <h1>Welcome to the Home Page</h1>
          <Link href="/about">
            <a>About Us</a>
          </Link>
        </div>
      );
    }
    
    export default HomePage;
    

Dynamic Routing

Dynamic Routing

To create a dynamic route, add square brackets to a page name in the pages directory, like [id].js. This allows you to capture the value of the id parameter within your page.

  1. Creating a Dynamic Route: Create a file named [id].js inside the pages/posts directory for a dynamic post route.

  2. Fetching Data: Use getStaticProps and getStaticPaths (for SSG) or getServerSideProps (for SSR) to fetch data based on the dynamic parameter.

    Example in pages/posts/[id].js:

    import { useRouter } from "next/router";
    
    const Post = () => {
      const router = useRouter();
      const { id } = router.query;
    
      return <p>Post: {id}</p>;
    };
    
    export default Post;
    

Nested Routes

To create nested routes, you simply structure your pages directory in the way you want your URL to be structured.

For example, to create a route like /blog/2021/first-post, your file structure would be:

  blog/
    2021/
      first-post.js

Programmatic Navigation

Besides using the Link component, you can also navigate programmatically using the useRouter hook from next/router.

Example:

import { useRouter } from "next/router";

function HomePage() {
  const router = useRouter();

  const navigateToAbout = () => {
    router.push("/about");
  };

  return (
    <div>
      <button onClick={navigateToAbout}>Go to About Page</button>
    </div>
  );
}

export default HomePage;

Building upon the foundational knowledge of routing in Next.js, let's explore some advanced routing concepts including fallback loading states in dynamic routes, catch-all routes, and optimizing user experience with shallow routing.

Fallback Loading States in Dynamic Routes

When you're generating dynamic routes using getStaticPaths with { fallback: true }, you may encounter situations where the page hasn't been generated yet. In such cases, Next.js serves a fallback version of the page initially, which is perfect for rendering loading placeholders.

Implementing a Fallback State:

In your dynamic page, you can use the isFallback property from useRouter to determine if the fallback is being displayed:

import { useRouter } from "next/router";

const Post = () => {
  const router = useRouter();

  if (router.isFallback) {
    return <div>Loading...</div>;
  }

  // Your normal page rendering
  return <div>Post content</div>;
};

export default Post;

Catch-All Routes

Catch-all routes allow you to match paths that have multiple segments. You might use this for a CMS-like experience where you don't know the exact depth of your URLs.

Creating a Catch-All Route:

To create a catch-all route, add three dots (...) inside the brackets. For example, pages/posts/[...slug].js will match /posts/a, /posts/a/b, /posts/a/b/c, and so on.

Accessing Parameters:

In your page component, you can access the catch-all parameters as an array under the key you've named in the file. For the above example, the key would be slug.

import { useRouter } from "next/router";

const Post = () => {
  const router = useRouter();
  const { slug } = router.query; // slug is an array

  return <div>Slug: {slug.join("/")}</div>;
};

export default Post;

Shallow Routing

Shallow routing allows you to change the URL without running data fetching methods again, that means you can update the path without triggering getStaticProps, getServerSideProps, or getInitialProps to re-run. This is particularly useful for filtering or pagination where the page data doesn't need to be fetched again.

Using Shallow Routing:

To enable shallow routing, pass the shallow: true option to router.push or router.replace.

const { router } = useRouter();

// Assuming the current path is `/events?counter=0`
const handleClick = () => {
  /*
    This will update the URL without re-running data fetching methods
    on the page, which means the page/content remains unchanged but the URL changes.
  */
  router.push("/events?counter=1", undefined, { shallow: true });
};

Optimizing Navigation with Prefetching

Next.js automatically prefetches pages linked with the Link component that are visible in the viewport. This makes navigation to these pages feel instant. However, you can also manually prefetch pages if needed, for instance, in response to a user's action.

Manually Prefetching a Page:

You can use the router.prefetch method to prefetch a page programmatically.

const { router } = useRouter();

const handleMouseOver = () => {
  // Prefetch the about page
  router.prefetch("/about");
};

return (
  <div onMouseOver={handleMouseOver}>Hover me to prefetch the About page!</div>
);

Conclusion

Advanced routing techniques in Next.js enhance the flexibility and user experience of your application. By leveraging fallback loading states, you can improve the loading experience for your users. Catch-all routes offer unmatched flexibility in handling a wide range of URL structures. Shallow routing and manual prefetching are powerful tools for optimizing your application's interactivity and responsiveness. With these advanced concepts, you can build dynamic and highly efficient Next.js applications that cater to complex routing requirements.

Routing in Next.js is intuitive and powerful, leveraging a file-based system for simplicity and supporting advanced patterns like dynamic and nested routes. By understanding the basics of routing and navigation in Next.js, you can build complex and highly interactive web applications. Remember, the key to mastering Next.js routing lies in organizing your pages directory effectively and leveraging the framework's built-in hooks and components for navigation.

Tags :
Share :

Related Posts

Building Powerful Desktop Applications with Next.js

Building Powerful Desktop Applications with Next.js

Next.js is a popular React framework known for its capabilities in building server-side rendered (S

Continue Reading
Can use custom server logic with Next.js?

Can use custom server logic with Next.js?

Next.js, a popular React framework for building web applications, has gained widespread adoption for its simplicity, performance, and developer-frien

Continue Reading
Can use TypeScript with Next.js?

Can use TypeScript with Next.js?

Next.js has emerged as a popular React framework for building robust web applications, offering developers a powerful set of features to enhance thei

Continue Reading
Does Next.js support progressive web app (PWA) features?

Does Next.js support progressive web app (PWA) features?

In the ever-evolving landscape of web development, the quest for delivering a seamless, app-like experience on the web has led to the rise of Progres

Continue Reading
Exploring Compatibility Can  Use Next.js with Other Front-End Frameworks?

Exploring Compatibility Can Use Next.js with Other Front-End Frameworks?

Next.js, a popular React-based web development framework, has gained significant traction in the world of front-end development due to its efficient

Continue Reading
Exploring Next.js Comprehensive Guide to the React Framework

Exploring Next.js Comprehensive Guide to the React Framework

Next.js has emerged as a powerful and popular framework for building web applications with React. Developed and maintained by Vercel, Next.js simplif

Continue Reading