서버 운영
로컬에선 열리던 미리보기 링크가 배포 서버에서 404가 난 이유
관리자 페이지에서 동적 라우트 파일을 의심했던 문제가 사실은 상대 경로 생성 함수였다.
문제 증상
관리자에서 글을 저장한 뒤 미리보기 버튼을 누르면 로컬에서는 상세 페이지가 열렸다. 그런데 운영 서버에서는 같은 버튼이 /admin/posts/... 아래로 붙으면서 404가 났다. 처음에는 동적 라우트 파일을 의심했지만, 실제 원인은 링크를 만드는 기준 URL이 현재 화면 위치에 따라 달라지는 코드였다.
헷갈렸던 지점은 router.push(slug)처럼 짧게 쓴 코드가 생각보다 오래 살아남았다는 것이다. 목록 페이지에서는 우연히 맞았고, 편집 페이지에서는 상대 경로가 되어버렸다.
주소를 세 부분으로 나눠 봤다
브라우저 주소창에 보이는 것을 그대로 복사해서 정리했다.
- 현재 관리자 주소
- 클릭 후 이동한 주소
- 원래 기대한 공개 글 주소
이렇게 적으니 라우트가 없는 문제가 아니라 상대 경로 조합 문제라는 게 바로 드러났다.
절대 경로 생성 함수로 고쳤다
관리자 화면에서는 사용자가 어디에 있든 공개 글은 항상 /posts/{slug}로 가야 했다.
function getPostPath(slug: string) {
return `/posts/${encodeURIComponent(slug)}`;
}
배포 환경에서 도메인까지 포함해야 하는 공유 링크는 별도 함수로 분리했다.
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL ?? "https://blog.example.com";
const publicUrl = new URL(getPostPath(slug), siteUrl).toString();
수정 후 확인 순서
버튼만 누르지 않고 여러 상황에서 테스트했다.
- 관리자 목록에서 미리보기 클릭
- 편집 페이지 안에서 미리보기 클릭
- 새 탭으로 열기
- 복사한 URL을 시크릿 창에서 열기
시크릿 창 확인을 넣은 이유는 관리자 세션 때문에 보이는 페이지와 실제 공개 페이지가 다를 수 있기 때문이다.
배운 점
동적 라우트 문제처럼 보여도, 운영에서만 깨지는 링크는 상대 경로부터 확인하는 게 빠를 때가 있다. 특히 관리자 페이지처럼 URL 깊이가 자주 바뀌는 화면에서는 slug만 넘기지 말고 공개 경로를 만드는 함수를 하나로 모아두는 편이 덜 헷갈린다.