홈으로 돌아가기

Next.js에서 useAnchorObserver를 사용한 앵커 네비게이션

이 기사는 useAnchorObserver 훅을 사용한 싱글 페이지 Next.js 애플리케이션의 앵커 네비게이션 구현을 설명합니다. 스크롤과 URL 동기화가 자동화되며, 브라우저 히스토리와 SEO 지원. 설정과 함께 전체 코드 제공.

Next.js 싱글 페이지 앱: 버그 없는 앵커 네비게이션
Advertisement 728x90

Next.js 싱글 페이지 애플리케이션에서 앵커 네비게이션 구현하기

Next.js 싱글 페이지 애플리케이션에서 앵커 네비게이션은 페이지를 새로 고치지 않고도 섹션 간에 매끄럽게 이동할 수 있게 해줍니다. react-use-observer-hooks 라이브러리의 useAnchorObserver 훅은 스크롤과 URL 동기화를 자동화합니다: 스크롤 중에 보이는 섹션을 감지하고, 주소가 변경되면 해당 앵커로 스크롤합니다.

이 메커니즘은 양방향으로 작동합니다: 스크롤은 IntersectionObserver를 통해 URL을 업데이트하고, URL 변경(클릭이나 뒤로 가기 버튼으로 인한)은 해당 섹션으로 스크롤을 트리거합니다. 이는 피드백 루프를 방지하고 적절한 브라우저 기록 처리를 보장합니다.

프로젝트 설정

Next.js 15(페이지 라우터), React 19, Tailwind CSS v4를 사용합니다. 의존성을 설치하세요:

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

훅과의 충돌을 피하기 위해 next.config.ts에서 기본 제공되는 스크롤 복원을 비활성화하세요:

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

/, /about, /contact와 같은 경로를 단일 페이지에서 처리하기 위해 catch-all 라우트 [[...slug]].tsx를 생성하세요.

메인 페이지 코드

href, label, 컴포넌트가 포함된 섹션 배열을 정의하세요:

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

const SECTIONS = [
  { href: '/',        label: '홈',    Component: HomeSection },
  { href: '/about',   label: '소개',   Component: AboutSection },
  { href: '/contact', label: '참여하기', 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>
    </>
  );
}

핵심 요소:

  • ref는 섹션 컨테이너에 적용됩니다. 훅은 직접적인 자식 요소를 인덱스로 anchors 배열에 매핑합니다.
  • router.pushscroll: false는 Next.js의 자동 스크롤을 방지합니다.
  • shallow: true는 서버 재렌더링 없이 네비게이션을 최적화합니다.

네비게이션 컴포넌트

Navbar는 동일한 옵션으로 <Link>를 사용합니다:

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는 보이는 섹션을 기반으로 활성 항목을 자동으로 강조 표시합니다.

Google AdInline article slot

애플리케이션 동작

결과적인 구현은 다음과 같은 기능을 제공합니다:

  • /about에 직접 링크 접근 시 올바른 섹션으로 이동.
  • 적절한 브라우저 뒤로 가기 버튼 기능.
  • 고유 URL로 검색 엔진 색인 지원.
  • 보이는 콘텐츠와 메뉴 동기화.

핵심 포인트

  • useAnchorObserver 훅은 양방향 스크롤과 URL 동기화를 완전히 자동화합니다.
  • scrollRestoration 비활성화는 충돌을 피하는 데 필수적입니다.
  • 페이지 라우터의 catch-all 라우트는 SPA 스타일 네비게이션에 적합합니다.
  • shallow: true + scroll: false는 재렌더링을 최소화합니다.
  • 브라우저 기록과 SEO 지원이 기본으로 제공됩니다.

— Editorial Team

Advertisement 728x90

다음 읽기