One of Next.js' main selling points is how simple it makes routing. For example, when you visit a website's home page and click on an "About Page" link, routing allows you to navigate from the home page to the about page.
Routing involves creating routes, managing navigation, and handling dynamic URLs.
In this article, we'll explore how Next.js handles routing efficiently.
Next.js Routing
Next.js Routing refers to how navigation between pages is handled in a Next.js application. When a user visits a website, routing determines which page is displayed based on a specific URL.
Next.js handles routing by mapping URLs to files and folders within the pages directory. This means that any file inside the pages directory automatically becomes a route, eliminating the need to use a separate Routing library like React Router.
How does the Next.js File-based Routing System work?
Next.js utilizes a file-based routing system that automatically defines the routes of your application based on your project's folder and file structure. The Pages Router, also known as the Pages directory (or folder), is the traditional routing system in Next.js.
When you add a file inside the pages/ directory, Next.js automatically turns the file into a route.
For example:
In a Next.js project, if a file named index.js is placed inside the pages directory, it is automatically routed to the root of the site.
- pages/index.js - /(homepage)
If you add other folders or create subfolders within the pages directory, they become nested routes.
Example
- pages/product/index.js - /product
- pages/product/products.js - /product/products
The second Routing system is called the App Router. App Router was introduced in Next.js version 13. It is the recommended system that utilizes the App directory (/app) to define routes, layout, and UI structures using React server components.
If the App directory, each folder represents a route. Inside each folder, a special file named page.js defines the page that renders that route.
Example:
- app/page.js - / (homepage)
- app/product/page.js - /product
The App Router also introduces other special files that simplify routing, such as
- layout.js (or jsx, tsx) - The layout file creates a shared layout that wraps around the content of your pages. It helps maintain consistency across your application and improves the application's performance.
If you have elements like a footer or a header on each page, layout ensures they are persistent across the different routes.
default.js (or jsx, tsx) - This provides a fallback UI for parallel routes (which allows different parts of a page to render independently) when no specific child route is matched.
global-error.js (or jsx, tsx) - This file defines a global error UI that catches and handles errors across your Next.js application, ensuring users get a clear error message when something in the application goes wrong
error.js (or jsx, tsx) - This file is used to display an error message in the UI if an error occurs.
not-found.js (or jsx, tsx) - This is used to define 404 pages.
loading.js (or jsx, tsx) - This is used to add loading states for pages or routes.
template.js (or jsx, tsx) - This file wraps a layout or a page, and can remount its child components when route parameters change, for example, whenever a user navigates back and forth between routes.
Routing in Next.js
Let’s see how Routing works in Next.js using a few examples.
Prerequisite: To get started, you should have a basic understanding of how to create a Next.js app and set it up in the VSCode environment
Set up the project
Install Next.js by running the following command:
npx create-next-app@latest
During setup, you'll see prompts allowing you to choose your project's requirements, such as whether to use JavaScript or TypeScript, whether to use the App router (which is recommended), and whether to install Tailwind CSS, among other options.
After choosing your preferences, create-next-app will automatically create a new folder with your project name and install all the required dependencies, as shown in the image below.
Create a Route
In the image, we have the src/app/products/page.tsx
In the products folder, we didn't name the file index.tsx or products.tsx instead, we used page.tsx, which is the Next.js convention. This allows Next.js to recognize it as a route.
In other words, each route in the App Router must have its own folder named after the route (e.g, products). Inside the folder, the file must always be named page.tsx (or page.js) so that Next.js can render it as the page for that route.
Inside the page.tsx file, we used export default for the React component to tell Next.js to render it for the /products route.
Products Route
When you visit the localhost where the project is running and add /products route
https://localhost:300/products
You will see that Next.js matched the URL to the folder named products.
The products folder becomes the route path /products. This means that when someone visits the route /products, Next.js renders the component defined in the page.tsx file.
The image below is what the page looks like before adding the /products route.
This is the homepage, also the default Next.js welcome page. You can modify this page and replace its entire content, adding your own components or layout.
Create Nested Route
A nested (or child) route is created by placing one folder inside another. This is necessary to keep related pages organised and ensure the structure of the application is clear and scalable.
Let's assume we want to create a product page to display details for a specific product.
First, create a folder named product inside the products folder. Then, within the product folder, create a file called page.tsx.
Inside the page.tsx file, use the React default export component, so that Next.js recognizes it as a route, as shown in the image below.
In the image, the product page is accessed by adding the /product to the /products route, as shown below ;
http://localhost:3000/products/product
Dynamic Routes
A dynamic route allows you to display different pages using a single page file. For example, if you have a products page with 50 products, instead of creating 50 separate pages, you can create a single file that handles all the routes. Using this approach, Next.js automatically loads the correct page based on the product's ID.
To create the dynamic route, we added a folder named [id] inside the products folder. We saved the ID in the square bracket to indicate that this is a dynamic route.
In the image above, you can see that /5 was added to the /products route because the dynamic route ought to receive a value.
In the image above, we used a params object to display any value entered in the URL on the page. This allows the page to determine what to show to the user.
In a real-world application, you would fetch the data from an API or database and check if the ID exists using params before the page renders. However, in the example, the route works because the dynamic route matches any value we pass in the URL, displaying the product page.
Navigate using Component
Let's move to the products page without reloading the entire page by using the component. The component enables client-side navigation, meaning it doesn't trigger a full-page refresh but prefetches and renders the intended page. This makes page transitions smoother and faster.
In the image above, we created two buttons for two products, assuming those are all the products we want the users to see, and wrapped the buttons in the <Link> Component.
When a user clicks on any of the buttons, they are redirected to the specific or corresponding product page.
In the above image, the same <Link> component wraps the "Go back to the products" button, allowing users to return to view all displayed products.
Layout Page
Another way to create smooth navigation between pages that share similar components is to use a layout page, which is provided by Next.js. Typical examples of pages that can be shared between pages include: the navigation bar, sidebar, and footer.
Layout page ensures that they remain interactive and do not re-render every time you switch between those pages.
Let's create a Navbar that's consistent across the products and product pages. You can style your Navbar however you like.
In the image shown above, a layout.tsx file was created inside the products folder, which also contains the folder for displaying individual products.
This layout allows you to wrap pages that share the same components (in this example, the Navbar) using the children prop that represents the content nested within a component. Using this approach ensures consistency across pages.
When we navigate to a specific product, the navbar is rendered on the page as well as shown in the image below.
Summary
Next.js simplifies the process of navigating between pages. It uses a file-based routing system where files within the Pages or App folder structure automatically define your web page routes.
It supports nested routes, dynamic routes, and layout options to enable smooth and fast navigation, including maintaining consistency across pages, unlike React, which may require libraries like React Router to handle navigation.
This file-based system keeps the project organized, enables fast configuration, and reduces routing errors.
Frequently Asked Questions
How does Next.js handle data fetching for dynamic content?
Next.js handles data fetching through functions like getStaticProps for static generation and getServerSideProps for server-side rendering. These functions fetch data per page, allowing dynamic content rendering based on the fetched data. This approach enables efficient data loading and dynamic content updates.
How often do Next.js and Nuxt.js receive updates?
Both frameworks receive regular updates, including bug fixes, new features, and performance improvements. The frequency of updates can vary, but both communities are committed to maintaining and enhancing their frameworks.
How does Next.js improve SEO compared to traditional SPA frameworks?
Next.js enhances SEO by enabling server-side rendering, which ensures that web crawlers can fully index web pages. This leads to better visibility on search engines as the content is pre-rendered on the server, making it more accessible to search engine bots.
What are the key benefits of using Next.js for web development?
Next.js offers server-side rendering for faster page loads, automatic code splitting for optimized performance, and easy routing with a filesystem-based approach. It also supports static exporting, making it versatile for various hosting options.
Jessica Agorye is a developer based in Lagos, Nigeria. A witty creative with a love for life, she is dedicated to sharing insights and inspiring others through her writing. With over 5 years of writing experience, she believes that content is king.
View all posts by Jessica Agorye