Home > frontend > How to Implement Dynamic Routing in ReactJS with React Router.

How to Implement Dynamic Routing in ReactJS with React Router.

Dynamic routing is a concept that redirects a website visitor from a page to another based on the value passed on the URL.

By :Thomas Inyang🕒 11 Jan 2025

react_router

Introduction

Routing in web development is an important concept of a website, it gives your website a map to direct visitors to the appropriate location based on their actions or inputs. As front-end developers, it’s very important to utilize this concept as it’s beneficial to the users who intend to share a post or product-item URL with anyone.


In this post, you will learn how to route dynamically based on specific input, such as a blog slug, using React Router. This powerful tool simplifies dynamic routing in ReactJS applications, making it straightforward, efficient, and highly effective.

Prerequisite:

  1. Knowledge of ReactJs.
  2. React App with Vite.

What is Dynamic Routing?

Dynamic routing is the ability of a website to display different page components based on the URL path which gives room for more flexibility. An example of dynamic routing is a blog website, where you can have a single route that displays different posts based on their unique slugs or IDs.

How to Implement Dynamic Route In a React App using React Router.

In the section, you will need to do the following:

Step1

Install React App.

npx create-vite@latest

This will install the React App when you follow the prompts. You can either choose JavaScript or Typescript as the programming language tool. For this tutorial choose Typescript.


Step2:

Install React Router.

npm i react-router

This will install the react-router which will enable us to navigate from one page to another.


Step3:

Update the main.tsx file with this.

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router";
import App from "./app";

const root = document.getElementById("root");

ReactDOM.createRoot(root).render(
<StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
</Routes>
</BrowserRouter>
</StrictMode>
);

In this code, you’ve been able to set up ReactRouter, and you can navigate between pages by specifying the path “/path” and element component. In this case, this is the homepage path "/”.


Step4:

Create a type file in the src dir, types.d.ts, and enter the following code block

export interface Post {
id: number;
title: string;
slug: string;
content: string;
}

This will be used to strictly type the blog post data.


Step5:

Create mock data for the blog.

src/mockData.ts

import { Post } from "./types";

export const posts: Post[] = [
{
id: 1,
title: "One random blog post",
slug: "one-random-blog",
content:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente dicta eaque voluptate eveniet quisquam nulla possimus incidunt doloremque rerum deleniti?",
},
{
id: 2,
title: "The Story That Never Happened",
slug: "the-story-that-never-happened",
content:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente dicta eaque voluptate eveniet quisquam nulla possimus incidunt doloremque rerum deleniti?",
},
{
id: 3,
title: "One blow seven faint",
slug: "one-blow-seven-faint",
content:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente dicta eaque voluptate eveniet quisquam nulla possimus incidunt doloremque rerum deleniti?",
},
{
id: 4,
title: "We are almost there",
slug: "we-are-almost-there",
content:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente dicta eaque voluptate eveniet quisquam nulla possimus incidunt doloremque rerum deleniti?",
}
];

The Post interface is imported and used as a “type” for the mockData.


Step6:

Create a components folder and a file AllPosts.txs in it, and enter this code block

import { Link } from "react-router";
import {posts} from "../mockData"
export default function AllPosts(){

return(
<>
<div style={{width:"100%", padding:"4px", backgroundColor: "powderblue"}}>

{posts.map((post, index)=>(
<div key={index} style={{width:"auto", borderRadius:"3px", borderStyle:"solid", borderColor:"red"}} >

<h1 style={{fontSize:"14px"}}>{post.title}</h1>
<Link to={`/post/${post.slug}`}>{post.slug}</Link>;
</div>
))}
</div>
</>
)
}

This is the entry file that shows all the blog posts (mock) and when the post slug is clicked, the user will be redirected (dynamic routing) to the post details page.


Step7

Create a post folder with a PostDetails.tsx file and paste this code

src/post/PostDetails

import { useParams, Link } from "react-router-dom";
import { posts } from "../mockData";

export default function PostDetails() {
// Extract the slug parameter from the URL
const { slug } = useParams<{ slug: string }>();

// Find the post that matches the slug
const post = posts.find(post => post.slug === slug);

// Handle case where post isn't found
if (!post) {
return (
<div className="error-container">
<h1>Article Not Found</h1>
<p>We couldn't find the article you're looking for.</p>
<Link to="/">Return to all articles</Link>
</div>
);
}

return (
<div className="post-detail-container">
<Link to="/" className="back-link">← All Articles</Link>
<article>
<h1>{post.title}</h1>
<div className="post-content">
{post.content}
</div>
</article>
</div>
);
}

