Navegación entre páginas

En el capítulo anterior, creaste el diseño del dashboard y sus páginas. Ahora, agreguemos algunos enlaces para permitir a los usuarios navegar entre las rutas del dashboard.

¿Por qué optimizar la navegación?

Para enlazar entre páginas, tradicionalmente se usaría el elemento HTML <a>. Actualmente, los enlaces de la barra lateral usan elementos <a>, pero observa lo que sucede cuando navegas entre las páginas de inicio, facturas y clientes en tu navegador.

¿Lo notaste?

¡Hay una recarga completa de la página en cada navegación!

En Next.js, puedes usar el componente <Link /> para enlazar entre páginas de tu aplicación. <Link> permite realizar navegación del lado del cliente (client-side navigation) con JavaScript.

Para usar el componente <Link />, abre /app/ui/dashboard/nav-links.tsx, e importa el componente Link desde next/link. Luego, reemplaza la etiqueta <a> con <Link>:

/app/ui/dashboard/nav-links.tsx
import {
  UserGroupIcon,
  HomeIcon,
  DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
 
// ...
 
export default function NavLinks() {
  return (
    <>
      {links.map((link) => {
        const LinkIcon = link.icon;
        return (
          <Link
            key={link.name}
            href={link.href}
            className="flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3"
          >
            <LinkIcon className="w-6" />
            <p className="hidden md:block">{link.name}</p>
          </Link>
        );
      })}
    </>
  );
}

Como puedes ver, el componente Link es similar a usar etiquetas <a>, pero en lugar de <a href="…">, usas <Link href="…">.

Guarda los cambios y verifica si funciona en tu localhost. Ahora deberías poder navegar entre las páginas sin ver una recarga completa. Aunque partes de tu aplicación se renderizan en el servidor, no hay una recarga completa de página, lo que hace que se sienta como una aplicación web nativa. ¿Por qué sucede esto?

División de código automática y precarga (Automatic code-splitting and prefetching)

Para mejorar la experiencia de navegación, Next.js divide automáticamente el código de tu aplicación por segmentos de ruta. Esto es diferente de una SPA (Single Page Application) tradicional de React, donde el navegador carga todo el código de tu aplicación en la carga inicial de la página.

Dividir el código por rutas significa que las páginas quedan aisladas. Si una página específica genera un error, el resto de la aplicación seguirá funcionando. Esto también significa menos código para que el navegador analice, lo que hace que tu aplicación sea más rápida.

Además, en producción, cuando los componentes <Link> aparecen en el viewport del navegador, Next.js precarga automáticamente el código para la ruta enlazada en segundo plano. Cuando el usuario hace clic en el enlace, el código de la página de destino ya estará cargado, ¡y esto es lo que hace que la transición entre páginas sea casi instantánea!

Aprende más sobre cómo funciona la navegación.

Patrón: Mostrar enlaces activos

Un patrón de UI común es mostrar un enlace activo para indicar al usuario en qué página se encuentra actualmente. Para hacer esto, necesitas obtener la ruta actual del usuario desde la URL. Next.js proporciona un hook llamado usePathname() que puedes usar para verificar la ruta e implementar este patrón.

Dado que usePathname() es un hook de React, necesitarás convertir nav-links.tsx en un Componente del Cliente. Agrega la directiva "use client" de React al inicio del archivo, luego importa usePathname() desde next/navigation:

/app/ui/dashboard/nav-links.tsx
'use client';
 
import {
  UserGroupIcon,
  HomeIcon,
  DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
 
// ...

Luego, asigna la ruta a una variable llamada pathname dentro de tu componente <NavLinks />:

/app/ui/dashboard/nav-links.tsx
export default function NavLinks() {
  const pathname = usePathname();
  // ...
}

Nota: nav-links.tsx no es un archivo especial para Next.js — puede tener cualquier nombre. Si lo renombras, asegúrate de actualizar las declaraciones de importación correspondientes.

Puedes usar la biblioteca clsx presentada en el capítulo sobre estilos CSS para aplicar condicionalmente clases cuando el enlace está activo. Cuando link.href coincide con pathname, el enlace debe mostrarse con texto azul y un fondo azul claro.

Aquí está el código final para nav-links.tsx:

/app/ui/dashboard/nav-links.tsx
'use client';
 
import {
  UserGroupIcon,
  HomeIcon,
  DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import clsx from 'clsx';
 
// ...
 
export default function NavLinks() {
  const pathname = usePathname();
 
  return (
    <>
      {links.map((link) => {
        const LinkIcon = link.icon;
        return (
          <Link
            key={link.name}
            href={link.href}
            className={clsx(
              'flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3',
              {
                'bg-sky-100 text-blue-600': pathname === link.href,
              },
            )}
          >
            <LinkIcon className="w-6" />
            <p className="hidden md:block">{link.name}</p>
          </Link>
        );
      })}
    </>
  );
}

Guarda y verifica en tu localhost. Ahora deberías ver el enlace activo resaltado en azul.

On this page