0% found this document useful (0 votes)
18 views12 pages

Getting Started - Linking and Navigating - Next - Js

Uploaded by

q7qcyfbxwb
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views12 pages

Getting Started - Linking and Navigating - Next - Js

Uploaded by

q7qcyfbxwb
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

2025/9/5 14:45 Getting Started: Linking and Navigating | Next.

js

Menu

App Router Getting Started Linking and Navigating

Copy page

Linking and Navigating


In [Link], routes are rendered on the server by default. This often means the client has to
wait for a server response before a new route can be shown. [Link] comes with built-in
prefetching, streaming, and client-side transitions ensuring navigation stays fast and
responsive.

This guide explains how navigation works in [Link] and how you can optimize it for
dynamic routes and slow networks.

How navigation works


To understand how navigation works in [Link], it helps to be familiar with the following
concepts:

- Server Rendering
- Prefetching
- Streaming
- Client-side transitions

Server Rendering
In [Link], Layouts and Pages are React Server Components by default. On initial and
subsequent navigations, the Server Component Payload is generated on the server before
being sent to the client.

[Link] 1/12
2025/9/5 14:45 Getting Started: Linking and Navigating | [Link]

There are two types of server rendering, based on when it happens:

- Static Rendering (or Prerendering) happens at build time or during revalidation and
the result is cached.
- Dynamic Rendering happens at request time in response to a client request.

The trade-off of server rendering is that the client must wait for the server to respond
before the new route can be shown. [Link] addresses this delay by prefetching routes the
user is likely to visit and performing client-side transitions.

Good to know: HTML is also generated for the initial visit.

Prefetching
Prefetching is the process of loading a route in the background before the user navigates
to it. This makes navigation between routes in your application feel instant, because by the
time a user clicks on a link, the data to render the next route is already available client
side.

[Link] automatically prefetches routes linked with the <Link> component when they
enter the user's viewport.

app/[Link] TypeScript

[Link] 2/12
2025/9/5 14:45 Getting Started: Linking and Navigating | [Link]

import Link from 'next/link'

export default function Layout({ children }: { children: [Link] }) {


return (
<html>
<body>
<nav>
{/* Prefetched when the link is hovered or enters the viewport */}
<Link href="/blog">Blog</Link>
{/* No prefetching */}
<a href="/contact">Contact</a>
</nav>
{children}
</body>
</html>
)
}

How much of the route is prefetched depends on whether it's static or dynamic:

- Static Route: the full route is prefetched.


- Dynamic Route: prefetching is skipped, or the route is partially prefetched if
[Link] is present.

By skipping or partially prefetching dynamic routes, [Link] avoids unnecessary work on


the server for routes the users may never visit. However, waiting for a server response
before navigation can give the users the impression that the app is not responding.

To improve the navigation experience to dynamic routes, you can use streaming.
[Link] 3/12
2025/9/5 14:45 Getting Started: Linking and Navigating | [Link]

Streaming
Streaming allows the server to send parts of a dynamic route to the client as soon as
they're ready, rather than waiting for the entire route to be rendered. This means users see
something sooner, even if parts of the page are still loading.

For dynamic routes, it means they can be partially prefetched. That is, shared layouts and
loading skeletons can be requested ahead of time.

To use streaming, create a [Link] in your route folder:

app/dashboard/[Link] TypeScript

export default function Loading() {


// Add fallback UI that will be shown while the route is loading.
[Link] 4/12
2025/9/5 14:45 Getting Started: Linking and Navigating | [Link]
return <LoadingSkeleton />
}

Behind the scenes, [Link] will automatically wrap the [Link] contents in a
<Suspense> boundary. The prefetched fallback UI will be shown while the route is loading,
and swapped for the actual content once ready.

Good to know: You can also use <Suspense> to create loading UI for nested components.

Benefits of [Link] :

- Immediate navigation and visual feedback for the user.


- Shared layouts remain interactive and navigation is interruptible.
- Improved Core Web Vitals: TTFB , FCP , and TTI .

To further improve the navigation experience, [Link] performs a client-side transition with
the <Link> component.

Client-side transitions
Traditionally, navigation to a server-rendered page triggers a full page load. This clears
state, resets scroll position, and blocks interactivity.

[Link] avoids this with client-side transitions using the <Link> component. Instead of
reloading the page, it updates the content dynamically by:

- Keeping any shared layouts and UI.


- Replacing the current page with the prefetched loading state or a new page if available.

Client-side transitions are what makes a server-rendered apps feel like client-rendered
apps. And when paired with prefetching and streaming, it enables fast transitions, even for
dynamic routes.

What can make transitions slow?


[Link] 5/12
2025/9/5 14:45 Getting Started: Linking and Navigating | [Link]

These [Link] optimizations make navigation fast and responsive. However, under certain
conditions, transitions can still feel slow. Here are some common causes and how to
improve the user experience:

Dynamic routes without [Link]

When navigating to a dynamic route, the client must wait for the server response before
showing the result. This can give the users the impression that the app is not responding.

We recommend adding [Link] to dynamic routes to enable partial prefetching,


trigger immediate navigation, and display a loading UI while the route renders.

app/blog/[slug]/[Link] TypeScript

export default function Loading() {


return <LoadingSkeleton />
}

Good to know: In development mode, you can use the [Link] Devtools to identify if the route is
static or dynamic. See devIndicators for more information.

Dynamic segments without generateStaticParams

If a dynamic segment could be prerendered but isn't because it's missing


generateStaticParams , the route will fallback to dynamic rendering at request time.

Ensure the route is statically generated at build time by adding generateStaticParams :

app/blog/[slug]/[Link] TypeScript

