
Using next/link for Client‑Side Navigation

One of the first habits developers need to unlearn when moving into Next.js is treating every internal link like a plain old HTML anchor.
An ordinary anchor works perfectly well in the browser:
<a href="/about">About</a>The trouble is that in a Next.js application, internal navigation can do more than a full page reload. It can stay on the client, preserve application state more gracefully, and feel noticeably faster. That is what next/link is for.
Link is the component for internal navigation
When navigating between pages inside a Next.js application, we use the Link component:
import Link from 'next/link';const Navigation = (): JSX.Element => { return ( <nav> <Link href="/about"> <a>About</a> </Link> </nav> );};That tells Next.js this is an internal route transition, not just a generic browser navigation.
Why Not Just Use a Normal Anchor
Because internal links in Next.js can be smarter.
Link enables client‑side navigation, which means the framework can:
- avoid a full document reload
- reuse the application shell more smoothly
- prefetch route resources in some cases
- make navigation feel faster and more app‑like
A plain anchor still works, but it gives up those benefits for internal routes.
The Difference Shows up in User Experience
With a full reload, the browser treats the destination like an entirely new page load. With client‑side navigation, the route change feels lighter because the application can stay alive while only the page content changes.
That does not mean every navigation becomes instant, of course. Data still needs to load and rendering still takes time. But the framework has much more room to make transitions feel efficient when it knows the link is internal.
That sounds like a small detail until a project gets large enough for navigation to become part of the performance story. On the Nando’s UK & Ireland Replatform, using Next.js routing properly mattered because internal journeys had to feel quick and predictable across a much broader site.
href points to the route, not the component
This sounds obvious, but it is worth being explicit about. Link works with the route path:
<Link href="/articles"> <a>Articles</a></Link>The link is not importing or targeting a component directly. It is targeting the URL that the file‑system router understands.
That keeps navigation aligned with the route layer rather than with arbitrary implementation details.
The nested <a> matters in this era of Next.js
At the time of writing, the conventional pattern is:
<Link href="/about"> <a>About</a></Link>That anchor is still the actual clickable element, which means we keep ordinary HTML semantics for links. The Link component enhances navigation behaviour around it.
This is one of the reasons the pattern works well. It does not throw away what an anchor already is. It adds framework‑aware routing behaviour to it.
Use Link for internal routes, not external ones
This is a very common beginner mistake.
If the destination is another page inside the same Next.js application, Link is appropriate.
If the destination is an external site, a normal anchor is usually the right tool:
<a href="https://example.com">External site</a>There is no client‑side route transition to optimise there. It is simply a standard link to another origin.
Prefetching is One of the Quiet Advantages
Next.js can prefetch route resources for links that are likely to be visited soon, especially when they enter the viewport.
That means the user may perceive navigation as faster because some of the work has already started before they click.
This is one of those features that often goes unnoticed when it is working well. That is usually a good sign. Fast‑feeling navigation is more impressive when the user does not have to think about why it feels smooth.
Dynamic routes still work through Link
Links are not limited to flat static paths. As the route structure grows, Link remains the way we connect the user to internal destinations.
In a content site, for instance, article cards can use internal links naturally:
<Link href="/articles/accessibility-basics"> <a>Accessibility basics</a></Link>That keeps navigation explicit and still lets Next.js treat the transition as part of the application.
The Component Improves Routing, Not Semantics
This distinction matters because developers sometimes start thinking of Link as a replacement for accessible link behaviour. It is not.
The semantics still come from the anchor:
- keyboard interaction
- screen‑reader expectations
- link meaning
Next.js is helping with routing performance and application behaviour. The underlying HTML still matters.
Internal Navigation is One of the Places Frameworks Earn Their Keep
A lot of framework features sound impressive in architecture diagrams. Internal navigation is much more immediate. Users can feel the difference between a site that reloads clumsily and one that moves between sections with less friction.
next/link is part of how Next.js creates that smoother experience without demanding much custom code from the developer.
Common Mistakes
The same mistakes appear repeatedly:
- using plain anchors for internal routes everywhere
- using
Linkfor external destinations - forgetting the nested anchor pattern
- treating
Linkas though it were a generic wrapper for anything clickable
Most of these come from not separating "navigation within the app" from "ordinary hyperlinks in general".
This is a Small API with a Large Impact
next/link is not a complicated feature. That is part of its strength.
The component does one very important job: it tells Next.js that a link is part of the app's route system, and that the framework should handle the transition accordingly.
That small bit of intent unlocks better navigation behaviour than a raw anchor alone could provide in this context.
Internal Navigation Deserves an App‑Aware Link
Next.js treats internal navigation as part of the application, not just as document‑to‑document movement. next/link is the API that expresses that idea. Once you adopt it consistently for internal routes, the application becomes simpler for the developer and often feels faster for the user.
That is a very good trade for such a small piece of framework syntax.
Related Articles

Event Delegation in JavaScript. 
Dynamic Navigation with React Router. Dynamic Navigation with React Router

The Difference Between JavaScript Callbacks and Promises. The Difference Between JavaScript Callbacks and Promises

LeetCode: Removing the nth Node from the End of a List. LeetCode: Removing the
nthNode from the End of a List
Adding Static Files to a Gatsby Site. Adding Static Files to a Gatsby Site
Get the Number of Years Between Two Dates with PHP and JavaScript. Get the Number of Years Between Two Dates with PHP and JavaScript

Understanding Phantom window.resize Events in iOS. Understanding Phantom
window.resizeEvents in iOS
Sliding Window Fundamentals: Solving 'Longest Substring Without Repeating Characters'. Sliding Window Fundamentals: Solving 'Longest Substring Without Repeating Characters'

Generate Parentheses in TypeScript: A Clean Backtracking Walkthrough. Generate Parentheses in TypeScript: A Clean Backtracking Walkthrough

Dynamic Array Manipulation with JavaScript's splice(). Dynamic Array Manipulation with JavaScript's
splice()
Understanding Tail call Optimisation in JavaScript. Understanding Tail call Optimisation in JavaScript

Using Middleware in Next.js for Route Protection. Using Middleware in Next.js for Route Protection