Next.js에서의 라우팅

본 글은 Next.js 프레임워크에서 라우팅 시스템의 발전과 중요성을 살펴보고, 특히 App Router와 Pages Router의 근본적인 차이점을 분석한다. 또한 현대 웹 어플리케이션에서 사용되는 다양한 렌더링 전략과 라우팅 전략 간의 상관관계를 조사하여, Next.js의 새로운 App Router가 해결하고자 했던 기술적 도전과 근본적인 정신을 시사한다.

2025.04.19 | 조회 13 |
1
|

1. Next.js에서 라우팅이 나타난 배경

Next.js는 원래 React 애플리케이션의 서버사이드 렌더링(SSR)을 쉬운 방법으로 제공하기 위해 설계되었다. 순수한 React는 클라이언트 사이드 렌더링에 초점을 둘 라이브러리로, 상당한 크기의 자바스크립트 번들을 클라이언트로 전송해야 하고, 이는 초기 로딩 속도와 검색 엔진 최적화(SEO)에 불리한 영향을 미치는 경향이 있었다.

초기 Next.js는 파일 시스템 기반 라우팅(File-system based routing)을 도입함으로써 개발자들에게 직관적인 경로 구성 방식을 제공했다. 이는 pages/ 디렉토리를 통해 구현되었으며, 파일 경로가 곧 URL 경로로 매핑되는 단순한 방식이었다. 이러한 파일 기반 라우팅 시스템은 불필요한 비즈니스 로직을 줄이고, 리액트 경로의 산만한 구성을 편리하게 구조화하는 데 큰 역할을 했다.

그러나 웹 애플리케이션이 점점 복잡해지고 향상된 사용자 경험에 대한 요구가 늘어나면서, 레이아웃, 데이터 가져오기, 렌더링 전략 등에서 기존의 Pages Router는 일정한 한계를 보였다. 특히 React 생태계의 발전과 함께 React 18에서 도입된 Server Component와 같은 새로운 기능을 활용하기 위해서는 다른 접근법이 필요했다. 이러한 배경에서 Next.js 13에서는 App Router라는 새로운 라우팅 시스템을 도입하였고, 이는 더 발전된 파일 시스템 기반 라우팅을 제공하며 서버 컴포넌트, 보다 유연한 레이아웃 구성, 그리고 개선된 데이터 가져오기 기능을 포함하고 있다.

2. 라우팅이 해결하는 문제점

Next.js의 라우팅 시스템은 웹 애플리케이션 개발에서 발생하는 여러 문제점을 해결하기 위해 설계되었다. 먼저, 파일 시스템 기반 라우팅은 개발자들이 필요한 복잡한 라우트 구성을 직관적이고 관리하기 쉽게 만들어준다. 전통적인 클라이언트 사이드 라우팅에서는 종종 라우트 정의가 소스 코드 내에서 업데이트해야 하는 불편함이 있었다.

다음으로, Next.js의 라우팅 시스템은 서버 사이드 렌더링(SSR)과 정적 사이트 생성(SSG)을 자연스럽게 통합하여 패치 없이 구현할 수 있도록 해준다. 이는 각 페이지마다 적합한 렌더링 전략을 선택하여 성능과 사용자 경험을 최적화할 수 있도록 한다. Pages Router에서는 getServerSideProps, getStaticProps, getStaticPaths 등의 시스템을 통해 이를 구현했고, App Router에서는 강화된 데이터 인터페이스를 통해 더 단순하면서도 강력한 방식으로 제공하고 있다.

또한, Next.js의 App Router는 네스트된 레이아웃과 구성 패턴을 효과적으로 관리할 수 있는 기능을 제공한다. 이는 UI 구성 요소를 재사용하고 일관성 있는 사용자 경험을 제공하는 데 필수적인 문제를 해결한다. 기존의 Pages Router에서는 _app.js와 getLayout 패턴을 통해 일부 구현할 수 있었지만, App Router에서는 layout.js 파일을 통해 더 강력하고 자연스러운 방식으로 문제를 해결하고 있다.

