이 글에서 정리하는 내용
이 글에서는 제가 Next.js 프로젝트에서 next.config.js로 리다이렉트를 설정하는 방법을 정리합니다. 단순 주소 변경을 왜 설정 파일에서 처리하는지, redirects()를 기존 설정과 어떻게 합치는지, permanent 값이 307과 308 응답과 어떻게 연결되는지, 그리고 next.config.js 기준 리다이렉트와 다른 라우팅 기능은 무엇이 다른지까지 한 번에 이해할 수 있도록 구성했습니다.
리다이렉트가 필요한 상황

저는 Next.js에서 주소 구조를 바꾸거나 잘못 만든 경로를 교정해야 할 때, 먼저 리다이렉트가 필요한 상황인지부터 구분합니다. 예를 들어 예전 페이지 주소가 이미 외부에 공유되어 있거나, 검색엔진에 색인된 주소를 새 경로로 옮겨야 한다면 단순 링크 수정만으로는 부족합니다. 이때 들어온 요청을 새 주소로 이동시키는 리다이렉트가 필요합니다. 특히 운영 중인 서비스에서는 사용자가 오래된 URL로 접속해도 정상 페이지로 도착해야 하므로, 라우트 파일 안에서 임시로 처리하기보다 설정 레벨에서 일관되게 관리하는 편이 훨씬 안정적입니다.
언제 설정 파일 리다이렉트를 먼저 검토할까
// 대표적인 상황
// 1) 기존 주소를 새 주소로 변경해야 할 때
// 2) 오타가 포함된 잘못된 URL을 올바른 URL로 보정할 때
// 3) 이미 공개된 예전 링크를 계속 살려야 할 때
// 4) 미리 알고 있는 경로 목록을 한 번에 관리할 때
제가 실무에서 기준으로 잡는 핵심은 간단합니다. 미리 알고 있는 주소 변경이라면 next.config.js의 redirects()를 먼저 검토하고, 사용자 상태나 요청 조건에 따라 더 복잡하게 분기해야 한다면 다른 방식이 필요한지 살펴봅니다. 즉, 정적인 규칙은 설정 파일에, 동적인 분기는 코드나 다른 라우팅 수단에 두는 흐름이 관리하기 쉽습니다.
next.config.js에 추가하는 방법
제가 가장 많이 사용하는 방식은 기존 nextConfig 객체 안에 async redirects()를 추가하는 구조입니다. 이미 trailingSlash, images 같은 설정이 들어 있어도 같은 객체 안에 나란히 넣으면 됩니다. 중요한 점은 redirects()가 배열을 반환해야 하고, 각 항목에는 최소한 source, destination, permanent가 들어간다는 것입니다.
기본 구조
/** @type {import('next').NextConfig} */
const nextConfig = {
trailingSlash: true,
images: {
unoptimized: true,
},
async redirects() {
return [
{
source: '/old-page',
destination: '/new-page',
permanent: true,
},
];
},
};
module.exports = nextConfig;
이 구조에서 source는 사용자가 들어오는 기존 경로이고, destination은 실제로 보내고 싶은 새 경로입니다. permanent: true는 영구 이동으로 처리되어 308 상태 코드를 사용하고, 클라이언트와 검색엔진이 오래 유지되는 주소 이전으로 이해할 수 있습니다. 반대로 permanent: false는 307 임시 이동으로 처리되므로, 행사 페이지처럼 잠시만 다른 경로로 보내는 경우에 더 잘 맞습니다. 파일 위치는 프로젝트 루트이며, 보통 package.json과 같은 레벨에 둡니다.
| 항목 | 의미 |
|---|---|
| source | 들어오는 기존 경로 |
| destination | 이동시킬 새 경로 |
와일드카드와 패턴 매칭도 가능하다
async redirects() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*',
permanent: true,
},
];
}
제가 next.config.js 리다이렉트를 실무에서 더 유용하게 느끼는 지점은, 정확히 한 경로만 바꾸는 것이 아니라 패턴 단위로도 처리할 수 있다는 점입니다. Next.js 공식 문서 기준으로 :slug* 같은 와일드카드 패턴을 사용할 수 있고, 경로뿐 아니라 헤더, 쿠키, 쿼리 조건을 기준으로도 리다이렉트를 구성할 수 있습니다. 주소 체계를 한 번에 옮겨야 하는 경우에는 이런 방식이 특히 편합니다.
실무에서 자주 쓰는 예시
/** @type {import('next').NextConfig} */
const nextConfig = {
trailingSlash: true,
images: {
unoptimized: true,
},
async redirects() {
return [
{
source: '/lee-jonghun-choi-in-simple/',
destination: '/lee-jonghun-choi-in/simple/',
permanent: true,
},
];
},
};
module.exports = nextConfig;
제가 이 예시를 먼저 넣는 이유는, 실제 프로젝트에서 가장 흔한 리다이렉트가 완전히 다른 페이지로 이동하는 경우보다 주소 체계를 바로잡는 경우이기 때문입니다. 특히 슬러그를 나누는 기준이 뒤늦게 바뀌었거나, 배포 후에 더 읽기 좋은 URL로 재정리해야 할 때 이런 규칙이 바로 필요해집니다. 이미 외부에 공유된 링크가 있다면 기존 경로를 죽이지 말고 새 경로로 넘겨주는 편이 훨씬 안전합니다.
여러 개를 함께 관리하는 방식
async redirects() {
return [
{
source: '/old-about',
destination: '/about',
permanent: true,
},
{
source: '/event-2025',
destination: '/events/spring',
permanent: false,
},
{
source: '/lee-jonghun-choi-in-simple/',
destination: '/lee-jonghun-choi-in/simple/',
permanent: true,
},
];
}
저는 리다이렉트가 두세 개를 넘어가기 시작하면, 주소 교정용과 임시 이동용을 한 파일 안에서 섞어 두되 의미가 보이게 정렬하는 편입니다. 예전 고정 페이지를 새 구조로 넘기는 규칙, 잠깐 운영하는 이벤트 경로를 다른 페이지로 보내는 규칙, 오타 URL을 바로잡는 규칙을 한곳에서 확인할 수 있기 때문입니다. 설정 파일을 수정한 뒤에는 개발 서버를 다시 확인해 실제 이동이 의도대로 적용되는지 꼭 점검하는 편이 좋습니다.
permanent와 관련 개념 정리

