Navigation is a first-class concern in Next.js, and the framework provides both declarative and programmatic ways to move between routes. The <Link> component from next/link is the preferred way to navigate. It performs client-side transitions without a full page reload and, by default, prefetches the destination when the link enters the viewport, so the next page is essentially instant.
Static routes are fully prefetched, while dynamic routes are prefetched only up to the nearest loading.tsx boundary, which keeps prefetching costs bounded. You can opt out of prefetching on a per-link basis with prefetch={false} when the destination is unlikely to be visited or is expensive to load.
For programmatic navigation in Client Components, the useRouter hook from next/navigation exposes methods like router.push('/path') to navigate, router.replace('/path') to swap the current history entry, router.refresh() to re-fetch the current route's Server Components, and router.back() to move to the previous page. Two companion hooks are also worth knowing. The usePathname hook returns the current URL pathname as a string, which is handy for highlighting the active link in a navigation menu. The useSearchParams hook returns a read-only URLSearchParams object representing the query string, allowing you to read parameters like ?q=hello through searchParams.get('q'). Together with <Link>, they cover virtually every navigation pattern a typical application requires.