마지막으로, App Router는 가장 현대적인 웹 애플리케이션에서 중요한 문제인 콘텍스트 공유와 동적 파라미터 처리를 효과적으로 해결해준다. 특히 서버 컴포넌트와 클라이언트 컴포넌트의 분리를 통해 데이터 가져오기와 상태 관리를 분리하면서 보다 효율적인 데이터 흐름과 사용자 상호작용을 구현할 수 있도록 해준다. 이로 인해 개발자들이 보다 큰 애플리케이션을 만들어 나가는 과정에서 발생할 수 있는 복잡성을 효과적으로 관리할 수 있게 되었다.

3. App Router와 Pages Router의 근본적인 차이점

Next.js의 App Router와 Pages Router는 표면적으로는 동일한 파일 시스템 기반 라우팅 기능을 제공하지만, 근본적인 아키텍처와 기술적 접근법에서 많은 차이를 보인다. 가장 피상적인 차이점은 기본 렌더링 패러다임에 있다. Pages Router는 기본적으로 모든 컴포넌트를 클라이언트 컴포넌트로 취급하며, getServerSideProps나 getStaticProps와 같은 함수를 통해 서버 사이드 로직을 추가하는 방식을 취한다.

반면 App Router는 React 18에서 도입된 서버 컴포넌트(Server Component)를 기본으로 채택하여 모든 컴포넌트가 기본적으로 서버에서 렌더링되는 방식을 취한다. 필요한 경우에만 'use client' 디렉티브를 통해 클라이언트 컴포넌트로 지정하여 클라이언트 사이드 기능이 필요한 컴포넌트를 만들 수 있다. 이는 기본적인 철학에서 큰 차이를 보여주는데, 서버 중심의 사고방식으로 전환하며 개발자들에게 보다 예측 가능한 패턴을 제공한다. (use server 디렉티브를 이용한 Server Component에 대한 이해는 리액트 18v의 RSC에 대해 깊게 공부할 필요가 있다)

더불어 데이터 가져오기 방식에서도 중요한 차이가 있다. Pages Router에서는 getServerSideProps, getStaticProps, getStaticPaths와 같은 전용 함수를 통해 데이터를 가져와야 했다. 반면 App Router에서는 더 직관적이고 자연스러운 데이터 가져오기 매커니즘을 제공한다. 서버 컴포넌트 내부에서 비동기 함수로 직접 데이터를 가져오고, fetch API에 캠싱 옵션을 패스하여 정적 또는 동적 렌더링을 선택할 수 있다.

또 다른 근본적인 차이는 레이아웃 구성에서 발견된다. Pages Router에서는 _app.js와 _document.js 파일을 통해 글로벌 레이아웃을 정의하고, 페이지별 레이아웃을 위해서는 getLayout 패턴과 같은 추가적인 비표준 패턴이 필요했다. 반면 App Router에서는 layout.js 파일을 통해 레이아웃을 효율적으로 구성할 수 있고, 네스트된 파일 구조로 바로 네스트된 레이아웃을 구성할 수 있다. 이는 파일 시스템 구조와 컴포넌트 구조 간의 직관성을 크게 향상시켰다.

마지막으로, 에러 처리와 로딩 상태 관리에서도 차이를 보인다. Pages Router에서는 구체적인 에러 핸들링을 위해 _error.js 파일을 사용했지만, App Router는 더 세분화된 error.js 파일을 각 디렉토리에 두어 레이아웃 수준에서 에러 범위를 한정할 수 있다. 마찬가지로 로딩 상태에 대해서도 loading.js 파일을 통해 React Suspense에 기반한 스트리밍과 서스펜스 기능을 보다 쉽게 사용할 수 있도록 하였다. 이러한 문제들은 App Router의 특수 파일 규약(special file conventions)을 통해 원활히 해결되어 보다 물 흐르듯 자연스러운 패턴으로 구현할 수 있게 되었다.

4. 현대 웹 어플리케이션에서 사용되는 렌더링 전략과 라우팅 전략과의 상관관계

현대 웹 어플리케이션 개발에서 렌더링 전략과 라우팅 전략은 밀접하게 연관되어 있다. Next.js의 App Router는 이러한 관계를 더욱 명확하고 유연하게 정의할 수 있도록 설계되었다. 렌더링 전략은 크게 정적 렌더링(Static Rendering), 동적 렌더링(Dynamic Rendering), 그리고 스트리밍(Streaming)으로 구분할 수 있다.

