Intro
- It has a file-system based routing mechanism
- When a file is added to the pages folder in a project, it automatically becomes available as a route
- By mixing and matching file names with a nested folder structure, it is possible to pretty much define the most common routing patterns
- Routing variations are:
- Route with pages
- Nested routes
- Dynamic routes
- Catch-all routes
- Navigate from the UI
- Programmatically navigate between pages
Routing with pages
It has a file-system-based routing mechanism.
- Scenario 01: index.js file within the pages folder will map to the root (https://localhost:3000) of your domain.
- Scenario 02: Pages are associated with routes based on their names. In the pages folder, about.js maps to https://localhost:3000/about and profile.js maps to https://localhost:3000/profile in the address bar.
Nested routes
- Scenario 01: pages->blog->index.js maps to https://localhost:3000/blog
- Scenario 02: pages->blog->first.js maps to https://localhost:3000/blog/first
- Scenario 03: pages->blog->second.js maps to https://localhost:3000/blog/second
Dynamic routes
- To implement dynamic routes, you need to name a component by wrapping it with square brackets like [componentName].js and componentName will correspond to the dynamic value in the url
- pages->product->[productId].js maps to https://localhost:3000/product/1, https://localhost:3000/product/2 or even https://localhost:3000/product/100. The number/string after the /product/ in the url will dynamically correspond and map to [productId].js component and the number/string after /product/ can be found inside [productId].js component using the useRouter hook like this -
const router = useRouter();
const productId = router.query.productId;
// productId is the dynamic component’s name
- But if a number/string after /product/ in the url is matched with the name of a component already existing inside the product page, that component with the matched name will get priority over [productId].js and be rendered rather than [productId].js being rendered.
Nested dynamic routes
- To implement nested dynamic routes like https://localhost:3000/product/7/review/2, you need a folder structure like pages/product/[productId]/review/[reviewId].js. Note that this time [productId] is a folder, not a .js file.
- So, pages/product/[productId]/review/[reviewId].js maps to https://localhost:3000/product/7/review/2
- In this mechanism, to achieve the functionality of https://localhost:3000/product/1, (only dynamic, not nested dynamic) you need a folder structure like pages/product/[productId]/index.js. You will find productId in the url dynamically in the index.js file.
- Thus you can implement dynamic nested routes by having dynamic segments in the folder name as well as file name.
- Speaking of dynamic multiple path segments, Next JS does offer another feature to handle the same. To know more about the feature, read the next topic.
Catch all routes
- This feature applies to scenario where the url contains multiple route segments like https://localhost:3000/docs/feature1/concept1
- The folder structure for https://localhost:3000/docs/feature1/concept1 should be pages/docs/[...params].js and inside [...params].js you can use useRouter to get both feature/ and concept/ or even more to it like below -
const router = useRouter();
const { params = [] } = router.query;
// assigned an empty array because initially it is undefined
// and may give an error in production
console.log(params); // [ "features1", "concept1" ]
- After getting your dynamic route segments, You can then conditionally render your components or JSX elements like this -
const Doc = () => {
const router = useRouter();
const { params = [] } = router.query;
// assigned an empty array because initially it is undefined
// and may give an error in production
console.log(params); // [ "features1", "concept1" ]
if (params.length === 2) {
return (
<h2>Viewing docs for feature {params[0]} and concept {params[1]}</h2>
)} else if (params.length === 1) {
return (
<h2>Viewing docs for feature {params[0]}</h2>
)}
return (
<div>Docs home page</div>
)};
export default Doc;
- But the folder structure pages/docs/[...params].js will give a 404 while trying to access https://localhost:3000/docs. To have a quick fix, you can put another pair of square brackets around [params].js, so the new folder structure is pages/docs/[[...params]].js and https://localhost:3000/docs does not give a 404 and works as expected.
Link component navigation
You can navigate in the UI using Link component offered by Next.js like this -
<Link href="product/2" replace >
<a>Go to Product 2</a>
</Link>
Navigating programmatically
You can navigate programmatically using useRouter. All other routing variations are valid in this mechanism.
const Home = () => {
const router = useRouter();
const handleOrder = () => {
console.log('Placing the order...');
router.push('/product');
};
return (
<div>
<button onClick={handleOrder}>Place order</button>
</div>
);
};
Custom 404 page
To provide your custom 404 page, create a 404.js file in the pages folder.
Conclusion
So, that is all about routing in NextJS. Hope you liked it. Thanks for reading.
Top comments (1)
sensational content 👏