모든 애플리케이션의 기본 구조는 Routing
이다. 이 페이지에서는 웹 라우팅의 기본 개념과 Next.js에서 라우팅을 처리하는 방법을 소개한다.
용어
아래와 같이 문서 전체에서 사용되는 용어들을 볼 수 있다.
Tree
:계층 구조를 시각화하는 데 사용되는 관례. 예를 들어, 부모 및 자식 컴포넌트를 가진 컴포넌트 트리, 폴더 구조 등이 있다.Subtree
: 새로운 루트(첫 번째)에서 시작하여 잎(마지막)에서 끝나는 트리의 일부분이다.Root
: 트리나 서브트리에서 첫 번째 노드로, 루트 레이아웃과 같은 것이다.Leaf
: 자식이 없는 서브트리의 노드로, 예를 들어 URL 경로의 마지막 세그먼트와 같다.URL Segment
: 슬래시로 구분된 URL 경로의 일부분이다.URL Path
: 도메인 이후에 오는 URL의 일부분으로, 세그먼트로 구성된다.app 디렉토리
버전 13에서 Next.js는 공유 레이아웃
, 중첩 라우팅
, 로딩 상태
, 에러 핸들링
등을 지원하는 React Server Components를 기반으로한 새로운 App Router를 소개했다.
App Router
는 새로운 app
디렉토리에서 작동한다. 이 app
디렉토리는 기존의 pages
디렉토리와 함께 작동하여 점진적인 적용을 가능하게 한다. 이를 통해 애플리케이션의 일부 라우트를 새로운 동작으로 전환하면서 이전 동작을 유지하는 동시에 다른 라우트를 pages
디렉토리에 유지할 수 있다.
App Router는 Pages Router보다 우선한다.
디렉토리 간의 라우트는 동일한 URL 경로를 해결해서는 안 되며, 이는 충돌을 방지하기 위해 build-time 에러를 일으킨다.
기본적으로 app 내부의 컴포넌트는 React Server Components
이다. 이는 성능 최적화를 위한 것으로, 쉽게 적용할 수 있도록 해주며, Client Components
도 사용할 수 있다.
App Router에서의 폴더와 파일의 역할
1. 폴더
라우트를 정의하는 데 사용된다. 라우트는 루트 폴더에서 마지막 leaf 폴더까지의 계층 구조를 따르는 중첩된 폴더의 단일 경로이다. 마지막 leaf 폴더에는 page.js
파일이 포함된다.
2. 파일
Route Segments
에 표시되는 UI를 만드는 데 사용된다.
Route Segments
라우트의 각 폴더는 라우트 세그먼트를 나타낸다. 각 라우트 세그먼트는 URL 경로의 해당 세그먼트와 매핑
된다.
Nested Routes
중첩된 라우트를 만들려면, 서로 중첩된 폴더를 추가
하면 된다.
예를 들어, app 디렉토리 내에 두 개의 새 폴더를 중첩함으로써 새로운 /dashboard/settings
라우트를 추가할 수 있다.
/dashboard/settings 라우트는 세 개의 세그먼트로 구성된다.
/ (루트 세그먼트)
dashboard (세그먼트)
settings (리프 세그먼트)
File Conventions ( 파일 규칙 )
Next.js는 중첩된 라우트에서 특정 동작을 가진 UI를 생성하기 위해 일련의 특수 파일을 제공한다.
pages.js
라우트의 고유한 UI를 생성하고 경로를 공개적으로 접근 가능하게 만든다.route.js
라우트의 서버 측 API 엔드포인트를 생성한다.layout.js
세그먼트와 해당 하위 요소들에 대한 공유 UI를 생성한다. 레이아웃은 페이지 또는 하위 세그먼트를 감싸는 역할을 한다.template.js
layout.js와 유사하지만, 네비게이션 시 새로운 컴포넌트 인스턴스가 마운트된다. 이 동작이 필요하지 않은 경우 layout을 사용한다.loading.js
세그먼트와 해당 하위 요소들에 대한 로딩 UI를 생성한다. loading.js는 페이지 또는 하위 세그먼트를 React Suspense 경계로 감싸며, 로딩 UI를 표시한다.error.js
세그먼트와 해당 하위 요소들에 대한 오류 UI를 생성한다. error.js는 페이지 또는 하위 세그먼트를 React Error 경계로 감싸며, 오류 UI를 표시한다.global-error.js
error.js와 유사하지만, 루트 layout.js에서 오류를 캐치하기 위한 파일이다.not-found.js
라우트 세그먼트에서 notFound 함수가 throw되거나, 어떠한 라우트와도 일치하지 않는 URL이 있는 경우 표시할 UI를 생성한다.파일 확장자로 .js
, .jsx
또는 .tsx
를 사용할 수 있다.
컴포넌트 계층 구조
루트 세그먼트의 특수 파일에 정의된 React 컴포넌트는 특정 계층 구조에서 렌더링된다.
layout.js
template.js
error.js
(React error boundary)loading.js
(React suspense boundary)not-found.js
(React error boundary)page.js
또는 중첩된 layout.js
중첩된 라우트에서는 세그먼트의 컴포넌트가 해당 부모 세그먼트의 컴포넌트 안에 중첩
된다.
Colocation ( 공간 이용 )
특수 파일 외에도 스타일시트
, 테스트
, 컴포넌트
등을 포함한 사용자 정의 파일을 폴더 내에 공간 이용 할 수 있다.
서버 센트릭 라우팅과 클라이언트 사이드 네비게이션
page
디렉토리와는 달리, App Router는 서버 컴포넌트와 서버에서 데이터를 가져오기 위해 서버 센트릭 라우팅을 사용한다. 서버 센트릭 라우팅에서는 클라이언트가 라우트 맵을 다운로드할 필요가 없으며 서버 컴포넌트를 요청하는 동일한 요청을 사용하여 라우트를 찾을 수 있다. 이 최적화는 모든 애플리케이션에 유용하지만 많은 라우트가 있는 애플리케이션에서 더 큰 영향을 미친다.
라우팅이 서버 센트릭이지만 라우터는 Link Component
를 사용하여 클라이언트 사이드 네비게이션을 사용한다. 이는 싱글 페이지 애플리케이션의 동작과 유사하다. 따라서 사용자가 새로운 경로로 이동할 때 브라우저는 페이지를 다시 로드하지 않는다. 대신 URL이 업데이트되고 Next.js는 변경된 세그먼트만 렌더링한다.
또한 사용자가 앱에서 이동할 때, 라우터는 React Server Component 페이로드 결과를 인메모리 클라이언트 캐시에 저장한다. 캐시는 라우트 세그먼트별로 분할되어 어느 수준에서든 무효화할 수 있으며 React의 동시 렌더링에서 일관성을 보장한다. 이것은 특정 경우에 이전에 검색한 세그먼트의 캐시를 재사용할 수 있어 성능을 더욱 향상시킨다.
부분 렌더링
Next.js에서 형제 라우트(예: 아래 /dashboard/settings 및 /dashboard/analytics) 간 이동할 때, 변경되는 라우트의 레이아웃 및 페이지만 가져와 렌더링한다. 상위 서브트리의 세그먼트 이상은 다시 가져오거나 다시 렌더링하지 않는다. 따라서 레이아웃을 공유하는 라우트에서 사용자가 형제 페이지 간에 이동할 때 레이아웃이 유지된다.
부분 렌더링이 없는 경우 각 탐색마다 전체 페이지가 서버에서 다시 렌더링된다. 업데이트되는 세그먼트만 렌더링하는 것은 전송되는 데이터 양과 실행 시간을 줄여 성능을 향상시킨다.
Advanced Routing Patterns
App Router는 더 복잡한 라우팅 패턴을 구현하는 데 도움이 되는 일련의 규칙을 제공한다.
1. 병렬 라우트
독립적으로 탐색할 수 있는 두 개 이상의 페이지를 동시에 보여줄 수 있다. 자체 하위 탐색 기능이 있는 분할 보기에 사용할 수 있다. ex) 대시보드.
2. 인터셉트 라우트
라우트를 가로채서 다른 라우트의 컨텍스트에서 보여줄 수 있다. 현재 페이지의 컨텍스트를 유지하는 것이 중요한 경우에 사용할 수 있다. ex) 작업을 편집하는 동안 모든 작업을 볼 수 있도록 하거나 피드에서 사진을 확대하는 경우.