October 3, 2024
O. Wolfson
Currently Reading: Linking and Navigation, from the Next.js Docs.
Next.js offers multiple ways to navigate between routes, which can improve the user experience by speeding up page transitions and preserving state. Here’s a quick guide to the most common methods:
<Link>
ComponentThe <Link>
component is Next.js's recommended way to navigate between pages. It extends the HTML <a>
tag to include prefetching and client-side navigation.
Example:
jsximport Link from "next/link";
export default function Page() {
return <Link href="/dashboard">Go to Dashboard</Link>;
}
When you use <Link>
, Next.js automatically prefetches the linked page in the background, enhancing performance.
useRouter()
HookThe useRouter()
hook gives you programmatic control over navigation within Client Components. It’s great when you want to trigger navigation based on some logic (e.g., after a form submission).
Example:
jsx"use client";
import { useRouter } from "next/navigation";
export default function Page() {
const router = useRouter();
return (
<button onClick={() => router.push("/dashboard")}>Go to Dashboard</button>
);
}
redirect()
FunctionFor Server Components, you can use the redirect()
function to change routes, especially after fetching some data or handling server logic.
Example:
tsimport { redirect } from "next/navigation";
export default async function Profile({ params }) {
const team = await fetchTeam(params.id);
if (!team) {
redirect("/login");
}
// Render profile if the team exists
}
This is particularly useful in server actions or when redirecting users based on server-side data.
Next.js allows you to use the native browser history methods, pushState
and replaceState
. These are useful for updating the URL without triggering a full page reload.
Example (Sorting Products):
jsx"use client";
export default function SortProducts() {
function updateSorting(order) {
const params = new URLSearchParams(window.location.search);
params.set("sort", order);
window.history.pushState(null, "", `?${params.toString()}`);
}
return (
<div>
<button onClick={() => updateSorting("asc")}>Sort Ascending</button>
<button onClick={() => updateSorting("desc")}>Sort Descending</button>
</div>
);
}
This approach is more manual and gives you fine control over the browser's history stack.
Next.js optimizes navigation performance by combining client-side techniques and server capabilities:
Next.js automatically splits your code into smaller chunks by route. This reduces the amount of code downloaded during navigation, leading to faster page loads.
By default, Next.js preloads routes when they appear in the viewport or when the page is loaded, improving page load times on navigation.
Next.js uses a client-side cache to store prefetched route segments, which reduces the need for repeated server requests during navigation.
When you navigate between sibling routes (e.g., /dashboard/settings
and /dashboard/analytics
), only the changing parts of the page are rendered. The shared layout remains the same, leading to faster transitions.
Next.js enables "soft navigation," where only the necessary route segments are re-rendered, preserving React state and improving performance.
Next.js automatically maintains the scroll position and reuses cached route segments when navigating backwards and forwards in the browser.
Next.js offers multiple navigation tools for various scenarios:
<Link>
for standard client-side navigation.useRouter()
for programmatic navigation in Client Components.redirect()
in Server Components for server-side redirects.history
API when fine control over the URL is needed without reloading the page.Each of these tools is designed to optimize performance and improve the user experience by minimizing page reloads and leveraging Next.js’s built-in caching and prefetching capabilities.