정적 렌더링은 빌드 타임이나 데이터 재검증 후에 페이지를 렌더링하고 그 결과를 캐싱하여 재사용한다. 이는 데이터가 자주 변경되지 않고 모든 사용자에게 동일한 콘텐츠를 제공하는 페이지에 적합하다. 동적 렌더링은 각 사용자의 요청시에 페이지를 렌더링하며, 개인화된 데이터나 사용자별 콘텍스트에 맞춘 콘텐츠가 필요한 경우에 사용된다. 스트리밍은 렌더링 작업을 작은 단위로 분할하여 순차적으로 사용자에게 전달하는 기술로, 페이지의 일부를 먼저 보여주면서 나머지를 계속 처리할 수 있도록 해준다.

Next.js의 App Router는 이러한 렌더링 전략을 라우팅 시스템과 더 긴밀하게 통합하였다. 특수 파일 규약과 함께 데이터 가져오기 옵션을 통해 각 라우트 세그먼트나 페이지에 맞는 렌더링 전략을 쉽게 지정할 수 있다. 또한, React Suspense와 통합된 로딩 UI를 지원하여 스트리밍 렌더링을 보다 원활하게 구현할 수 있도록 도와준다.

전통적인 웹 어플리케이션 렌더링 전략은 크게 서버 사이드 렌더링(SSR), 정적 사이트 생성(SSG), 그리고 증분적 정적 재생성(ISR)으로 구분할 수 있다. SSR은 각 사용자 요청시 서버에서 페이지를 렌더링하여 HTML을 생성하는 방식으로, 항상 최신 데이터를 포함하지만 서버 부하가 높은 단점이 있다. SSG는 빌드 타임에 정적 HTML을 미리 생성하여 최적의 성능을 제공하지만, 데이터가 변경되면 새로운 빌드가 필요한 제한점이 있었다. ISR은 이러한 두 전략의 장점을 결합한 접근법으로, 정적 페이지를 생성하면서도 지정된 시간 후에 배경에서 다시 생성하여 데이터를 업데이트한다.

Next.js의 Pages Router에서는 이러한 렌더링 전략을 getServerSideProps, getStaticProps, 그리고 getStaticProps와 revalidate 옵션을 통해 구현했다. 또한 Page Router를 사용하여 서버가 필요없는 정적 내보내기를 사용할 수 있다.

https://nextjs.org/docs/pages/building-your-application/deploying/static-exports

반면 App Router에서는 더 자연스러운 방식으로 접근한다. 기본적으로 개발자는 fetch API에 캐싱 옵션을 지정하여 렌더링 전략을 제어할 수 있다. 'force-cache' 옵션은 SSG와 유사한 정적 렌더링을, 'no-store' 옵션은 SSR과 유사한 동적 렌더링을, 그리고 'next: { revalidate: seconds }' 옵션은 ISR과 유사한 증분적 정적 렌더링을 구현한다.

fetch(url, { next: { revalidate: false } }) // SSG (Static Site Generation)
fetch(url, { next: { revalidate: 10 } }) // ISR (Incremental Static Regeneration)
fetch(url, { cache: 'no-store' }) // SSR (Server Side Rendering)

또한, App Router의 강점 중 하나는 각 라우트 세그먼트나 에 따라 다른 렌더링 전략을 사용할 수 있다는 점이다. 예를 들어, 동일한 어플리케이션 내에서 블로그 페이지는 정적 렌더링을 사용하고, 대시보드 페이지는 동적 렌더링을 사용하고, 각 페이지 내의 다양한 구성 요소는 서로 다른 렌더링 전략을 활용할 수 있다. 이는 성능과 새로움, 그리고 사용자 경험 간의 최적의 균형을 이루는 데 큰 도움을 준다.

최근에는 Next.js 15에서 소개된 부분 정적 사이트 생성(Partial Prerendering, PPR)이 라우팅과 렌더링 간의 더 긴밀한 통합을 보여준다. PPR은 동일한 페이지 내에서 정적 부분과 동적 부분을 혼합하여 사용할 수 있도록 해주는 기술이다. 이를 통해 페이지의 정적인 부분은 미리 렌더링하여 빠르게 서비스하고, 동적인 부분은 스트리밍을 통해 다양한 데이터를 가져오면서도 사용자 경험을 향상시킬 수 있다.

