App Router 버전의 Next.js에서 페이지 라우팅 설정 방법을 정리하도록 할건데, 새로운 App Router를 사용하면 기존의 Page Router와 구조적 차이점이 있지만, 여전히 디렉토리 구조를 활용하여 라우팅을 설정할 수 있다.
Next.js의 Page Router
에서는 pages
폴더 아래 파일의 이름을 그대로 페이지 경로로 사용했다. 예를 들어, pages/index.tsx
는 루트 경로(/), pages/search.tsx
는 /search 경로를 담당했다. App Router
에서도 디렉토리 구조를 활용하여 라우팅을 설정하지만, 페이지 파일의 이름은 항상 page.tsx
로 고정된다.
예를 들어 /search
페이지를 생성하려면,
app/search/page.tsx
구조로 폴더와 파일을 생성한다.동적으로 경로에 URL 파라미터
가 포함되는 페이지도 유사한 방식으로 설정된다. /book/1
, /book/2
등의 경로를 설정하려면 app/book/[id]/page.tsx
구조를 만든다. 이때 [id]
폴더는 URL 파라미터
를 받는다는 것을 의미한다.
이렇듯이 App Router
버전의 Next앱에서도 app
폴더 밑에 구조를 기반으로 페이지 라우팅이 자동 설정 된다는 점은 Page Router
버전과 동일하지만, 대신에 App Router
에서는 page
라는 이름을 갖는 파일만 페이지 파일로서 설정이 된다.
app/search
폴더를 생성한 후, 해당 폴더 안에 page.tsx
파일을 생성한다. 아래는 Search 페이지
예제 코드이다.// src/app/search/page.tsx
export default function Page() {
return <div>Search 페이지</div>
}
이제 브라우저에서 localhost:3000/search
로 접속하면 위의 Search 페이지
가 렌더링된다.
App Router
에서는 query string
과 URL 파라미터
모두 페이지 컴포넌트의 props
를 통해 전달된다. query string
값은 searchParams
객체로 전달되며, searchParams
라는 값은 Promise
형태로 저장되어 있어 비동기로 꺼내와 사용할 수 있다.
가장 먼저 해줘야 할 일은, 페이지 라우팅을 설정하기 전에, 기본적으로 설정이 되어있는 템플릿 코드들을 먼저 제거를 해준다. 이렇게 해야만 앞으로 변경되는 사항들을 확실히 확인해 볼 수 있다. 그래서 가장 먼저 src
폴더 안에 app
폴더 안에 이 프로젝트의 전체 스타일을 담당하고 있는 global.css
파일에서 기본적으로 설정된 템플릿의 스타일을 전부 다 제거 해주고, 이어서 현재 index페이지의 스타일을 담당하고 있는 page.module.css
파일의 내용도 싹 다 제거해준다. 마지막으로는 현재 index페이지의 역할을 하는 page.tsx
파일에서 Home컴포넌트의 return문 내부의 최상위 div
태그만 남기고 전부 다 제거해 준다. 그런 다음에 불필요한 import문도 제거 해준다. 이렇게 까지 해줬다면 이제 실습 준비는 모두 완료가 된 상태이다.
// src/app/search/page.tsx
export default async function Page({
searchParams,
}: {searchParams:Promise<{q:string}>}) {
const {q} = await searchParams
return <div>Search 페이지 : {q}</div>
}
위 코드는 localhost:3000/search?q=사과
로 접근했을 때 Search 페이지 : 사과
라는 텍스트를 화면에 렌더링한다. searchParams
는 Promise
객체 형태로 전달되므로 await
으로 값을 받아오도록 설정한다.
이
async 함수 컴포넌트
는 React의 서버 컴포넌트이기 때문에async
키워드를 붙일 수 있다.서버 컴포넌트
의 경우에는, 서버에서 사전 렌더링을 위해서만 딱 한 번 실행이 된다. 그렇기 때문에 그때 비동기적으로 실행이 되어도 문제가 발생하지 않기 때문에 비동기 처리를 바로 사용할 수 있다.
이제 localhost:3000/search?q=사과
경로로 이동하면 Search 페이지 : 사과
로 querystring출력이 된다.
이제 /book/[id]
형식의 경로를 설정하고, 해당 경로에 포함된 URL 파라미터
값을 컴포넌트 내에서 활용해보자.
🔖 app/book/[id]
폴더를 생성하고, 그 안에 page.tsx
파일을 만들어 페이지 컴포넌트를 작성한다.
// src/app/book/[id]/page.tsx
페이지입니다.
export default function Page() {
return <div>book/[id] 페이지입니다.</div>
}
위의 코드를 작성하고 localhost:3000/book/1
에 접속하면 book/[id]
페이지입니다.가 화면에 출력된다. 이때 1
은 URL 파라미터
로 인식된다.
🔖 이제 URL 파라미터
로 전달되는 id
값을 페이지에서 사용할 수 있도록 수정해보자.
// src/app/book/[id]/page.tsx
export default async function Page({
params,
}: {params: Promise<{id:string}>}) {
const {id} = await params;
return <div>book/[id] 페이지 : {id}</div>
}
이 코드는 URL 파라미터
id
값을 비동기로 꺼내 화면에 렌더링한다. 예를 들어, localhost:3000/book/100
경로로 접근하면 book/[id] 페이지 : 100
이 출력된다. params
또한 Promise
객체이므로 await
으로 값을 가져와야 한다.
그럼 이제 /book/1
, /book/2
, ... , /bok/100
이런 식으로 /book 뒤에 URL Parameter
가 하나 포함되는 경로로 요청을 받게 되면 먼저 book이라는 경로에 따라서 book
폴더 밑을 탐색하게 될 거고, 그 뒤에 나오는 URL Parameter
값은 [id]
폴더에 대응이 되어서 결론적으로 /book/[id]
아래에 있는 page.tsx
파일의 컴포넌트가 페이지로써 화면에 렌더링 된다.
Next.js 13의 App Router
버전에서는 app 폴더 구조를 이용하여 페이지를 설정한다. 페이지의 이름은 항상 page.tsx
로 고정되며, 쿼리 문자열
이나 URL 파라미터
값은 props
로 전달되는 searchParams
와 params
를 통해 사용할 수 있다.
URL 파라미터
는 params
객체로,
query string
은 searchParams
객체로 받아와 비동기
로 사용 가능하며, 서버 컴포넌트
의 특성 덕분에 비동기 처리가 간편하게 적용된다.
App Router
는 기존 라우팅 방식과 유사하지만, 더 유연하게 서버 측에서 데이터를 받아와 사용할 수 있도록 설계되었다.