개발 slecs

레거시 URL 경로 유지로 검색 가시성 보존

목차

구 URL 구조(/{slug})에서 새로운 구조(/p/{id})로 마이그레이션하면서, 기존에 인덱싱된 모든 레거시 경로를 301 영구 리다이렉트로 자동 연결하는 작업을 했다. 작은 변경처럼 보이지만 SEO 손실, 사용자 경험, 외부 인바운드 링크 유지 관점에서 꽤 중요한 결정 포인트였다.

URL 구조 변경과 그 파장

서비스가 성장하면서 콘텐츠 구조화 방식이 바뀌는 건 자연스럽다. 처음엔 단순히 slug로 경로를 만들었는데, 나중에 ID 기반 구조로 변경하면서 호환성 문제가 생긴 것. 이때 핵심은 기존 사용자와 검색엔진 양쪽에 부담을 주지 않는 것이다.

브라우저 북마크, 블로그/SNS에서 공유된 링크, 외부 사이트의 인바운드 링크, 무엇보다 구글/네이버가 이미 인덱싱한 페이지들이 모두 레거시 경로를 가리키고 있기 때문이다. 이들을 무시하고 그냥 404를 반환하거나 홈으로 리다이렉트하면? 검색 결과에서 사라지고, 사용자는 "링크가 깨졌네"라고 경험하고, 시간이 지나 다시 인덱싱되기까지 SEO 손실이 눈에 띄게 발생한다.

301 vs 302, 그 미묘한 차이

리다이렉트를 할 때 사람들이 자주 놓치는 부분이 상태 코드다.

구분 301 Moved Permanently 302 Found 307 Temporary Redirect
의미 영구적 이동 임시 이동 임시 이동 (메서드 보존)
캐싱 검색엔진이 새 URL로 업데이트 계속 기존 URL 크롤 제한적 캐싱
사용 경우 도메인 변경, URL 구조 완전 변경 임시 점검/이벤트 페이지 HTTP 메서드 중요할 때
SEO 영향 높음 (페이지 랭크 인수 통과) 낮음 (원본 유지) 보통

이 작업에서 301을 선택한 이유는 명확하다. 우리는 구 URL 구조를 완전히 버릴 계획이고, 검색엔진이 새 경로로 리인덱싱하길 원했기 때문이다. 만약 302를 썼다면? 검색엔진은 "아, 이건 임시겠지, 나중에 다시 기존 URL을 크롤링해야지"라고 생각해서, 변경 사실을 제대로 반영하지 않았을 것.

Astro의 동적 라우팅으로 어떻게 구현했나

Astro는 파일 기반 라우팅을 쓴다. src/pages/[...slug].astro 같은 파일은 모든 경로를 캡처하는 catch-all 라우트다.

---
// src/pages/[...slug].astro
export async function getStaticPaths() {
  // 모든 가능한 레거시 slug 나열
  // (빌드 타임 또는 요청 타임에 결정)
}

const { slug } = Astro.params;

// 레거시 slug를 새로운 ID 기반 경로로 변환
const newUrl = convertLegacySlugToNewPath(slug);

// 301 리다이렉트
return Astro.redirect(newUrl, 301);
---

핵심은 Astro.redirect(url, 301)로 명시적으로 상태 코드를 지정한 것. 이렇게 하면 브라우저와 검색엔진 모두에게 "이 페이지는 여기로 영구적으로 옮겨갔다"는 신호를 보낸다.

팀 관점에서 고려했던 것들

이런 URL 마이그레이션 작업을 할 때, 내가 팀 리더로서 챙겨야 할 부분들이 있었다:

  • 매핑 로직의 정확성: slug에서 ID로의 변환 로직이 정말 모든 경우를 커버하는가? 특수 문자, 중복 slug, 역사적으로 변경된 규칙들?
  • 모니터링 계획: 배포 후 실제로 리다이렉트가 잘 작동하는지 어떻게 확인할 것인가? (Google Search Console, 로그 분석 등)
  • 점진적 검증: 모든 레거시 URL을 한 번에 전환하기보다, 먼저 샘플 몇 개를 A/B 테스트할 여지가 있는가?
  • 팀 커뮤니케이션: 마케팅팀은 언제쯤 SEO 효과를 기대할 수 있는지, 외부 파트너사와 공유한 링크들이 영향받지 않는지 확인해야 하는가?

특히 마지막 포인트가 중요했다. 외부 협력사나 고객사와 링크를 공유했다면, 그들 입장에서는 "아, 너희 URL이 바뀐 거네"라고 알아야 한다. 리다이렉트는 사용자 입장에선 투명하지만, 운영 관점에선 명시적인 공지와 모니터링이 필요하다.

배운 점과 주의사항

처음에는 "그냥 리다이렉트하면 되지" 했지만, 실제로는 꽤 신경 쓸 부분이 많았다:

  1. 캐시 전략: CDN이 301을 브라우저 캐시처럼 오래 보관하면, 나중에 리다이렉트 로직을 수정할 때 문제가 될 수 있다. 캐시 헤더를 신중하게.

  2. 로그 분석의 필요성: 초기엔 301이 얼마나 트래픽을 받는지, 점진적으로 감소하는지 모니터링해야 한다. 이상하게 높으면 뭔가 잘못된 걸 의미할 수 있다.

  3. 사내 문서와 API 문서 업데이트: 개발팀 내 위키, API 문서, 클라이언트 SDK에서 레거시 경로가 아직 남아있지 않은지 확인. 레거시를 권장하는 예제를 그대로 두면 신규 팀원이 헷갈린다.

  4. 타이밍: URL 변경은 주말에, 혹은 예측 가능한 시간에 하는 게 좋다. 만약 문제가 생기면 빠르게 대응할 수 있으니까.

결국 이 "간단한" 301 리다이렉트는 기술적으로는 몇 줄이지만, 사용자 경험, SEO, 운영 안정성이 교차하는 결정 포인트였다. 다음 번엔 처음부터 URL 구조를 더 신중하게 설계해야겠다는 생각도 들었고.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.