This component uses React Router's `useParams` hook hat extracts dynamic parameters from the current URL. In our case, it pulls out the `slug` portion, which we then use to find the matching post from our data.


Step 8: Updating the App Component

Let's update our main App component to serve as the container for our blog listing. Modify `src/App.tsx`:

import AllPosts from "./components/AllPosts";
function App() {
return (
<div className="app-container">
<header>
<h1>React Dynamic Routing Demo</h1>
</header>
<main>
<AllPosts />
</main>
<footer>
<p>Built with React Router and TypeScript</p>
</footer>
</div>
);
}
export default App;

Step9

Update the main.tsx file.

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router";
import "./index.css";
import App from "./App.tsx";
import PostDetails from "./post/PostDetails.tsx";

createRoot(document.getElementById("root")!).render(
<StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="/post/:slug" element={<PostDetails />} />
</Routes>
</BrowserRouter>

</StrictMode>
);
```

The magic happens in this line: `<Route path="/post/:slug" element={<PostDetails />} />`. The colon syntax (`:slug`) designates a dynamic parameter in the URL. When a user navigates to a URL like `/post/understanding-react-hooks`, React Router captures `understanding-react-hooks` as the `slug` parameter, which becomes accessible in the `PostDetails` component via the `useParams` hook.


Step10

Test run the app from the terminal npm run dev. After loading is complete, when you click on a post slug you will be redirected to the page of the params (slug).

Best Practices for Dynamic Routing In ReactJS.

To ensure your dynamic routing implementation is robust, maintainable, and user-friendly:


1. Use Descriptive, SEO-Friendly URL Parameters

Instead of using opaque IDs:

- ❌ `/post/12345`

- ✅ `/post/understanding-react-hooks`


2. Implement Proper Loading States

Users should receive feedback while data for the dynamic route is loading:

function PostDetails() {
const { slug } = useParams<{ slug: string }>();
const [post, setPost] = useState<Post | null>(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
setLoading(true);
// Fetch post based on slug
fetchPost(slug).then(data => {
setPost(data);
setLoading(false);
});
}, [slug]);

if (loading) return <LoadingSpinner />;
if (!post) return <NotFound />;

return <article>{/* Post content */}</article>;
}

3. Handle Invalid Parameters Gracefully

Always account for the possibility that the URL parameter doesn't match any existing content:

function ProductDetail() {
const { productId } = useParams<{ productId: string }>();
const product = useProduct(productId);

if (!product) {
return (
<div>
<h1>Product Not Found</h1>
<p>The product you're looking for may have been removed or doesn't exist.</p>
<Link to="/products">Browse all products</Link>
</div>
);
}

// Render product details
}

4. Implement Redirects for Changed URLs

If your content URLs change (e.g., due to title updates), implement redirects to preserve SEO and user bookmarks:

function PostRedirect() {
const { oldSlug } = useParams<{ oldSlug: string }>();
const newSlug = findNewSlug(oldSlug);

if (newSlug) {
return <Navigate to={`/post/${newSlug}`} replace />;
}

return <NotFound />;
}
// In routes
<Route path="/post/old/:oldSlug" element={<PostRedirect />} />

Dynamic routing is very useful for a website. It enhances the user experience by allowing seamless transitions between one to another and making your application feel faster and more responsive.

Conclusion

Throughout this comprehensive guide, we've explored how dynamic routing in React transforms static web pages into interactive, deeply linked applications. By implementing React Router with URL parameters, you can create flexible, scalable solutions for a wide range of use cases—from blogs and e-commerce sites to dashboards and documentation platforms.


The techniques you've learned enable:

- Enhanced user experiences through direct URL access to specific content

- Improved shareability via clean, descriptive URLs

- Better SEO performance with permanent, crawlable links

- Reduced code redundancy by rendering different content with the same component

- Seamless state preservation through bookmarkable, deep-linkable pages


As you continue developing React applications, remember that effective routing is not merely a technical implementation detail—it's a fundamental aspect of user experience design. The thoughtful URL structures you create become the pathways through which users navigate, share, and return to your application.


Share with others

You may also like