레거시 퍼머링크를 301 리다이렉트로 통합했다
목차
몇 달 전부터 서비스의 URL 구조를 /{slug} 형식에서 /p/{id} 형식으로 정리하고 있었다. 당시엔 신규 구조로의 전환만 진행했는데, 이번엔 여전히 구형 URL로 들어오는 트래픽을 301 영구 리다이렉트로 깔끔하게 처리했다.
왜 지금이었나
처음엔 "구형 URL은 서서히 자연 소멸할 거겠지" 라고 생각했다. 하지만 현실은 달랐다:
- 외부 링크: 블로그, SNS, 뉴스레터 등에서 여전히 구형 URL이 공유되고 있었음
- 검색 결과: 구형 URL이 검색 인덱스에 여전히 존재 → 검색에서 유입되는 트래픽이 404를 만남
- 이용자 혼동: 북마크된 구형 링크를 클릭한 사용자들이 "페이지 없음" 에러를 봄
결국 SEO 가치 손실 + 이용자 경험 저하로 이어졌다. 301 리다이렉트는 단순한 "기술적 정리"가 아니라, 검색 엔진이 페이지의 권위도(authority)를 새 URL로 이전하게 하고, 외부 링크의 가치를 보존하는 작업이었다.
Astro의 catch-all 라우트로 구현
src/pages/[...slug].astro 파일에서 들어오는 모든 구형 요청을 잡아낸 후:
// 들어온 slug 를 파싱해서 ID로 변환
const { slug } = Astro.params;
const id = parseSlugToId(slug); // 기존 slug 형식 → 새 id 형식
// 301 리다이렉트 응답 생성
return new Response(null, {
status: 301,
headers: {
Location: `/p/${id}`,
}
});
이 접근은 기존 라우팅을 건드리지 않으면서도, 모든 구형 요청을 한곳에서 처리할 수 있다는 게 핵심이다. 파일 추가나 복잡한 미들웨어를 거치지 않아도 된다.
마이그레이션에서 배운 일반론
이번 작업을 통해 몇 가지 교훈을 얻었다:
| 상황 | 처리 방법 | 이유 |
|---|---|---|
| 서비스 초기 구조 변경 | 신규 구조만 적용 | 유입 트래픽이 적으니 즉각 전환 가능 |
| 구형 URL에 여전히 트래픽 있음 | 301 리다이렉트 적용 | SEO 가치 보존, 이용자 경험 개선 |
| 장기간 병행 필요 | 301을 한 해 이상 유지 | 검색 엔진이 재크롤링·재인덱싱하는 데 시간 필요 |
실제로 HTTP 상태 코드를 선택할 때도 중요하다:
- 301 (영구 이동): "이 URL은 앞으로 여기로 이동합니다" — SEO 가치 이전
- 302 (임시 이동): "일시적 변경입니다" — SEO 가치를 새 URL로 이전하지 않음 (우리는 영구 정책이었으니 301 맞음)
다음 단계
당분간 이 리다이렉트는 계속 유지할 예정이다. 3~6개월 뒤 분석 데이터를 보면서, 구형 URL 유입이 정말 무시할 수준으로 떨어졌을 때 제거를 고려할 수 있다.
프로덕션에 배포하면서 한 가지 확인한 게, 캐시 레이어(CDN)의 TTL 설정도 맞춰야 한다는 점이었다. 301은 브라우저가 오래 캐시할 수 있어서, 혹시 나중에 매핑 규칙이 바뀐다면 사용자 캐시 때문에 문제가 생길 수 있다. 우리는 캐시 시간을 보수적으로 설정했다.
URL 구조 정리는 "사소한 기술 부채 정리" 처럼 보일 수 있지만, 실제로는 검색 가시성 + 이용자 신뢰도 + 시스템 복잡도 감소가 한 번에 달성되는 작업이었다.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.