In my eight years of building React applications, I’ve found that one of the most critical parts of the user experience is how they move between pages.
If you are coming from traditional HTML, you might be used to the standard anchor tag (<a>) for navigation.
However, in the world of Single Page Applications (SPAs), using a standard anchor tag causes a full page reload, which breaks the seamless feel we want.
In this tutorial, I will show you exactly how to use the Link component to create a smooth navigation experience in your React projects.
What is the React Router Link Component?
The Link component is a declarative way to navigate around your application.
It renders an accessible anchor tag in the DOM, but it intercepts the click event to prevent a browser refresh.
I prefer using this because it keeps the application state intact while the URL changes.
Set Up the Project (USA City Explorer)
To make this practical, let’s build a small “USA City Explorer” app where we navigate between different major cities like New York, Los Angeles, and Chicago.
First, ensure you have React Router installed in your project.
npm install react-router-domThe Basic Implementation
To get started, we need to wrap our application in a BrowserRouter and then define our routes.
Here is the complete code for a basic setup.
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
// Simple components for our pages
const Home = () => (
<div style={{ padding: '20px' }}>
<h1>Welcome to the USA City Explorer</h1>
<p>Select a city to learn more about its famous landmarks.</p>
</div>
);
const NewYork = () => (
<div style={{ padding: '20px' }}>
<h2>New York City</h2>
<p>Home of the Statue of Liberty and Times Square.</p>
</div>
);
const LosAngeles = () => (
<div style={{ padding: '20px' }}>
<h2>Los Angeles</h2>
<p>The entertainment capital of the world, featuring Hollywood.</p>
</div>
);
const App = () => {
return (
<Router>
<nav style={{ padding: '10px', backgroundColor: '#f0f0f0' }}>
<ul style={{ listStyle: 'none', display: 'flex', gap: '15px' }}>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/nyc">New York City</Link>
</li>
<li>
<Link to="/la">Los Angeles</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/nyc" element={<NewYork />} />
<Route path="/la" element={<LosAngeles />} />
</Routes>
</Router>
);
};
export default App;You can refer to the screenshot below to see the output.

In this example, the to prop in the Link component tells the app which path to load. I find this much cleaner than managing window locations manually.
Use the “to” Prop with Objects
Sometimes, you need to send more than just a URL string. You might want to pass search parameters or a state to the destination page.
I often use this when I want to pass a specific “referral” code or a “category” filter without making the URL messy.
Here is how you can pass an object to the to prop.
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link, useLocation } from 'react-router-dom';
const Chicago = () => {
const location = useLocation();
const { fromDashboard } = location.state || {};
return (
<div style={{ padding: '20px' }}>
<h2>Chicago: The Windy City</h2>
<p>Known for its stunning architecture and deep-dish pizza.</p>
{fromDashboard && <p style={{ color: 'blue' }}>You arrived here from the Admin Dashboard!</p>}
</div>
);
};
const Dashboard = () => (
<div style={{ padding: '20px' }}>
<h1>Admin Dashboard</h1>
<Link
to={{
pathname: "/chicago",
search: "?sort=popular",
hash: "#landmarks"
}}
state={{ fromDashboard: true }}
>
View Chicago Stats
</Link>
</div>
);
const App = () => {
return (
<Router>
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/chicago" element={<Chicago />} />
</Routes>
</Router>
);
};
export default App;You can refer to the screenshot below to see the output.

In my experience, using the state property is the best way to keep track of where a user came from without cluttering the URL.
Replace the History Entry
By default, every time a user clicks a Link, a new entry is added to the browser’s history stack.
However, there are times, like after a form submission or a login, when you want to replace the current entry instead of adding a new one.
This prevents the user from clicking the “Back” button and seeing the form or login page again.
You can achieve this using the replace prop.
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
const FinalizeTrip = () => (
<div style={{ padding: '20px' }}>
<h2>Booking Confirmed</h2>
<p>Your trip to Miami has been successfully scheduled.</p>
<Link to="/" replace>
Return to Home (History Replaced)
</Link>
</div>
);
const App = () => {
return (
<Router>
<Routes>
<Route path="/" element={<div><h1>Home Page</h1><Link to="/confirm">Confirm Trip</Link></div>} />
<Route path="/confirm" element={<FinalizeTrip />} />
</Routes>
</Router>
);
};
export default App;You can refer to the screenshot below to see the output.

