문제와 원인
없는 경로가 HTTP 404를 반환하면서 홈 canonical과 홈 title을 함께 출력했다. root metadata의 canonical: "/"와 robots: { index: true, follow: true }를 오류 페이지도 상속했고, vinext의 오류 경계가 추가한 noindex와 root의 index, follow가 함께 렌더됐다.
수정 전 코드
metadata
export const metadata: Metadata = {
metadataBase: new URL("https://www.baeumzip.site"),
title: "배움집(Baeumzip) | 자격증·전공 학습 플랫폼",
alternates: {
canonical: "/",
},
robots: { index: true, follow: true },
};
수정 후 코드
metadata
root의 alternates: { canonical: "/" }를 삭제해 정상 페이지가 각자의 canonical을 선언하도록 바꿨다. 수정 후 root 발췌:
export const metadata: Metadata = {
metadataBase: new URL("https://www.baeumzip.site"),
title: "배움집(Baeumzip) | 자격증·전공 학습 플랫폼",
robots: { index: true, follow: true },
};
현재 root에도 홈 canonical은 없지만 index, follow와 홈 title은 남아 있다. vinext가 자체 noindex와 병합 metadata를 모두 출력해 오류 페이지에 서로 다른 robots 지시가 함께 들어간다.
검증 결과
metadata 재구성
macOS·Node.js·vinext에서 원본 root 스냅샷과 오류 경계의 noindex를 버전별 1회 렌더했다. 이 metadata 재구성을 로컬 HTTP 404로 제공하고, 1280×720 CSS px·DPR 2의 브라우저 DOM과 Swagger UI 응답을 읽었다.
| root 조건 | canonical | robots | robots 내용 |
|---|---|---|---|
| 수정 전 | 1개 | 2개 | noindex + index, follow |
| canonical 제거 직후 | 0개 | 2개 | noindex + index, follow |
| 현재 | 0개 | 2개 | noindex + index, follow |
로컬 Worker의 404 응답
기존 로컬 빌드 스냅샷의 worker.fetch에 비인증 Twitterbot/1.0 합성 GET을 경로별 1회 전달했다. 같은 Worker 응답을 로컬 Swagger에서 경로별 1회 요청하고 렌더된 head를 집계했다.
| 경로 | HTTP 상태 | canonical | robots |
|---|---|---|---|
/nonexistent-audit-page | 404 | 0개 | 2개: noindex, index, follow |
/guides/nonexistent-audit-course | 404 | 0개 | 2개: noindex, index, follow |
/learn/invalid-audit-route | 404 | 0개 | 2개: noindex, index, follow |
세 경로의 title은 모두 모두의 문제집 | 자격증·전공 학습 플랫폼이었다. canonical 제거는 3/3경로에 반영됐고, robots 중복과 홈 title 상속은 3/3경로에 남아 있다.