제가 처음 Next.js 리다이렉트를 정리할 때 가장 헷갈렸던 부분은 permanent와 다른 라우팅 기능의 차이였습니다. 하지만 기준은 생각보다 단순합니다. 주소 자체를 새 주소로 바꾸고 싶다면 리다이렉트이고, 사용자가 보는 주소는 그대로 두고 내부적으로 다른 곳에 연결하고 싶다면 리라이트에 가깝습니다. 또 컴포넌트나 서버 로직 안에서 상황에 따라 이동시키는 것은 설정 파일의 정적 규칙과 성격이 다릅니다.
헷갈리기 쉬운 개념 비교
redirects
- 미리 아는 경로 변경을 next.config.js에서 처리
- 브라우저 주소가 새 경로로 바뀜
- permanent 값에 따라 307 또는 308 응답 사용
rewrites
- 내부적으로 다른 경로에 연결
- 브라우저 주소는 유지됨
redirect()
- 렌더링 중이나 서버 로직 안에서 이동 처리
- 상황에 따라 303 또는 307 응답이 사용될 수 있음
Proxy
- 요청 정보에 따라 조건부 리다이렉트나 대량 규칙 처리
- 단순 규칙보다 복잡한 분기에 적합
저는 이 부분을 실무적으로 이렇게 기억합니다. 구조 개편, 경로 통합, 오타 보정처럼 배포 전에 이미 규칙을 아는 작업은 next.config.js의 redirects()가 잘 맞습니다. 반면 로그인 여부나 세션 상태처럼 요청마다 조건이 달라지는 경우는 코드 안의 redirect() 또는 Proxy가 더 자연스럽습니다. 그리고 주소를 바꾸지 않고 내부 연결만 바꾸고 싶다면 rewrites를 검토하면 됩니다. Next.js 문서에서는 단순한 이동은 먼저 redirects를 검토하고, 요청 데이터 접근이나 복잡한 로직이 필요할 때 Proxy를 쓰는 방향을 권장합니다.
| 기능 | 언제 적합한가 |
|---|---|
| redirects | 미리 아는 주소 변경, URL 이전, 오타 보정 |
| rewrites | 주소는 유지하고 내부 연결만 바꾸고 싶을 때 |
정리
저는 Next.js에서 리다이렉트가 필요할 때 먼저 이 질문부터 확인합니다. 이 규칙이 배포 전에 이미 정해진 주소 변경인가, 아니면 실행 중 조건에 따라 달라지는 이동인가. 전자라면 next.config.js의 redirects()를 쓰는 것이 가장 단순하고 관리하기 좋습니다. 그리고 permanent는 단순한 옵션이 아니라, 이 주소 변경이 앞으로 계속 유지될지 판단하는 기준입니다. 실무에서는 기존 설정을 지우지 말고 같은 객체 안에 자연스럽게 합치고, 적용 후에는 실제 URL 접속 테스트까지 해두는 흐름이 가장 안전합니다.
많이 받는 질문
Q. next.config.js 말고 next.config.ts로도 작성할 수 있나요?
가능합니다. 다만 현재 프로젝트가 어떤 파일명을 쓰고 있는지 먼저 확인하고, 이미 사용 중인 설정 파일 형식에 맞춰 유지하는 편이 좋습니다.
Q. permanent: true는 무조건 좋은가요?
그렇지는 않습니다. 앞으로도 계속 유지할 주소 이전이면 적합하지만, 잠깐만 다른 페이지로 보내는 용도라면 false가 더 자연스러울 수 있습니다. Next.js 기준으로 true는 308, false는 307 응답으로 처리됩니다.
Q. App Router를 써도 next.config.js의 redirects()를 그대로 쓰나요?
네. App Router를 사용하더라도 미리 알고 있는 전역 리다이렉트 규칙은 설정 파일에서 관리할 수 있습니다. 반대로 화면 렌더링 중 조건 분기는 코드 안의 리다이렉트 방식이 더 잘 맞습니다. 또한 redirects는 Proxy보다 먼저 실행됩니다.