Enlaces y Navegación

Existen dos formas de navegar entre rutas en Next.js:

Esta página explicará cómo usar <Link>, useRouter(), y profundizará en cómo funciona la navegación.

<Link> es un componente integrado que extiende la etiqueta HTML <a> para proporcionar precarga (prefetching) y navegación del lado del cliente entre rutas. Es la forma principal de navegar entre rutas en Next.js.

Puedes usarlo importándolo desde next/link y pasando una prop href al componente:

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>
}

Hay otras props opcionales que puedes pasar a <Link>. Consulta la referencia de API para más información.

Ejemplos

Enlaces a Segmentos Dinámicos

Al enlazar a segmentos dinámicos, puedes usar template literals e interpolación para generar una lista de enlaces. Por ejemplo, para generar una lista de publicaciones de blog:

app/blog/PostList.js
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>
  )
}

Verificación de Enlaces Activos

Puedes usar usePathname() para determinar si un enlace está activo. Por ejemplo, para agregar una clase al enlace activo, puedes verificar si el pathname actual coincide con el href del enlace:

'use client'

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

export function Links() {
  const pathname = usePathname()

  return (
    <nav>
      <ul>
        <li>
          <Link className={`link ${pathname === '/' ? 'active' : ''}`} href="/">
            Inicio
          </Link>
        </li>
        <li>
          <Link
            className={`link ${pathname === '/about' ? 'active' : ''}`}
            href="/about"
          >
            Acerca de
          </Link>
        </li>
      </ul>
    </nav>
  )
}
'use client'

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

export function Links() {
  const pathname = usePathname()

  return (
    <nav>
      <ul>
        <li>
          <Link className={`link ${pathname === '/' ? 'active' : ''}`} href="/">
            Inicio
          </Link>
        </li>
        <li>
          <Link
            className={`link ${pathname === '/about' ? 'active' : ''}`}
            href="/about"
          >
            Acerca de
          </Link>
        </li>
      </ul>
    </nav>
  )
}

Desplazamiento a un id

El comportamiento predeterminado del App Router de Next.js es desplazarse al inicio de una nueva ruta o mantener la posición de desplazamiento para la navegación hacia atrás y adelante.

Si deseas desplazarte a un id específico durante la navegación, puedes agregar un enlace hash # a tu URL o simplemente pasar un enlace hash a la prop href. Esto es posible porque <Link> se renderiza como un elemento <a>.

<Link href="/dashboard#settings">Configuración</Link>

// Salida
<a href="/dashboard#settings">Configuración</a>

Deshabilitar la restauración del desplazamiento

El comportamiento predeterminado del App Router de Next.js es desplazarse al inicio de una nueva ruta o mantener la posición de desplazamiento para la navegación hacia atrás y adelante. Si deseas deshabilitar este comportamiento, puedes pasar scroll={false} al componente <Link>, o scroll: false a router.push() o router.replace().

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

const router = useRouter()

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

Hook useRouter()

El hook useRouter te permite cambiar rutas programáticamente.

Este hook solo puede usarse dentro de Componentes del Cliente y se importa desde next/navigation.

app/page.js
'use client'

import { useRouter } from 'next/navigation'

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

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

Para una lista completa de métodos de useRouter, consulta la referencia de API.

Recomendación: Usa el componente <Link> para navegar entre rutas a menos que tengas un requisito específico para usar useRouter.

Cómo Funcionan el Enrutamiento y la Navegación

El App Router utiliza un enfoque híbrido para el enrutamiento y la navegación. En el servidor, tu código de aplicación se divide automáticamente por segmentos de ruta. Y en el cliente, Next.js precarga (prefetches) y almacena en caché los segmentos de ruta. Esto significa que, cuando un usuario navega a una nueva ruta, el navegador no recarga la página, y solo los segmentos de ruta que cambian se vuelven a renderizar, mejorando la experiencia de navegación y el rendimiento.

1. Precarga (Prefetching)

La precarga es una forma de cargar una ruta en segundo plano antes de que el usuario la visite.

Hay dos formas en que las rutas se precargan en Next.js:

  • Componente <Link>: Las rutas se precargan automáticamente cuando son visibles en el viewport del usuario. La precarga ocurre cuando la página se carga por primera vez o cuando aparece en la vista al desplazarse.
  • router.prefetch(): El hook useRouter se puede usar para precargar rutas programáticamente.

El comportamiento de precarga de <Link> es diferente para rutas estáticas y dinámicas:

  • Rutas estáticas: prefetch tiene como valor predeterminado true. Toda la ruta se precarga y almacena en caché.
  • Rutas dinámicas: prefetch tiene como valor predeterminado automático. Solo el diseño compartido hasta el primer archivo loading.js se precarga y almacena en caché durante 30s. Esto reduce el costo de cargar una ruta dinámica completa y significa que puedes mostrar un estado de carga instantánea para una mejor retroalimentación visual a los usuarios.

Puedes deshabilitar la precarga estableciendo la prop prefetch en false.

Consulta la referencia de API de <Link> para más información.

Nota importante:

  • La precarga no está habilitada en desarrollo, solo en producción.

2. Almacenamiento en Caché

Next.js tiene una caché en memoria del lado del cliente llamada Router Cache. A medida que los usuarios navegan por la aplicación, la carga útil del Componente de Servidor React de los segmentos de ruta precargados y las rutas visitadas se almacenan en la caché.

Esto significa que, al navegar, la caché se reutiliza tanto como sea posible, en lugar de hacer una nueva solicitud al servidor, mejorando el rendimiento al reducir la cantidad de solicitudes y datos transferidos.

Aprende más sobre cómo funciona la Router Cache y cómo configurarla.

3. Renderizado Parcial

El renderizado parcial significa que solo los segmentos de ruta que cambian durante la navegación se vuelven a renderizar en el cliente, y cualquier segmento compartido se preserva.

Por ejemplo, al navegar entre dos rutas hermanas, /dashboard/settings y /dashboard/analytics, las páginas settings y analytics se renderizarán, y el diseño compartido dashboard se preservará.

Cómo funciona el renderizado parcial

Sin el renderizado parcial, cada navegación causaría que la página completa se volviera a renderizar en el servidor. Renderizar solo el segmento que cambia reduce la cantidad de datos transferidos y el tiempo de ejecución, lo que mejora el rendimiento.

4. Navegación Suave

Por defecto, el navegador realiza una navegación dura entre páginas. Esto significa que el navegador recarga la página y restablece el estado de React, como los hooks useState en tu aplicación, y el estado del navegador, como la posición de desplazamiento o el elemento enfocado del usuario. Sin embargo, en Next.js, el App Router utiliza navegación suave. Esto significa que React solo renderiza los segmentos que han cambiado mientras preserva el estado de React y del navegador, y no hay recarga completa de la página.

5. Navegación Atrás y Adelante

Por defecto, Next.js mantendrá la posición de desplazamiento para la navegación hacia atrás y adelante, y reutilizará los segmentos de ruta en la Router Cache.