[Next.js]App라우팅

전유덕·2024년 8월 18일
0
post-thumbnail

개요

Next.js 13부터 도입된 App Router는 애플리케이션의 구조와 흐름을 유연하게 관리할 수 있는 도구입니다. 이 기능을 활용하면 복잡한 페이지 간의 레이아웃을 손쉽게 구성하고, 사용자 경험을 극대화할 수 있습니다. 이번 포스팅에서는 App Router의 다양한 레이아웃 패턴을 새로운 예제 코드를 통해 설명하겠습니다.

전반적인 레이아웃 설계

기본 레이아웃은 애플리케이션의 모든 페이지에 적용되는 기본적인 프레임워크입니다. 이를 통해 전체 애플리케이션에서 일관된 스타일과 구조를 유지할 수 있습니다. 이 레이아웃에서는 주로 공통적인 UI 요소를 정의하고, 각 페이지에서 고유한 콘텐츠를 전달받아 보여줍니다.

// app/layout.js
export default function BaseLayout({ children }) {
  return (
    <html lang="ko">
      <head>
        <meta charSet="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>My Next.js App</title>
      </head>
      <body>
        <header>
          <div className="header-container">공통 헤더</div>
        </header>
        <main className="content">{children}</main>
        <footer>
          <div className="footer-container">공통 푸터</div>
        </footer>
      </body>
    </html>
  );
}

이 기본 레이아웃 구조에서는 head 태그를 통해 문서의 메타 데이터를 정의하고, 전역적으로 사용할 헤더와 푸터를 설정합니다. 이로 인해 각 페이지가 고유의 콘텐츠를 가질 수 있으면서도 전체 애플리케이션의 스타일이 일관되게 유지됩니다.

섹션별 맞춤형 레이아웃

특정 페이지나 섹션에 맞춤형 레이아웃을 적용하여 각 섹션의 특성을 반영한 디자인을 구성할 수 있습니다. 이 방법은 사용자가 섹션별로 구분된 경험을 할 수 있게 하며, 특히 복잡한 애플리케이션에서 중요한 역할을 합니다.

// app/profile/layout.js
export default function ProfileLayout({ children }) {
  return (
    <div className="profile-container">
      <aside className="profile-sidebar">
        <nav>
          <ul>
            <li><a href="/profile">프로필 보기</a></li>
            <li><a href="/profile/edit">프로필 수정</a></li>
            <li><a href="/profile/settings">설정</a></li>
          </ul>
        </nav>
      </aside>
      <section className="profile-content">{children}</section>
    </div>
  );
}

이 ProfileLayout에서는 프로필 메뉴를 사이드바에 배치하여 사용자가 쉽게 탐색할 수 있도록 했습니다. 각 메뉴 항목은 해당하는 프로필 관련 페이지로 연결되며, 메인 콘텐츠 영역에서는 사용자가 선택한 콘텐츠가 표시됩니다. 이 구조는 특히 사용자 중심의 네비게이션을 구현할 때 유용합니다.

라우트 그룹화 및 관리

/app
  ├── (account)
  │   ├── layout.js
  │   └── settings/page.js
  └── (store)
      ├── layout.js
      └── products/page.js

위 구조에서는 account와 store 같은 라우트 그룹을 사용하여 서로 다른 기능을 제공하는 페이지를 독립적으로 구성할 수 있습니다. 이러한 그룹화는 프로젝트의 규모가 커질수록 코드베이스를 체계적으로 관리하는 데 큰 도움이 됩니다. 특히, 각 그룹이 고유한 레이아웃을 가질 때 그룹화가 더 유용합니다

특정 용도의 전용 레이아웃

특정 경로나 페이지에 대해 맞춤형 레이아웃을 제공하는 방법입니다. 전용 레이아웃은 주로 특정 기능에 맞춘 UI/UX를 제공해야 할 때 사용됩니다.

// app/account/layout.js
export default function AccountLayout({ children }) {
  return (
    <div className="account-layout">
      <header className="account-header">
        <h1>계정 관리</h1>
        <p>여기서 계정 정보를 관리하세요.</p>
      </header>
      <main>{children}</main>
      <footer className="account-footer">
        <p>계정 관련 도움말이 필요하시면 여기를 클릭하세요.</p>
      </footer>
    </div>
  );
}

AccountLayout은 계정 관리에 특화된 레이아웃으로, 계정 정보와 관련된 활동을 집중적으로 다루는 페이지에 적합합니다. 이 레이아웃은 사용자에게 친숙한 인터페이스를 제공하며, 계정과 관련된 모든 기능이 이 레이아웃 내에서 이루어집니다.

