개발 slecs

레거시 퍼머링크를 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

첫 댓글 달아줘.