이번 포스트에서는 Next.js에서 URL Parameter
를 사용하여 동적 경로 페이지를 만드는 방법에 대해 알아보고자한다. 예를 들어, 상품 상세 페이지를 구현할 때, /product/1
, /product/2
와 같은 가변적인 값(상품 ID)을 포함한 URL을 처리할 수 있는 동적 페이지를 생성하는 방법을 다룬다.
URL Parameter는 URL 경로에 포함된 가변적인 값을 의미한다. 예를 들어, /product/1
에서 1
은 상품의 ID를 나타내며, 이 값은 동적 경로에 의해 처리된다. Next.js에서는 이러한 동적 경로를 쉽게 설정할 수 있으며, 가변적인 값을 기반으로 페이지를 렌더링할 수 있다.
product
폴더를 만들어준 다음에, 해당 폴더 안에 대괄호로 [id].tsx
라는 이름으로 파일을 만들어줘 경로를 정의한다. 그럼 Next.js는 id
라는 값이 가변적인 경로(/product/1
, /product/2
등)를 처리하는 페이지로 인식한다.다음과 같이 pages/product/[id].tsx
파일을 생성.
import { useRouter } from 'next/router';
export default function ProductPage() {
const router = useRouter();
const { id } = router.query; // URL Parameter인 id 값을 가져옴
return <h1>Product {id}</h1>;
}
이렇게 설정해 주면, Next가 이 파일은 지금 /product/[id]
라는 가변적인 값 즉, URL Parameter
를 갖는 동적 경로에 대응하는 파일이구나 라고 인식을 해서 이 경로상에 URL Parameter
인 id
값이 뭐가 되던 파일에 작성된 컴포넌트를 페이지로서 화면에 렌더링 시키도록 설정이 된다.
이렇게 query프로터피테 id의 값으로 파라미터가 저장된 이유는 pages폴더 아래에 이 page에 대응할 파일 이름을 정할 때 [id].tsx
라는 이름으로 만들어 주었기 때문. 그래서 ~product/1
라는 이런 경로에 이 1
이라는 값이 query프로퍼티 안에 id
라는 이름으로 대응이 되어서 저장이 되었다.
그래서 이 코드는 /product/1
경로로 접속하면 Product 1
, /product/2
로 접속하면 Product 2
라는 식으로 해당 ID 값을 출력해준다. useRouter
훅을 사용해 router.query
에서 id
값을 가져와 화면에 렌더링해 준다.
경로에 여러 개의 ID가 포함된 동적 경로를 처리해야 하는 경우도 있다. 예를 들어, /product/1/13/25
와 같이 ID가 여러 개 들어올 때를 위한 설정. 이때는 대괄호에 점 3개(...)를 사용하여 경로를 설정할 수 있다.
pages/product/[...id].tsx
파일을 생성하여, 여러 개의 경로 구간을 처리할 수 있다.
Catch All Segment
라고 부른다 Segment
는 구간
이라는 뜻.import { useRouter } from 'next/router';
export default function ProductPage() {
const router = useRouter();
const { id } = router.query; // 배열 형태로 여러 ID 값을 가져옴
return <h1>Product IDs: {id?.join(', ')}</h1>;
}
경로상에 이런/
슬래시로 구분되는 이런 하나하나의 구간을 뜻함. 그래서 모든 구간에 다 대응하는 페이지를 만들겠다라는 의미.
이제 이 여러개의 id 값은 query프로퍼티의 id에 배열
형태로 저장이 됨. ex : ['1','13','25','121']
그래서 이 코드는 /product/1/13/25
와 같이 여러 개의 ID 값을 배열로 받아 화면에 출력함. 예를 들어, Product IDs: 1, 13, 25라고 렌더링된다.
만약 경로 뒤에 ID가 없더라도 대응하는 범용적인 페이지를 만들고 싶다면, 대괄호를 두 번 감싸 Optional Catch All Segment로 설정할 수 있다. 파일명을 [[...id]].tsx로 변경하면, /product
경로처럼 ID가 생략된 URL에도 대응할 수 있다.
import { useRouter } from 'next/router';
export default function ProductPage() {
const router = useRouter();
const { id } = router.query;
return <h1>{id ? `Product IDs: ${id.join(', ')}` : 'All Products'}</h1>;
}
이 코드는 /product
경로로 접속하면 All Products
를 출력하고, /product/1/13
등 경로에 ID가 있으면 해당 값을 출력한다.
존재하지 않는 경로로 접속했을 때 표시될 404 페이지도 쉽게 설정할 수 있다. 이를 위해 404.tsx
파일을 pages
폴더에 추가하면 된다.
export default function NotFoundPage() {
return <div>존재하지 않는 페이지입니다.</div>;
}
이렇게 설정하면, 사용자가 존재하지 않는 페이지에 접속했을 때 "존재하지 않는 페이지입니다."라는 메시지가 출력된다.
Query String | URL Parameter | |
---|---|---|
위치 | URL의 끝에 `?`로 시작하여 `key=value` 형식으로 추가됨 | URL 경로의 일부로 가변적인 값을 포함 |
형식 | `?key=value&key2=value2` | `/resource/123` |
사용 예시 | `localhost:3000/search?q=사과&category=fruit` | `localhost:3000/product/123` |
주 용도 | 검색, 필터, 페이지네이션 등 추가적인 정보 전달 | 리소스 식별, 특정 페이지 이동 등 경로에 따라 페이지 결정 |
경로에 대한 영향 | 경로에는 영향을 미치지 않음 | 경로의 일부로 페이지 자체를 결정 |
다중 값 전달 | `&`로 구분하여 여러 개의 값을 전달 가능 | 경로 구분자로 `/` 사용, 경로에 여러 값 포함 가능 |