조건부 라우팅 및 리디렉션

사용자가 특정 조건을 만족하지 못했을 때 다른 페이지로 리다이렉트하거나, 조건에 따라 다른 콘텐츠를 렌더링하는 방법입니다. 이를 통해 사용자에게 동적인 경험을 제공할 수 있습니다.

// app/home/page.js
import { useRouter } from 'next/router';
import { useEffect } from 'react';

export default function HomePage() {
  const router = useRouter();
  const isLoggedIn = false; // 실제 로그인 여부를 확인하는 로직

  useEffect(() => {
    if (!isLoggedIn) {
      router.push('/signin');
    }
  }, [isLoggedIn, router]);

  return (
    <div>
      <h1>환영합니다, 사용자님!</h1>
      {isLoggedIn ? (
        <p>계속해서 사이트를 이용하세요.</p>
      ) : (
        <p>로그인 중입니다...</p>
      )}
    </div>
  );
}

이 코드에서는 로그인 여부를 확인한 후 사용자를 로그인 페이지로 리다이렉트합니다. 리다이렉트 전에 사용자에게 로딩 상태를 표시하거나, 로딩 중 메시지를 표시하는 방식으로 더 나은 사용자 경험을 제공할 수 있습니다.

동적 경로와 데이터

동적 경로는 URL의 매개변수를 사용하여 다양한 페이지를 생성하고, 해당 페이지에 맞는 데이터를 불러와 표시하는 기능을 제공합니다. 이는 Next.js에서 매우 유용한 기능 중 하나입니다.

// app/blog/[slug]/page.js
export async function getStaticPaths() {
  const res = await fetch('https://api.example.com/posts');
  const posts = await res.json();

  const paths = posts.map((post) => ({
    params: { slug: post.slug },
  }));

  return { paths, fallback: false };
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://api.example.com/posts/${params.slug}`);
  const post = await res.json();

  return { props: { post } };
}

export default function BlogPost({ post }) {
  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </article>
  );
}

이 예제에서는 동적 경로를 사용하여 블로그 포스트 페이지를 생성합니다. getStaticPaths 함수는 가능한 모든 경로를 미리 생성하여 빌드 시간에 페이지를 생성하고, getStaticProps 함수는 각 경로에 맞는 데이터를 API로부터 가져와 렌더링합니다. 이 구조는 콘텐츠가 자주 변경되지 않는 페이지에 최적화되어 있으며, 페이지 로드 시간을 크게 줄일 수 있습니다.

마무리

Next.js를 파이널 프로젝트에서 사용하면서 가장 두드러진 차이점 중 하나는 바로 라우팅 패턴이었습니다. React의 라우팅 방식에 익숙했던 저는 Next.js의 폴더 구조를 기반으로 하는 라우팅 시스템이 처음에는 다소 직관적이지 않게 느껴졌습니다. React에서는 react-router와 같은 라이브러리를 사용해 명시적으로 라우트를 설정하는 반면, Next.js에서는 파일과 폴더 구조만으로도 라우트를 정의할 수 있습니다.

이 차이로 인해 처음에는 혼란스러웠지만, Next.js의 라우팅 방식에 점점 익숙해지면서 그 효율성과 편리함을 깨닫게 되었습니다. 특히, 특정 경로에 대응하는 파일을 생성하면 자동으로 해당 경로로 연결된 페이지가 설정되는 방식은 라우트를 간편하게 관리할 수 있게 해줍니다. 또한, 동적 경로나 API 라우팅과 같은 기능이 폴더 구조를 통해 자연스럽게 연계되므로, 프로젝트의 규모가 커질수록 그 진가를 발휘합니다.

결국, Next.js의 라우팅 시스템은 처음에는 다소 낯설게 느껴질 수 있지만, 한번 익숙해지면 개발 생산성을 크게 향상시키는 도구임을 알게 되었습니다. Next.js의 라우팅 방식이 React보다 더 구조적이고 강력하다고 느끼는 이유는, 폴더 구조만으로도 애플리케이션의 전체 흐름을 한눈에 파악할 수 있기 때문입니다. 이러한 장점은 유지보수성과 협업 효율성을 높이는 데 크게 기여합니다. 이제는 Next.js의 라우팅 방식이 React의 방식보다 더 직관적이고 강력하다는 생각을 하고 있습니다.

profile
zi존 개발자 되고싶다ㅏㅏ(훈수 대환영!)

0개의 댓글