charades.cyh-lab.com이 검색에 잘 잡히고 있는지 확인하려고charades.cyh-lab.com/sitemap.xml에 들어가봤다가 404를 봤다. 게임 5종에 가이드 아티클까지 붙여놨는데 정작 사이트맵이 없었다.
사이트맵이 아예 없었다
다른 서브도메인 사이트들은 만들 때부터 app/sitemap.ts를 같이 넣었는데, charades는 게임 기능 붙이는 데 집중하다 보니 사이트맵 자체를 빼먹었다. 게임 페이지 5개, 가이드, 개인정보처리방침, 이용약관까지 URL은 다 있는데 검색엔진에 알려주는 수단이 없었던 거다.
app/sitemap.ts 추가
App Router는 app/sitemap.ts에 함수 하나만 export하면 자동으로/sitemap.xml 라우트가 생긴다. 정적 페이지 목록을 우선순위와 함께 등록했다.
import type { MetadataRoute } from "next";
import { SITE_URL } from "@/lib/constants";
export default function sitemap(): MetadataRoute.Sitemap {
return [
{ url: SITE_URL, changeFrequency: "weekly", priority: 1 },
{ url: `${SITE_URL}/charades`, changeFrequency: "monthly", priority: 0.9 },
{ url: `${SITE_URL}/twenty-questions`, changeFrequency: "monthly", priority: 0.9 },
{ url: `${SITE_URL}/unison`, changeFrequency: "monthly", priority: 0.9 },
{ url: `${SITE_URL}/liar-game`, changeFrequency: "monthly", priority: 0.9 },
{ url: `${SITE_URL}/photo-quiz`, changeFrequency: "monthly", priority: 0.9 },
{ url: `${SITE_URL}/guide`, changeFrequency: "monthly", priority: 0.7 },
{ url: `${SITE_URL}/privacy`, changeFrequency: "yearly", priority: 0.3 },
{ url: `${SITE_URL}/terms`, changeFrequency: "yearly", priority: 0.3 },
];
}게임 페이지들은 priority: 0.9로 높게, 가이드는 0.7, 약관류는 0.3으로 낮게 뒀다. 가이드 아티클 15개는 이번엔 넣지 않았다 — 정적 라우트가 아니라 나중에 개별 페이지 구조를 정리하면서 추가하기로 했다.
robots.ts는 그대로 뒀다
애드센스 재승인 심사 기간 동안은 크롤링은 허용하되 각 페이지의 noindex 메타 태그로 색인만 막아둔 상태였다. 이 기간엔 robots.ts에서 사이트맵 링크를 일부러 비워뒀는데, 사이트맵 자체를 새로 만든 김에 이 부분도 다시 볼까 했지만 심사가 끝나기 전까지는 그대로 두기로 했다. 색인 방식과 사이트맵 노출 방식을 심사 중에 같이 건드리면 원인 파악이 더 어려워질 것 같았다.
www 쪽은 이미 자동으로 반영되고 있었다
처음엔 www.cyh-lab.com 사이트맵에도 새로 올라간 블로그 글 슬러그를 하나씩 확인해서 추가해야 하는 줄 알았다. 그런데 코드를 보니 이미 BLOG_POSTS 배열을 그대로 매핑하고 있어서, 글을 추가하기만 하면 사이트맵에도 자동으로 반영되는 구조였다.
import type { MetadataRoute } from "next";
import { BLOG_POSTS } from "@/lib/blog";
const siteUrl = "https://www.cyh-lab.com";
export default function sitemap(): MetadataRoute.Sitemap {
return [
{ url: siteUrl, changeFrequency: "weekly", priority: 1 },
...BLOG_POSTS.map((post) => ({
url: `${siteUrl}/blog/${post.slug}`,
changeFrequency: "monthly" as const,
priority: 0.6,
})),
// ...projects, about 등
];
}슬러그를 하나하나 손으로 챙길 필요가 없다는 걸 뒤늦게 확인한 셈이다. 반대로 charades는 정적 페이지 목록을 직접 나열하는 방식이라, 새 게임을 추가하면app/sitemap.ts도 같이 손봐야 한다는 걸 기억해두기로 했다.
사이트를 늘려가다 보니 한쪽에서 당연하다고 생각한 게 다른 쪽엔 빠져 있는 경우가 종종 있다. 새 서브도메인을 만들 때 체크리스트에 사이트맵을 넣어야겠다.