← 목록으로

챕터 23: 네비게이션 디자인과 UX

서론 훌륭한 네비게이션은 단순히 링크의 모음이 아닙니다. 사용자가 웹사이트를 탐색하는 여정을 안내하는 지도와 같습니다. 사용자가 현재 어디에 있는지, 어디로 갈 수 있는지, 어떻게 돌아갈 수 있는지를 명확하게 알려주어야 합니다.

이번 챕터에서는 네비게이션의 다양한 패턴과 UX 원칙을 적용하여 더 나은 사용자 경험을 제공하는 방법을 배워보겠습니다. 브레드크럼, 사이드바, 탭 네비게이션, 그리고 고급 인터랙션까지 실제 프로젝트에서 활용할 수 있는 실용적인 예제들을 만들어보겠습니다.

본론 브레드크럼 네비게이션 브레드크럼은 사용자가 웹사이트의 계층 구조에서 현재 위치를 파악할 수 있도록 도와줍니다:

jsx 'use client'

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

export default function BreadcrumbNavigation() { const pathname = usePathname()

// 경로를 분석하여 브레드크럼 생성 const generateBreadcrumbs = () => { const paths = pathname.split('/').filter(Boolean) const breadcrumbs = [{ name: '홈', href: '/' }]

paths.forEach((path, index) => {
  const href = `/${paths.slice(0, index + 1).join('/')}`
  // 경로명을 사용자 친화적으로 변환
  const name = path
    .split('-')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ')
  
  breadcrumbs.push({ name, href })
})

return breadcrumbs

}

const breadcrumbs = generateBreadcrumbs()

return (

{/* 브레드크럼 스타일 1: 기본 */}

  {/* 브레드크럼 스타일 2: 배경색 있는 스타일 */}
  <div className="container mx-auto px-4 py-8">
    <nav className="bg-gray-100 rounded-lg px-4 py-2 mb-8">
      <ol className="flex items-center space-x-1 text-sm">
        {breadcrumbs.map((item, index) => (
          <li key={item.href} className="flex items-center">
            {index > 0 && <span className="mx-2 text-gray-400">/</span>}
            {index === breadcrumbs.length - 1 ? (
              <span className="text-gray-700 font-medium">{item.name}</span>
            ) : (
              <Link href={item.href} className="text-gray-600 hover:text-gray-900 transition">
                {item.name}
              </Link>
            )}
          </li>
        ))}
      </ol>
    </nav>
    
    {/* 브레드크럼 스타일 3: 아이콘 포함 */}
    <nav className="mb-8">
      <ol className="flex items-center space-x-2">
        {breadcrumbs.map((item, index) => (
          <li key={item.href} className="flex items-center">
            {index === 0 && (
              <Link href={item.href} className="text-gray-600 hover:text-blue-600 transition">
                <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                  <path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z" />
                </svg>
              </Link>
            )}
            {index > 0 && (
              <>
                <svg className="w-5 h-5 mx-1 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
                  <path fillRule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" />
                </svg>
                {index === breadcrumbs.length - 1 ? (
                  <span className="text-gray-700 font-medium">{item.name}</span>
                ) : (
                  <Link href={item.href} className="text-gray-600 hover:text-blue-600 transition">
                    {item.name}
                  </Link>
                )}
              </>
            )}
          </li>
        ))}
      </ol>
    </nav>
  </div>
</div>

) } 사이드바 네비게이션 복잡한 콘텐츠 구조를 가진 웹사이트에 적합한 사이드바 네비게이션입니다:

jsx 'use client'

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

export default function SidebarNavigation() { const pathname = usePathname() const [expandedSections, setExpandedSections] = useState(['getting-started'])

const navigation = [ { id: 'getting-started', title: '시작하기', icon: '🚀', items: [ { name: '소개', href: '/docs/introduction' }, { name: '설치', href: '/docs/installation' }, { name: '빠른 시작', href: '/docs/quick-start' } ] }, { id: 'guides', title: '가이드', icon: '📚', items: [ { name: '라우팅', href: '/docs/routing' }, { name: '데이터 페칭', href: '/docs/data-fetching' }, { name: '스타일링', href: '/docs/styling' }, { name: '배포', href: '/docs/deployment' } ] }, { id: 'api', title: 'API 참조', icon: '⚙️', items: [ { name: 'Components', href: '/docs/components' }, { name: 'Hooks', href: '/docs/hooks' }, { name: 'Utils', href: '/docs/utils' } ] }, { id: 'examples', title: '예제', icon: '💡', items: [ { name: '블로그', href: '/docs/examples/blog' }, { name: '이커머스', href: '/docs/examples/ecommerce' }, { name: '대시보드', href: '/docs/examples/dashboard' } ] } ]

const toggleSection = (sectionId) => { setExpandedSections(prev => prev.includes(sectionId) ? prev.filter(id => id !== sectionId) : [...prev, sectionId] ) }

return (

{/* 사이드바 */}