![]()
Using <Link> with Incorrect Paths in React Router
A common React Router mistake is providing invalid paths to the <Link> component, which can lead to broken navigation or unexpected behavior. Let’s explore proper usage and common pitfalls.
The Problem
// ❌ Common incorrect usages
<Link to="about">About</Link> // Relative path issues
<Link to="/about/">About</Link> // Trailing slash inconsistency
<Link to={{ path: '/about' }}>About</Link> // Wrong object format
<Link to={undefined}>Home</Link> // Undefined path
Why these cause problems:
- Relative paths might not resolve as expected
- Trailing slashes can cause route mismatches
- Incorrect object format won’t navigate properly
- Undefined paths break navigation entirely
Correct Solutions
1. Absolute Paths (Recommended)
// ✅ Correct absolute path
<Link to="/about">About</Link>
2. Relative Paths (With Context)
// When current URL is "/users"
<Link to="profile">Profile</Link> // ✅ Navigates to "/users/profile"
3. Path Objects (Advanced)
// ✅ Correct object format
<Link to={{
pathname: '/users',
search: '?sort=name',
hash: '#results'
}}>
Users
</Link>
4. Dynamic Paths
// ✅ Using template literals
<Link to={`/users/${userId}`}>User Profile</Link>
Common Mistakes to Avoid
- Inconsistent trailing slashes:
// ❌ Inconsistent with route definitions
<Link to="/about/">About</Link>
// When route is defined as:
<Route path="about" element={<About />} />
- Relative paths without context:
// ❌ Might not resolve as expected
<Link to="profile">Profile</Link>
- Malformed objects:
// ❌ Wrong property names
<Link to={{ url: '/about' }}>About</Link>
- Using href instead of to:
// ❌ Wrong prop (this will do full page reload)
<Link href="/about">About</Link>
Best Practices
- Match route definitions exactly:
// Route definition
<Route path="about-us" element={<About />} />
// Link should match
<Link to="/about-us">About Us</Link>
- Prefer absolute paths for main navigation
- Use relative paths carefully within nested routes
- Normalize paths across your application
- TypeScript users – Define path types for safety:
type AppPaths = '/about' | '/users' | `/users/${number}`;
interface AppLinkProps {
to: AppPaths;
children: React.ReactNode;
}
Advanced Patterns
1. Custom Link Component
function AppLink({ to, ...props }) {
const resolved = useResolvedPath(to);
const match = useMatch({ path: resolved.pathname, end: true });
return (
<Link
to={to}
className={match ? 'active' : ''}
{...props}
/>
);
}
// Usage
<AppLink to="/about">About</AppLink>
2. Type-Safe Links (TypeScript)
const routes = {
home: '/',
about: '/about',
user: (id: number) => `/users/${id}`
} as const;
type RoutePath =
| typeof routes.home
| typeof routes.about
| ReturnType<typeof routes.user>;
function TypedLink({ to, ...props }: { to: RoutePath } & LinkProps) {
return <Link to={to} {...props} />;
}
// Usage
<TypedLink to={routes.user(123)}>User</TypedLink>
3. Active Link Detection
function NavLink({ to, ...props }) {
return (
<Link
to={to}
className={({ isActive }) => isActive ? 'active' : ''}
{...props}
/>
);
}
Remember: Consistent path usage throughout your application prevents routing issues. Always:
- Verify your
<Link>paths match your<Route>definitions - Prefer absolute paths for clarity
- Use the
toprop (nothref) - Consider TypeScript for path validation in larger apps
- Test your links with various routing scenarios
For nested routes, remember that relative paths are resolved relative to their current route context, so plan your route structure carefully.