Whenever I build checkout flows for US-based e-commerce sites, I always use the replace prop on the final confirmation button.
Style the Active Link with NavLink
While the standard Link is great, sometimes you need to show the user which page they are currently on.
React Router provides a special version of Link called NavLink for this exact purpose.
It automatically adds an “active” class to the element when the URL matches.
import React from 'react';
import { BrowserRouter as Router, Routes, Route, NavLink } from 'react-router-dom';
import './App.css'; // Assume you have CSS for .active-link
const Navigation = () => {
return (
<nav style={{ display: 'flex', gap: '20px', padding: '20px', borderBottom: '1px solid #ccc' }}>
<NavLink
to="/san-francisco"
style={({ isActive }) => ({
color: isActive ? 'red' : 'black',
fontWeight: isActive ? 'bold' : 'normal',
textDecoration: 'none'
})}
>
San Francisco
</NavLink>
<NavLink
to="/seattle"
style={({ isActive }) => ({
color: isActive ? 'red' : 'black',
fontWeight: isActive ? 'bold' : 'normal',
textDecoration: 'none'
})}
>
Seattle
</NavLink>
</nav>
);
};
const App = () => (
<Router>
<Navigation />
<Routes>
<Route path="/san-francisco" element={<div style={{padding: '20px'}}>Welcome to the Golden Gate City!</div>} />
<Route path="/seattle" element={<div style={{padding: '20px'}}>Welcome to the Emerald City!</div>} />
</Routes>
</Router>
);
export default App;I find NavLink indispensable for sidebars and headers where visual feedback is necessary for navigation.
Handle External Links
A common mistake I see developers make is trying to use the Link component for external websites like Google or LinkedIn.
The Link component is strictly for internal routing within your React app.
For external URLs, you should still use the standard <a> tag.
import React from 'react';
import { Link } from 'react-router-dom';
const Footer = () => {
return (
<footer style={{ marginTop: '50px', padding: '20px', backgroundColor: '#333', color: '#fff' }}>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<div>
<h3>Internal</h3>
<Link to="/about" style={{ color: '#fff' }}>About US Cities</Link>
</div>
<div>
<h3>External</h3>
<a href="https://www.usa.gov" target="_blank" rel="noopener noreferrer" style={{ color: '#fff' }}>
Official USA Government Portal
</a>
</div>
</div>
</footer>
);
};I always recommend adding rel=”noopener noreferrer” when using target=”_blank” for security reasons.
Programmatic Navigation vs. Link Component
While the Link component is the preferred way for user-initiated clicks, sometimes you need to trigger navigation in your code.
For example, after a user successfully logs into their account, you might want to redirect them to a profile page.
In these cases, you would use the useNavigate hook instead of the Link component.
import React from 'react';
import { useNavigate } from 'react-router-dom';
const Houston = () => {
const navigate = useNavigate();
const handleBooking = () => {
// Logic for booking a tour in Houston
console.log("Tour booked!");
// Programmatic redirect
navigate('/thank-you');
};
return (
<div style={{ padding: '20px' }}>
<h2>Houston, Texas</h2>
<button onClick={handleBooking} style={{ padding: '10px 20px', cursor: 'pointer' }}>
Book Space Center Tour
</button>
</div>
);
};I usually stick to the Link component for 90% of navigation needs and only use useNavigate for logic-based redirects.
Accessibility Considerations
One thing I’ve learned over the years is that accessibility should never be an afterthought.
The Link component is built with accessibility in mind, as it renders an <a> tag which screen readers recognize.
However, make sure your link text is descriptive. Instead of “Click here,” use “View details for New York City.”
This makes a huge difference for users who rely on assistive technologies.
Performance Benefits of the Link Component
Using Link prevents the browser from having to re-download your CSS and JavaScript bundles on every click.
In a large React application, this can save several megabytes of data transfer per user session.
I’ve seen page load times drop significantly just by switching from standard anchor tags to React Router navigation.
In this article, I have covered several ways to use the React Router Link component effectively.
Whether you are doing basic navigation, passing complex state, or styling active links, the Link component is your best friend.
You may read:
- React Functional Component Unmount
- Chakra UI React Component Library
- How to Use HeroUI (Formerly NextUI) in React
- React Component Composition Patterns

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.