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:
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:
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:
refse aplica al contenedor de secciones. El hook mapea los hijos directos por índice al arrayanchors.scroll: falseenrouter.pushevita el auto-scroll de Next.js.shallow: trueoptimiza 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.
Comportamiento de la Aplicación
La implementación resultante proporciona:
- Acceso directo a enlaces como
/aboutque 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
useAnchorObserverautomatiza completamente la sincronización bidireccional de scroll y URL. - Desactivar
scrollRestorationes esencial para evitar conflictos. - Las rutas catch-all en Pages Router son adecuadas para navegación tipo SPA.
shallow: true+scroll: falseminimizan los re-renderizados.- El historial del navegador y el soporte SEO vienen incluidos.
— Editorial Team
Aún no hay comentarios.