Cloudflare Pages에서 글 주소를 바꿀 때 옛 주소를 301로 넘기는 법 — _redirects 한 줄과 한글 주소 확인
블로그 글을 합치거나 주소를 바꿔도 여기저기 걸어 둔 옛 링크는 고치지 않아도 됩니다. Cloudflare Pages의 _redirects 파일에 옛 주소와 새 주소를 한 줄씩 적는 법, 끝 슬래시를 두 줄로 적는 이유, 한글 주소를 curl로 확인할 때 404가 나오는 이유를 정리했습니다.
블로그를 몇 달 쓰다 보면 같은 이야기를 두 번 쓴 글이 생깁니다. 지난 10월 이 블로그에서도 겹치는 글 네 쌍을 하나로 합쳤습니다. 합치면서 없앤 쪽의 주소는 이미 다른 글이나 검색 결과에 걸려 있을 수 있었는데, 그 링크를 하나씩 찾아 고치지는 않았습니다. 옛 주소로 들어온 사람을 새 주소로 넘겨주는 줄을 적어 두면 되기 때문입니다.
이 블로그는 Astro로 만들고 Cloudflare Pages로 배포합니다. 아래는 그 환경 기준입니다.
옛 주소를 지우면 생기는 일
글 파일을 지우고 다시 배포하면 옛 주소는 404 페이지가 됩니다. 링크를 눌러 온 사람은 없는 페이지를 보고 나가고, 검색엔진도 그 주소를 결국 색인에서 뺍니다. 그동안 옛 주소에 쌓인 링크도 새 글로 이어지지 않습니다.
301은 “이 주소는 영구히 저쪽으로 옮겼다”는 응답입니다. 브라우저는 새 주소로 바로 넘어가고, 검색엔진도 옛 주소 대신 새 주소를 색인합니다.
_redirects 파일에 한 줄씩
Cloudflare Pages는 빌드 결과물 맨 위에 있는 _redirects 파일을 읽어서 주소를 넘겨줍니다. Astro라면 public/_redirects에 두면 빌드할 때 그대로 결과물 맨 위로 복사됩니다.
형식은 한 줄에 옛 주소 새 주소 상태코드입니다.
# 2026-10-19 합친 글: 7/20 백업 안심 시험 → 7/20 복구 리허설 글
/blog/2026-07-20-백업-안심-시험/ /blog/2026-07-20-백업-복구-리허설-10초/ 301
/blog/2026-07-20-백업-안심-시험 /blog/2026-07-20-백업-복구-리허설-10초/ 301
실제 이 블로그 파일에 들어 있는 줄입니다. #으로 시작하는 줄은 주석이라, 언제 무엇을 합쳤는지 적어 두면 나중에 파일을 열었을 때 이 줄이 왜 있는지 바로 보입니다.
상태코드를 빼면 기본값은 302(임시 이동)입니다. 글을 합친 건 영구 이동이니 301을 적습니다.
끝 슬래시는 두 줄로 적었다
위 예시에서 같은 글을 두 줄 적은 건 끝에 /가 있는 주소와 없는 주소를 둘 다 받기 위해서입니다. 링크를 거는 사람마다 슬래시를 붙이기도 하고 빼기도 해서, 한쪽만 적어 두면 다른 쪽으로 온 사람은 404를 볼 수 있습니다. 새 주소 쪽은 사이트가 실제로 쓰는 형태(이 블로그는 끝 슬래시 있음) 하나로 맞췄습니다.
폴더째 옮길 때는 *로 한 줄에 묶을 수 있습니다.
/posts/* /blog/:splat 301
*에 걸린 부분이 :splat 자리에 그대로 들어갑니다.
Cloudflare 문서 기준으로 _redirects 한 파일에 넣을 수 있는 줄은 고정 주소 2,000줄, *나 :이름이 들어간 줄 100줄까지입니다. 글 몇 편 합치는 정도면 한참 남습니다.
확인할 때 한글 주소는 퍼센트 인코딩
배포한 뒤 터미널에서 확인하다가 한 번 헷갈린 부분이 있습니다. 한글 주소를 curl에 그대로 넣으면 404가 나옵니다.
curl -s -o /dev/null -w "%{http_code}\n" \
"https://calmdev.kr/blog/2026-07-20-백업-안심-시험/"
# 404
브라우저는 주소창의 한글을 %EB%B0%B1... 같은 퍼센트 인코딩으로 바꿔서 보내는데, curl은 받은 글자를 그대로 보냅니다. 같은 주소를 인코딩해서 보내면 301이 제대로 보입니다.
U='/blog/2026-07-20-백업-안심-시험/'
E=$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))" "$U")
curl -sI "https://calmdev.kr$E" | grep -i "^HTTP\|^location"
# HTTP/2 301
# location: /blog/2026-07-20-%EB%B0%B1%EC%97%85-%EB%B3%B5%EA%B5%AC-...
_redirects 파일에는 한글을 그대로 적어도 됩니다. 확인하는 쪽에서만 인코딩해서 보내면 됩니다. 처음에 404를 보고 파일이 틀린 줄 알았는데, 브라우저로 같은 주소를 열어 보니 잘 넘어가고 있었습니다.
마지막까지 따라가서 200이 나오는지도 한 번 봅니다.
curl -sL -o /dev/null -w "%{http_code} %{url_effective}\n" "https://calmdev.kr$E"
# 200 https://calmdev.kr/blog/2026-07-20-%EB%B0%B1%EC%97%85-%EB%B3%B5%EA%B5%AC-...
정리하면
- 글을 합치거나 주소를 바꾸면
public/_redirects에옛 주소 새 주소 301을 적는다 - 끝 슬래시 있는 주소와 없는 주소를 두 줄로 적는다
- 언제 왜 합쳤는지 주석을 남긴다
- 한글 주소는 퍼센트 인코딩해서 curl로 확인한다
이 블로그에 지금 걸려 있는 301은 합친 글 네 쌍과 내린 페이지 하나입니다. 옛 링크를 고치러 다닌 적은 아직 없습니다.