Linking and Navigation

beginner
9 min

Linking and Navigation

You now know how routes are created - this lesson is about moving between them. Next.js replaces the plain anchor tag with a smarter Link component that enables client-side navigation, prefetching, and preserved layout state. You will also learn programmatic navigation with useRouter and how to read the current URL.

Why Not Just Use an Anchor Tag?

A regular a tag triggers a full page load: the browser throws away the current page, downloads everything again, and re-runs all JavaScript. The Link component intercepts the click, fetches only the parts of the new route that changed, and swaps them in. Layouts persist, state survives, and navigation feels instant.

Using the Link Component

jsx
// app/components/Navbar.js import Link from 'next/link'; export default function Navbar() { return ( <nav> <Link href='/'>Home</Link> <Link href='/blog'>Blog</Link> <Link href='/about'>About</Link> <Link href={{ pathname: '/search', query: { q: 'nextjs' } }}> Search </Link> </nav> ); }

Link renders a real anchor tag in the HTML, so right-click, open in new tab, and SEO crawling all still work. The href can be a string or an object with pathname and query.

Prefetching: Speed for Free

In production, Next.js automatically prefetches a route when its Link scrolls into the viewport. By the time the user clicks, much of the destination is already loaded. You can opt out for rarely-used links:

jsx
<Link href='/archive' prefetch={false}>Old Archive</Link>

Prefetching only happens in production builds, so do not look for it in npm run dev.

Highlighting the Active Link

Navigation bars usually highlight the current page. Use the usePathname hook in a Client Component:

jsx
'use client'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; export default function NavLink({ href, children }) { const pathname = usePathname(); const isActive = pathname === href; return ( <Link href={href} className={isActive ? 'active' : ''}> {children} </Link> ); }

The 'use client' directive is required because hooks only run in Client Components - Lesson 6 explains this boundary in depth.

Programmatic Navigation with useRouter

Sometimes navigation happens after an action - submitting a form, finishing a login. Use the useRouter hook from next/navigation:

jsx
'use client'; import { useRouter } from 'next/navigation'; export default function LoginButton() { const router = useRouter(); async function handleLogin() { // ...authenticate... router.push('/dashboard'); } return <button onClick={handleLogin}>Log in</button>; }

Useful router methods:

  • router.push(href) - navigate and add a history entry.
  • router.replace(href) - navigate without adding to history.
  • router.back() and router.forward() - move through history.
  • router.refresh() - re-fetch server data for the current route.

Important: import from next/navigation, not the legacy next/router, when using the App Router.

Redirecting on the Server

Server Components cannot use hooks, but they can redirect:

jsx
import { redirect } from 'next/navigation'; export default async function ProfilePage() { const user = await getUser(); if (!user) redirect('/login'); return <h1>Welcome, {user.name}</h1>; }

redirect throws internally, so code after it never runs - no need for a return statement.

Key Takeaways

  • Link gives you client-side navigation with real anchor semantics and automatic prefetching.
  • usePathname identifies the active route for nav highlighting.
  • useRouter (from next/navigation) handles navigation after user actions.
  • redirect covers server-side navigation guards in Server Components.

Next up: Lesson 6 tackles the most important concept in modern Next.js - the difference between Server Components and Client Components.

Linking and Navigation - Next.js | CodeYourCraft | CodeYourCraft