← 전체 글로 돌아가기

Next.js

SEO용 canonical URL을 도메인 하나로 고정한 체크리스트

www와 비www, 쿼리 문자열이 섞인 작은 사이트에서 canonical과 리다이렉트를 맞춘 점검 목록.

검색 결과에 같은 글이 둘씩 보이기 시작했다

배포 초기에는 www 주소와 기본 도메인이 모두 열렸다. 공유 링크에는 ?ref=twitter도 붙었다. 페이지 내용은 같아도 검색 엔진에 어느 주소가 기준인지 매번 추측하게 만든 셈이었다.

기준 주소를 먼저 결정했다

나는 HTTPS의 비www 주소를 기준으로 정했다. 이 선택 자체보다, 애플리케이션·프록시·sitemap이 모두 같은 선택을 하는 것이 중요했다.

server {
  listen 443 ssl;
  server_name www.example.com;
  return 301 https://example.com$request_uri;
}

Next.js에서는 페이지별 canonical을 절대 URL로 만들었다. 개발 환경 주소가 섞이지 않게 환경 변수도 하나의 공개 주소만 갖게 했다.

export const metadata = {
  alternates: {
    canonical: 'https://example.com/posts/hello',
  },
}

쿼리 문자열은 용도에 따라 나눴다

UTM 값은 콘텐츠를 바꾸지 않으므로 canonical에서 제외했다. 반면 ?page=2처럼 목록 결과가 달라지는 값까지 무조건 첫 페이지로 canonical 처리하지 않았다. 여기서 가장 헷갈렸던 것은 필터 URL이었다. 실제로 색인할 가치가 없으면 canonical만 억지로 붙이기보다 noindex 여부를 먼저 검토했다.

배포 뒤에 확인한 목록

curl -I https://www.example.com/posts/hello
curl -s https://example.com/posts/hello | grep -o 'rel="canonical"[^>]*'
  • www 요청이 한 번의 301으로 기준 주소에 도착하는가
  • HTML의 canonical이 현재 공개 URL과 같은가
  • sitemap URL과 canonical URL이 일치하는가
  • 내부 링크가 옛 도메인을 만들고 있지 않은가

canonical은 검색 순위를 올리는 스위치라기보다, 사이트가 자기 주소를 일관되게 말하게 하는 장치였다.