Skip to content

Latest commit

 

History

History
209 lines (143 loc) · 8.54 KB

03-linking-and-navigating.mdx

File metadata and controls

209 lines (143 loc) · 8.54 KB
title description related
Linking and Navigating
Learn how navigation works in Next.js, and how to use the Link Component and `useRouter` hook.
links
app/building-your-application/caching
app/building-your-application/configuring/typescript

There are two ways to navigate between routes in Next.js:

This page will go through how to use <Link>, useRouter(), and dive deeper into how navigation works.

<Link> Component

<Link> is a built-in component that extends the HTML <a> tag to provide prefetching and client-side navigation between routes. It is the primary way to navigate between routes in Next.js.

You can use it by importing it from next/link, and passing a href prop to the component:

import Link from 'next/link'

export default function Page() {
  return <Link href="/dashboard">Dashboard</Link>
}
import Link from 'next/link'

export default function Page() {
  return <Link href="/dashboard">Dashboard</Link>
}

There are other optional props you can pass to <Link>. See the API reference for more.

Examples

Linking to Dynamic Segments

When linking to dynamic segments, you can use template literals and interpolation to generate a list of links. For example, to generate a list of blog posts:

import Link from 'next/link'

export default function PostList({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          <Link href={`/blog/${post.slug}`}>{post.title}</Link>
        </li>
      ))}
    </ul>
  )
}

Checking Active Links

You can use usePathname() to determine if a link is active. For example, to add a class to the active link, you can check if the current pathname matches the href of the link:

'use client'

import { usePathname } from 'next/navigation'
import Link from 'next/link'

export function Navigation({ navLinks }) {
  const pathname = usePathname()

  return (
    <>
      {navLinks.map((link) => {
        const isActive = pathname === link.href

        return (
          <Link
            className={isActive ? 'text-blue' : 'text-black'}
            href={link.href}
            key={link.name}
          >
            {link.name}
          </Link>
        )
      })}
    </>
  )
}

Scrolling to an id

The default behavior of the Next.js App Router is to scroll to the top of a new route or to maintain the scroll position for backwards and forwards navigation.

If you'd like to scroll to a specific id on navigation, you can append your URL with a # hash link or just pass a hash link to the href prop. This is possible since <Link> renders to an <a> element.

<Link href="/dashboard#settings">Settings</Link>

// Output
<a href="/dashboard#settings">Settings</a>

Disabling scroll restoration

The default behavior of the Next.js App Router is to scroll to the top of a new route or to maintain the scroll position for backwards and forwards navigation. If you'd like to disable this behavior, you can pass scroll={false} to the <Link> component, or scroll: false to router.push() or router.replace().

// next/link
<Link href="/dashboard" scroll={false}>
  Dashboard
</Link>
// useRouter
import { useRouter } from 'next/navigation'

router.push('/dashboard', { scroll: false })

useRouter() Hook

The useRouter hook allows you to programmatically change routes.

This hook can only be used inside Client Components and is imported from next/navigation.

'use client'

import { useRouter } from 'next/navigation'

export default function Page() {
  const router = useRouter()

  return (
    <button type="button" onClick={() => router.push('/dashboard')}>
      Dashboard
    </button>
  )
}

For a full list of useRouter methods, see the API reference.

Recommendation: Use the <Link> component to navigate between routes unless you have a specific requirement for using useRouter.

How Routing and Navigation Works

The App Router uses a hybrid approach for routing and navigation. On the server, your application code is automatically code-split by route segments. And on the client, Next.js prefetches and caches the route segments. This means, when a user navigates to a new route, the browser doesn't reload the page, and only the route segments that change re-render - improving the navigation experience and performance.

1. Prefetching

Prefetching is a way to preload a route in the background before the user visits it.

There are two ways routes are prefetched in Next.js:

  • <Link> component: Routes are automatically prefetched as they become visible in the user's viewport. Prefetching happens when the page first loads or when it comes into view through scrolling.
  • router.prefetch(): The useRouter hook can be used to prefetch routes programmatically.

The<Link>'s prefetching behavior is different for static and dynamic routes:

  • Static Routes: prefetch defaults to true. The entire route is prefetched and cached.
  • Dynamic Routes: prefetch default to automatic. Only the shared layout down until the first loading.js file is prefetched and cached for 30s. This reduces the cost of fetching an entire dynamic route, and it means you can show an instant loading state for better visual feedback to users.

You can disable prefetching by setting the prefetch prop to false.

See the <Link> API reference for more information.

Good to know:

  • Prefetching is not enabled in development, only in production.

2. Caching

Next.js has an in-memory client-side cache called the Router Cache. As users navigate around the app, the React Server Component Payload of prefetched route segments and visited routes are stored in the cache.

This means on navigation, the cache is reused as much as possible, instead of making a new request to the server - improving performance by reducing the number of requests and data transferred.

Learn more about how the Router Cache works and how to configure it.

3. Partial Rendering

Partial rendering means only the route segments that change on navigation re-render on the client, and any shared segments are preserved.

For example, when navigating between two sibling routes, /dashboard/settings and /dashboard/analytics, the settings and analytics pages will be rendered, and the shared dashboard layout will be preserved.

How partial rendering works

Without partial rendering, each navigation would cause the full page to re-render on the server. Rendering only the segment that changes reduces the amount of data transferred and execution time, leading to improved performance.

4. Soft Navigation

By default, the browser performs a hard navigation between pages. This means the browser reloads the page and resets React state such as useState hooks in your app and browser state such as the user's scroll position or focused element. However, in Next.js, the App Router uses soft navigation. This means React only renders the segments that have changed while preserving React and browser state, and there is no full page reload.

5. Back and Forward Navigation

By default, Next.js will maintain the scroll position for backwards and forwards navigation, and re-use route segments in the Router Cache.