Dynamic routing in Next.js is a powerful feature that enables developers to create more flexible and scalable applications. This blog will guide you through the process of setting up dynamic routes in Next.js, ensuring that you can create pages that respond to various paths and parameters with ease.
Next.js is a React framework that provides functionalities for server-side rendering and generating static websites, making it a go-to choice for developers aiming to build performant and SEO-friendly web applications. One of the standout features of Next.js is its file-system-based routing mechanism. Unlike traditional React applications that may require a routing library like React Router, Next.js comes with its own routing capabilities out-of-the-box.
In Next.js, the pages folder is at the heart of the routing system. Each JS or JSX file in this folder automatically becomes a route based on its file name. For example, a file named about.js in the pages folder would be accessible at /about. This convention simplifies the process of creating static pages.
However, when it comes to handling dynamic content, such as blog posts or user profiles, you need a way to generate routes that aren't known ahead of time. This is where dynamic routing comes into play. Next.js allows you to create pages with dynamic routes using a special file naming convention and a combination of two functions: getStaticPaths and getStaticProps.
Dynamic routing allows Next.js applications to handle a variety of paths, including those that are not known at build time. This is particularly useful for applications that need to display content based on identifiers from a database, such as blog id details pages or user profiles.
In Next.js, dynamic routes are defined using file names that start with brackets, effectively creating defined dynamic paths. Path parameters are placeholders in the URL that are replaced with actual values when a request is made. For instance, a file named [id].js in your pages directory will match any route like /posts/1 or /posts/abc, which is the actual blog post’s ID when a user visits the page.
To create a dynamic page, you'll need to add a new file to the pages folder using a special file naming convention. For example, to create dynamic blog id details pages, you would create a file named [id].js inside a directory named blog.
1// pages/blog/[id].js 2import React from 'react'; 3 4const BlogPost = ({ post }) => { 5 // Render post content 6 return ( 7 <div> 8 <h1>{post.title}</h1> 9 <article> 10 {post.content} 11 </article> 12 </div> 13 ); 14}; 15 16export default BlogPost;
The file named [id].js inside the blog directory is an example of setting up dynamic routes for a blog section in a Next.js application.
In the above file, [id] signifies that this is a dynamic page that will match any path like /blog/1, /blog/2, and so on.
Next.js allows you to pre-render pages at build time using getStaticProps and getStaticPaths. These functions are essential for generating static pages with dynamic paths, utilizing 'getStaticProps' and 'getStaticPaths' to generate all the HTML code necessary for pre-rendering dynamic SSG pages. This process is crucial for optimizing performance and SEO by ensuring that HTML code for each page is generated in advance, improving load times and search engine visibility.
The getStaticProps function fetches data for a page at build time. Here is an example of how it works:
1// pages/blog/[id].js 2export async function getStaticProps({ params }) { 3 // Fetch data for the blog post using params.id 4 const post = await getBlogPostById(params.id); 5 return { 6 props: { 7 post, 8 }, 9 }; 10}
The getStaticPaths function tells Next.js which paths to pre-render, including dynamic SSG pages, and plays a crucial role in defining which pages should be pre-rendered. This is where you define dynamic paths for your static pages, ensuring that all the other pages that might not be pre-generated are still accessible through the fallback mechanism. Let’s look at an example:
1// pages/blog/[id].js 2export async function getStaticPaths() { 3 const paths = await getAllBlogPostIds(); 4 return { 5 paths, 6 fallback: false, 7 }; 8}
In the getStaticPaths function, paths is an array of objects with the params key, which contains the actual values to be used for path parameters. The fallback keyword determines the behavior of paths not returned by getStaticPaths, allowing you to control how many pages to pre-generate and highlighting the importance of not pre-generating all those pages for performance reasons.
If you have too many blogs or pages that cannot be pre-generated at build time, you can use the fallback key to dynamically load pages on request. Setting fallback to true or 'blocking' allows Next.js to serve a fallback version of the page on the first request to such a path.
1// pages/blog/[id].js 2export async function getStaticPaths() { 3 // Only pre-generate pages for the most popular posts 4 const paths = await getPopularPostIds(); 5 return { 6 paths, 7 fallback: 'blocking', // or true 8 }; 9}
When fallback is set to true, the user may see a loading state, which you can customize by checking if the router.isFallback is true:
1// pages/blog/[id].js 2import { useRouter } from 'next/router'; 3 4const BlogPost = ({ post }) => { 5 const router = useRouter(); 6 7 if (router.isFallback) { 8 // Display a custom loading state 9 return <div>Loading...</div>; 10 } 11 12 // Render post content 13 return ( 14 <div> 15 <h1>{post.title}</h1> 16 <article> 17 {post.content} 18 </article> 19 </div> 20 ); 21}; 22 23export default BlogPost;
When fallback is set to 'blocking', Next.js will wait until the page is generated on the server before displaying it to the user, ensuring they never see a loading state.
To fully leverage dynamic routing, you need to understand how to implement path parameters in the getStaticPaths function. This function should return an array of possible values for each dynamic segment of the URL. Here's how you can do it:
1// pages/blog/[id].js 2export async function getStaticPaths() { 3 const posts = await getAllPosts(); // Your method to fetch posts 4 const paths = posts.map((post) => ({ 5 params: { id: post.id.toString() }, 6 })); 7 8 return { paths, fallback: false }; 9}
In the above code, getAllPosts would be a function that fetches all the blog posts from your data source, and you map over these posts to create an array of paths that Next.js will use to pre render pages.
For a complete dynamic SSG (Static Site Generation) setup, you need to combine getStaticProps and getStaticPaths. The getStaticProps function will fetch the necessary data for each page, while getStaticPaths will define which pages to pre-generate.
Here's how you can combine these functions in your [id].js file:
1// pages/blog/[id].js 2import { getAllPosts, getPostById } from '../../lib/posts'; 3 4export async function getStaticPaths() { 5 const posts = await getAllPosts(); 6 const paths = posts.map((post) => ({ 7 params: { id: post.id.toString() }, 8 })); 9 10 return { paths, fallback: false }; 11} 12 13export async function getStaticProps({ params }) { 14 const post = await getPostById(params.id); 15 return { 16 props: { 17 post, 18 }, 19 }; 20} 21 22const BlogPost = ({ post }) => { 23 // Render post content 24 return ( 25 <div> 26 <h1>{post.title}</h1> 27 <article> 28 {post.content} 29 </article> 30 </div> 31 ); 32}; 33 34export default BlogPost;
In this complete file, you have a dynamic page that will pre-render all the paths for your blog posts at build time, and each page will have the necessary data fetched and passed to the page component.
Dynamic routing in Next.js is a powerful feature that allows you to create flexible and efficient web applications. By understanding how to set up dynamic routes, implement path parameters, and combine getStaticProps with getStaticPaths, you can build applications that pre-render pages for optimal performance while still being able to dynamically load new content as needed. Implement these concepts in your next project, and you'll see just how seamless and scalable your web applications can become.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.