노트
redirect와 rewrite의 차이
2026.09.23
웹 애플리케이션에서 한 요청을 다른 페이지로 연결할 때 redirect와 rewrite를 사용할 수 있다. 둘 다 요청을 다른 곳으로 연결하지만, 브라우저의 주소가 바뀌는지가 다르다.
redirect
redirect는 브라우저에 다른 주소로 다시 요청하라고 응답한다. 사용자는 새로운 주소로 이동하고 주소창도 바뀐다.
예를 들어 minjun.me/blog를 블로그의 독립 도메인으로 옮기고 싶다면 다음처럼 설정할 수 있다.
async redirects() {
return [
{
source: '/blog',
has: [{ type: 'host' as const, value: 'minjun\\.me' }],
destination: 'https://blog.minjun.me',
permanent: true,
},
];
}
메인 도메인에서 /blog를 요청하면 브라우저는 https://blog.minjun.me를 다시 요청한다. 최종 주소가 바뀌기 때문에 사용자는 현재 어떤 주소를 사용하고 있는지 바로 알 수 있다.
Next.js의 redirects에서 permanent: true를 사용하면 308 응답을 보내고, false로 두면 307 응답을 보낸다. 영구적으로 주소를 옮길 때는 true를, 잠시 다른 주소로 보내거나 실험할 때는 false를 선택할 수 있다.
rewrite
rewrite는 브라우저 주소를 그대로 둔 채 서버 내부에서 다른 경로의 페이지를 보여준다. 주소와 실제로 렌더링하는 페이지를 분리할 수 있다.
blog.minjun.me/를 애플리케이션 내부의 /blog 페이지에 연결하려면 다음처럼 설정한다.
async rewrites() {
return {
beforeFiles: [
{
source: '/',
has: [
{ type: 'host' as const, value: 'blog\\.minjun\\.me' },
],
destination: '/blog',
},
],
};
}
사용자가 blog.minjun.me/에 접속하면 내부적으로 /blog 페이지가 렌더링된다. 하지만 주소창에는 계속 blog.minjun.me/가 표시된다.
둘을 나누어 사용하는 기준
주소 자체를 바꿔야 한다면 redirect, 주소는 유지하고 내부 페이지를 연결해야 한다면 rewrite를 사용한다.
| 상황 | 선택 | 브라우저 주소 |
|---|---|---|
| 오래된 주소를 새 주소로 옮김 | redirect | 바뀜 |
| 도메인의 루트를 내부 경로에 연결함 | rewrite | 유지됨 |
| 임시 주소로 보내거나 정식 주소를 알림 | redirect | 바뀜 |
| 외부에 보이는 주소와 앱 내부 경로를 분리함 | rewrite | 유지됨 |
내 사이트에서는 두 기능을 함께 사용했다. minjun.me/blog와 minjun.me/portfolio는 각각 서브도메인으로 이동해야 하므로 redirect를 적용했다. 반대로 blog.minjun.me/와 portfolio.minjun.me/는 주소를 그대로 보여주면서 /blog와 /portfolio 페이지를 렌더링해야 하므로 rewrite를 사용했다.
예를 들어 minjun.me/blog를 rewrite로 연결하면 주소창은 계속 minjun.me/blog로 남는다. 블로그 주소를 blog.minjun.me/로 바꾸려는 목적을 이루지 못한다. 반대로 blog.minjun.me/를 내부 경로인 /blog로 redirect하면 주소창도 blog.minjun.me/blog로 바뀐다. 그래서 minjun.me/blog를 blog.minjun.me/로 바꿀 때는 redirect를 쓰고, blog.minjun.me/ 주소를 유지하면서 앱의 /blog 페이지를 보여줄 때는 rewrite를 쓴다.