export async function generateStaticParams() {


const posts = await fetch('[Link] => [Link]())

return [Link]((post) => ({


slug: [Link],
}))
}

export default async function Page({


params,
}: {

[Link] 6/12
2025/9/5 14:45 Getting Started: Linking and Navigating | [Link]
params: Promise<{ slug: string }>
}) {
const { slug } = await params
// ...
}

Slow networks
On slow or unstable networks, prefetching may not finish before the user clicks a link. This
can affect both static and dynamic routes. In these cases, the [Link] fallback may
not appear immediately because it hasn't been prefetched yet.

To improve perceived performance, you can use the useLinkStatus hook to show inline
visual feedback to the user (like spinners or text glimmers on the link) while a transition is
in progress.

app/ui/[Link] TypeScript

'use client'

import { useLinkStatus } from 'next/link'

export default function LoadingIndicator() {


const { pending } = useLinkStatus()
return pending ? (
<div role="status" aria-label="Loading" className="spinner" />
) : null
}

You can "debounce" the loading indicator by adding an initial animation delay (e.g. 100ms)
and starting the animation as invisible (e.g. opacity: 0 ). This means the loading indicator
will only be shown if the navigation takes longer than the specified delay.

.spinner {
/* ... */
opacity: 0;
animation:
fadeIn 500ms 100ms forwards,
rotate 1s linear infinite;
}

[Link] 7/12
2025/9/5 14:45 Getting Started: Linking and Navigating | [Link]
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

@keyframes rotate {
to {
transform: rotate(360deg);
}
}

Good to know: You can use other visual feedback patterns like a progress bar. View an example
here .

Disabling prefetching
You can opt out of prefetching by setting the prefetch prop to false on the <Link>
component. This is useful to avoid unnecessary usage of resources when rendering large
lists of links (e.g. an infinite scroll table).

<Link prefetch={false} href="/blog">


Blog
</Link>

However, disabling prefetching comes with trade-offs:

- Static routes will only be fetched when the user clicks the link.
- Dynamic routes will need to be rendered on the server first before the client can
navigate to it.

To reduce resource usage without fully disabling prefetch, you can prefetch only on hover.
This limits prefetching to routes the user is more likely to visit, rather than all links in the
viewport.

app/ui/[Link] TypeScript

[Link] 8/12
2025/9/5 14:45 Getting Started: Linking and Navigating | [Link]

'use client'

import Link from 'next/link'


import { useState } from 'react'

function HoverPrefetchLink({
href,
children,
}: {
href: string
children: [Link]
}) {
const [active, setActive] = useState(false)

return (
<Link
href={href}
prefetch={active ? null : false}
onMouseEnter={() => setActive(true)}
>
{children}
</Link>
)
}

Hydration not completed


<Link> is a Client Component and must be hydrated before it can prefetch routes. On the
initial visit, large JavaScript bundles can delay hydration, preventing prefetching from
starting right away.

React mitigates this with Selective Hydration and you can further improve this by:

- Using the @next/bundle-analyzer plugin to identify and reduce bundle size by


removing large dependencies.
- Moving logic from the client to the server where possible. See the Server and Client
Components docs for guidance.

Examples
Native History API
[Link] 9/12
2025/9/5 14:45 Getting Started: Linking and Navigating | [Link]

[Link] allows you to use the native [Link] and


[Link] methods to update the browser's history stack without
reloading the page.

pushState and replaceState calls integrate into the [Link] Router, allowing you to sync
with usePathname and useSearchParams .

[Link]

Use it to add a new entry to the browser's history stack. The user can navigate back to the
previous state. For example, to sort a list of products:

'use client'

import { useSearchParams } from 'next/navigation'

export default function SortProducts() {


const searchParams = useSearchParams()

function updateSorting(sortOrder: string) {


const params = new URLSearchParams([Link]())
[Link]('sort', sortOrder)
[Link](null, '', `?${[Link]()}`)
}

return (
<>
<button onClick={() => updateSorting('asc')}>Sort Ascending</button>
<button onClick={() => updateSorting('desc')}>Sort Descending</button>
</>
)
}

[Link]

Use it to replace the current entry on the browser's history stack. The user is not able to
navigate back to the previous state. For example, to switch the application's locale:

'use client'

import { usePathname } from 'next/navigation'

export function LocaleSwitcher() {


const pathname = usePathname()

function switchLocale(locale: string) {


[Link] 10/12
2025/9/5 14:45 Getting Started: Linking and Navigating | [Link]
// e.g. '/en/about' or '/fr/contact'
const newPath = `/${locale}${pathname}`
[Link](null, '', newPath)
}

return (
<>
<button onClick={() => switchLocale('en')}>English</button>
<button onClick={() => switchLocale('fr')}>French</button>
</>
)
}

Next Steps

Link Component [Link]


Enable fast client-side navigation with API reference for the [Link] file.
the built-in `next/link` component.

Prefetching
Learn how to configure prefetching in
[Link]

Previous Next
Layouts and Pages Server and Client Components

Was this helpful?

Resources More About Vercel Legal


[Link] 11/12
2025/9/5 14:45 Getting Started: Linking and Navigating | [Link]

Docs [Link] Commerce [Link] + Vercel Privacy Policy


Support Policy Contact Sales Open Source Software
Learn Community GitHub
Showcase GitHub Bluesky
Blog Releases X
Team Telemetry
Analytics Governance
[Link] Conf
Previews

Subscribe to our newsletter

Stay updated on new releases and


features, guides, and case studies.

you@[Link] Subscribe

© 2025 Vercel, Inc.

[Link] 12/12

You might also like