Volver al inicio

Navegación por anclas en Next.js con useAnchorObserver

El artículo describe la implementación de navegación por anclas en una aplicación Next.js de una sola página usando el hook useAnchorObserver. La sincronización de scroll y URL está automatizada, soporte para historial del navegador y SEO. Se proporciona código completo con configuraciones.

App de una sola página en Next.js: navegación por anclas sin errores
Advertisement 728x90

Navegación por Anclas en una Aplicación de Página Única con Next.js

En aplicaciones de página única (SPA) con Next.js, la navegación por anclas permite transiciones fluidas entre secciones sin recargar la página. El hook useAnchorObserver de la biblioteca react-use-observer-hooks automatiza la sincronización del desplazamiento y la URL: detecta la sección visible durante el scroll y se desplaza al ancla cuando cambia la dirección.

El mecanismo funciona en ambas direcciones: el desplazamiento actualiza la URL mediante IntersectionObserver, mientras que los cambios en la URL (por clics o el botón de retroceso) activan el scroll hacia la sección. Esto evita bucles de retroalimentación y garantiza un manejo adecuado del historial del navegador.

Configuración del Proyecto

Utiliza Next.js 15 con Pages Router, React 19 y Tailwind CSS v4. Instala la dependencia:

Google AdInline article slot
npm install react-use-observer-hooks

Desactiva la restauración de scroll integrada en next.config.ts para evitar conflictos con el hook:

const nextConfig = {
  experimental: {
    scrollRestoration: false,
  },
};

Crea una ruta catch-all [[...slug]].tsx para manejar rutas como /, /about, /contact en una sola página.

Código de la Página Principal

Define un array de secciones con href, etiqueta y componentes:

Google AdInline article slot
import { useAnchorObserver } from 'react-use-observer-hooks';
import { useRouter } from 'next/router';

const SECTIONS = [
  { href: '/',        label: 'Inicio',    Component: HomeSection },
  { href: '/about',   label: 'Acerca de',   Component: AboutSection },
  { href: '/contact', label: 'Únete', Component: ContactSection },
];

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

  const { ref, focusedAnchor } = useAnchorObserver<HTMLDivElement>({
    anchors: SECTIONS.map(s => s.href),
    currentAnchor: router.asPath,
    onAnchorChange: (anchor) => {
      router.push(anchor, undefined, { scroll: false, shallow: true });
    },
  });

  return (
    <>
      <Navbar sections={SECTIONS} activeHref={focusedAnchor} />

      <div ref={ref}>
        {SECTIONS.map(({ href, Component }) => (
          <section key={href} style={{ minHeight: '100vh' }}>
            <Component />
          </section>
        ))}
      </div>
    </>
  );
}

Aspectos clave:

  • ref se aplica al contenedor de secciones. El hook mapea los hijos directos por índice al array anchors.
  • scroll: false en router.push evita el auto-scroll de Next.js.
  • shallow: true optimiza la navegación sin re-renderizados del servidor.

Componente de Navegación

Navbar utiliza <Link> con las mismas opciones:

import Link from 'next/link';

export const Navbar = ({ sections, activeHref }) => (
  <nav>
    {sections.map(({ href, label }) => (
      <Link
        key={href}
        href={href}
        scroll={false}
        shallow
        className={activeHref === href ? 'active' : ''}
      >
        {label}
      </Link>
    ))}
  </nav>
);

focusedAnchor resalta automáticamente el elemento activo según la sección visible.

Google AdInline article slot

Comportamiento de la Aplicación

La implementación resultante proporciona:

  • Acceso directo a enlaces como /about que aterrizan en la sección correcta.
  • Funcionalidad adecuada del botón de retroceso del navegador.
  • Indexación en motores de búsqueda con URLs únicas.
  • Sincronización del menú con el contenido visible.

Puntos Clave

  • El hook useAnchorObserver automatiza completamente la sincronización bidireccional de scroll y URL.
  • Desactivar scrollRestoration es esencial para evitar conflictos.
  • Las rutas catch-all en Pages Router son adecuadas para navegación tipo SPA.
  • shallow: true + scroll: false minimizan los re-renderizados.
  • El historial del navegador y el soporte SEO vienen incluidos.

— Editorial Team

Advertisement 728x90

Leer después