종합하면, 렌더링 전략과 라우팅 전략의 경계는 현대 웹 개발에서 점점 불분명해지고 있다. App Router는 서버 컴포넌트와 클라이언트 컴포넌트를 자연스럽게 통합하고, 다양한 렌더링 전략을 다루는 보다 유연한 모델을 제공하여 복잡한 웹 애플리케이션을 개발하는 과정을 단순화하면서도 성능과 사용자 경험을 최적화할 수 있도록 해준다.

결론

본 글에서는 Next.js의 라우팅 시스템의 발전과 기술적 차이점을 살펴보았다. Pages Router에서 App Router로의 전환은 단순한 기능적 개선이 아닌, 근본적인 프레임워크 사고방식의 전환을 나타낸다. 이는 React의 최신 기능을 활용하면서 서버 컴포넌트와 클라이언트 컴포넌트 간의 항상 유리한 경계를 제공하는 새로운 응용 프로그램 아키텍처로 이어지는 현대 웹 애플리케이션 패러다임을 고려한 시대에 맞는 접근법이다.

App Router의 도입은 단순히 기존 시스템의 변경이 아닌, 웹 개발 패러다임의 전환을 의미한다. 서버 컴포넌트를 기본으로 하는 방식으로 서버와 클라이언트 간의 상호작용을 다시 정의하고, 레이아웃 구조와 데이터 흐름의 자연스러움을 강조하며, 스트리밍과 그러뉴러 캐싱을 통한 사용자 경험의 향상을 촉진한다. 이러한 변화는 현대 웹 개발이 직면하는 도전과 그 해결책을 제시하며, 미래의 웹 개발 경향을 가늘하게 해준다.결론적으로, Next.js의 App Router는 현대 웹 개발의 중요한 도구로 자리매김하고 있으며, 성능, 개발자 경험, 그리고 사용자 경험 사이의 최적의 균형을 이루는 결정적인 역할을 담당한다. 처음에는 다소 복잡해 보일 수 있는 역설계 착안이지만, 실제로는 더 자연스럽고 편리한 방식을 제공함으로써 개발자들이 원하는 외부적 API와 내부적 구조 사이의 잠재적 관계를 개선하고 있다. 이는 개발자들이 더 호환성 있고 확장 가능한 애플리케이션을 만들 수 있도록 도와준다.

참고문헌

  1. Next.js 공식 문서. (2024). "Introduction".
  2. Next.js 공식 문서. (2024). "Routing Fundamentals".
  3. Next.js 공식 문서. (2024). "Rendering Fundamentals".
  4. Next.js 공식 문서. (2024). "Server Components".
  5. Next.js 공식 문서. (2024). "Client Components".
  6. Next.js 공식 문서. (2024). "Migrating from Pages to App Router".
  7. React 공식 문서. (2024). "React Server Components".
  8. Vercel. (2023). "Next.js 13 introduces App Router".
  9. Vercel. (2024). "Introducing Next.js 15".
  10. Dodds, K. (2023). "Understanding React Server Components".

다가올 뉴스레터가 궁금하신가요?

지금 구독해서 새로운 레터를 받아보세요

✉️

이번 뉴스레터 어떠셨나요?

Next.js 딥다이브 님에게 ☕️ 커피와 ✉️ 쪽지를 보내보세요!

댓글 1개

의견을 남겨주세요

확인
  • 마위의 프로필 이미지

    마위

    1
    1년 이상 전

    정리가 잘 되네요👍

    ㄴ 답글

다른 뉴스레터

© 2026 Next.js 딥다이브

next.js학습을 공유합니다.

메일리 로고

도움말 오류 및 기능 관련 제보

서비스 이용 문의admin@team.maily.so 채팅으로 문의하기

메일리 사업자 정보

메일리 (대표자: 이한결) | 대표번호: 070-8027-1409 | 사업자번호: 717-47-00705 | 서울특별시 송파구 위례광장로 199, 5층 501-2-31호

이용약관 | 개인정보처리방침 | 정기결제 이용약관 | 라이선스