다국어 블로그는 번역 자체는 잘 되어 있어도 검색엔진을 헷갈리게 만들 수 있습니다. 문제는 대개 글 내용이 아니라, canonical URL과 alternate language 관계를 글 상세, 카테고리, 인덱스, 홈 경로까지 어떻게 표현했는지에 있습니다.
그래서 이런 증상이 자주 생깁니다.
- 영어 글이 있는데도 검색에는 한국어 글만 강하게 남는다
- 한 언어 버전이 다른 언어 버전을 잡아먹는 것처럼 보인다
- 글 상세는 괜찮은데 카테고리나 인덱스는 흐트러진다
- 홈은 맞는데 세부 경로 alternate가 불완전하다
이 글은 그 실전 규칙을 정리합니다.
- 언제 self-canonical을 써야 하는지
hreflang묶음은 어떻게 연결돼야 하는지x-default는 언제 유용한지- 최종 렌더 HTML에서 무엇을 확인해야 하는지
짧게 말하면 각 언어 페이지를 독립적인 실제 페이지로 보고, canonical은 같은 언어 안에서 유지하고, hreflang으로 진짜 대응 페이지를 연결하고, 글/카테고리/인덱스/기본 fallback까지 같은 규칙을 지키는 것이 핵심입니다.
먼저 이 두 신호가 하는 일을 나눠서 보기
canonical과 hreflang은 같은 일을 하지 않습니다.
canonical은 이렇게 말합니다.
- 이 페이지 버전의 대표 URL은 이것이다
hreflang은 이렇게 말합니다.
- 이 페이지의 언어/지역 대안은 이것들이다
이 차이가 중요한 이유는, 다국어 블로그에서 가장 흔한 실수가 canonical을 언어 간 통합 도구처럼 써버리는 것이기 때문입니다.
영어 페이지 canonical을 한국어 페이지로 보내면, 영어 페이지를 이해시키는 것이 아니라 “영어 페이지는 자기 자신이 대표가 아니다”라고 말하게 됩니다.
Google이 기대하는 건강한 다국어 구조
Google의 다국어 문서를 기준으로 보면 기본 원칙은 꽤 단순합니다.
- 언어 버전마다 다른 URL을 쓴다
- 각 언어 페이지는 자기 자신과 다른 언어 버전을 함께
hreflang에 넣는다 - alternate URL은 절대경로를 쓴다
- 대응 페이지끼리는 서로를 가리켜야 한다
한국어와 영어 블로그라면 보통 이런 패턴이 자연스럽습니다.
- 한국어 페이지는 자기 자신을 canonical로 가리킨다
- 영어 페이지도 자기 자신을 canonical로 가리킨다
- 각 페이지는 실제 대응되는 번역 페이지를
hreflang으로 연결한다 x-default는 하나의 안정된 fallback 경험을 가리킨다
즉, 둘은 합쳐지는 것이 아니라 연결되는 관계입니다.
언어별로 다른 URL을 쓰고, 적응형 추측에 기대지 않기
Google은 쿠키나 브라우저 언어만 보고 같은 URL에서 내용을 바꾸는 방식보다, 언어별로 명시적인 URL을 쓰는 방식을 권장합니다.
이유는 간단합니다.
- Googlebot이 모든 언어 변형을 다 못 볼 수 있고
- 자동 redirect가 사용자와 크롤러 모두의 접근을 막을 수 있고
- locale별 경로가 따로 있어야 route 단위로 규칙을 유지하기 쉽기 때문입니다
Astro 기반 블로그라면 보통 이런 식이 관리하기 쉽습니다.
- 한국어 글:
/blog/my-guide/ - 영어 글:
/en/blog/my-guide/
런타임에서 한 URL이 언어를 바꾸는 방식보다 훨씬 명확합니다.
self-canonical이 기본값인 이유
localized page가 실제 페이지라면, canonical은 보통 자기 자신을 가리켜야 합니다.
즉:
- 한국어 canonical -> 한국어 URL
- 영어 canonical -> 영어 URL
Google canonical 문서도 hreflang을 쓸 때는 같은 언어의 canonical을 쓰거나, 같은 언어 canonical이 없을 때만 가능한 최선의 대체 언어를 쓰라고 설명합니다.
그래서 아래 지름길은 대부분 잘못입니다.
- 영어 페이지 canonical -> 한국어 원문
이건 영어 페이지를 대응 페이지로 연결하는 것이 아니라, 열등한 중복본처럼 취급하게 만듭니다.
hreflang 묶음은 상호 연결되고, 최소한 충분히 완결돼 있어야 한다
Google의 localized versions 문서는 각 언어 버전이 자기 자신과 다른 버전을 모두 적어야 하고, 서로 양방향으로 가리키지 않으면 무시될 수 있다고 설명합니다.
실전에서는 대개 이런 형태가 됩니다.
<link rel="alternate" hreflang="ko" href="https://example.com/blog/my-guide/" />
<link rel="alternate" hreflang="en" href="https://example.com/en/blog/my-guide/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/blog/my-guide/" />
중요한 것은 언어 코드 그 자체보다 아래입니다.
- URL이 절대경로인가
- 자기 자신도 포함하는가
- 진짜 대응 페이지끼리 서로 연결되는가
- 모든 버전에서 같은 묶음이 유지되는가
x-default는 fallback이지, 중복 제어 트릭이 아니다
x-default는 더 잘 맞는 언어나 지역 버전이 없을 때 보여줄 fallback URL을 정할 때 유용합니다.
좋은 예:
- 언어 선택 페이지
- 기본 언어 홈
- 사이트 전체에서 공통으로 쓰는 기본 route 버전
핵심은 일관성입니다.
사이트의 기본 경험이 한국어라면 x-default를 한국어 쪽으로 두는 것도 충분히 합리적입니다. 하지만 템플릿이나 route마다 fallback이 들쭉날쭉하면 신호가 약해집니다.
글 상세만 맞추면 끝이 아니다: 카테고리, 인덱스, 홈도 중요하다
많은 다국어 블로그가 글 상세에만 hreflang을 넣고 끝냅니다. 그다음 구조가 조용히 깨집니다.
- 홈
- 블로그 인덱스
- 카테고리 페이지
- 페이지네이션이나 아카이브
이 불일치는 사이트 전체 다국어 정보 구조를 약하게 만듭니다.
더 나은 기준은 이겁니다.
- route 유형에 실제 대응 페이지가 있으면 글과 같은 수준으로 canonical과
hreflang규칙을 적용한다 - 대응 페이지가 없으면 주제가 비슷하다는 이유만으로 가짜 alternate를 만들지 않는다
대응은 “주제가 비슷함”이 아니라 “route가 실제로 대응됨”이어야 합니다.
2개 언어 블로그에서 쓰기 쉬운 route 판단표
실전에서는 이 정도로 나누면 헷갈림이 줄어듭니다.
| route 유형 | canonical | hreflang |
|---|---|---|
| 번역된 글 쌍 | 각 언어에서 self-canonical | 실제 대응 글끼리 연결 |
| 언어별 카테고리 쌍 | 각 언어에서 self-canonical | 같은 카테고리끼리 연결 |
| 블로그 인덱스 쌍 | 각 언어에서 self-canonical | 같은 인덱스끼리 연결 |
| 대응 페이지가 없는 단독 페이지 | self-canonical | 가짜 alternate는 넣지 않음 |
이 모델이 edge case를 가장 덜 만듭니다.
다국어 블로그에서 자주 깨지는 실수
1. 한 언어 canonical을 다른 언어로 보내기
가장 큰 실수입니다. canonical은 alternate language를 알려주는 주도구가 아닙니다.
2. 상대경로나 들쭉날쭉한 URL 형식 쓰기
Google localized versions 문서는 fully-qualified alternate URL을 요구합니다. origin이 빠지거나 slash 규칙이 흔들리면 묶음이 조용히 약해집니다.
3. 글은 맞는데 카테고리나 인덱스는 비워두기
글만 다국어 구조를 갖고 목록 구조가 빠지면 사이트는 반쯤만 다국어인 상태가 됩니다.
4. 한쪽만 다른 쪽을 가리키고, 반대는 없는 경우
Google은 양방향 연결을 요구합니다. 서로 가리키지 않으면 hreflang 관계가 무시될 수 있습니다.
5. 자동 언어 redirect가 실제 페이지 접근을 막는 경우
사용자와 크롤러가 locale URL에 안정적으로 도달하지 못하면 검증도, 색인도 어려워집니다.
6. lang 속성을 핵심 신호로 오해하는 경우
Google은 페이지 언어를 visible content로 판단한다고 설명합니다. hreflang은 alternate target용이지, 페이지 언어 판별 자체와는 다릅니다.
컴포넌트 코드만 보지 말고 최종 렌더 HTML을 확인하기
여기서 많이 멈춥니다.
레이아웃 컴포넌트가 맞아 보여도 실제 출력이 맞는지 확인해야 합니다. 최종 렌더 HTML에서 최소한 아래를 보세요.
<link rel="canonical" ...><link rel="alternate" hreflang="ko" ...><link rel="alternate" hreflang="en" ...><link rel="alternate" hreflang="x-default" ...>
그리고 이 규칙이 아래 route들에도 같은지 봐야 합니다.
- 글 상세
- 카테고리 페이지
- 블로그 인덱스
- 홈
route 유형 하나만 다르게 동작하면 다국어 구조는 아직 덜 완성된 것입니다.
가장 안전한 사고방식: 대응 페이지는 분리해서 살리고, 그다음 연결한다
이 한 모델이 대부분의 실수를 막아줍니다.
- 각 localized page는 독립적인 실제 페이지다
- canonical은 self-reference를 유지한다
hreflang은 진짜 대응 페이지끼리만 연결한다x-default는 fallback 결정이다
이렇게 생각하면 구현이 복잡해지는 게 아니라 오히려 단순해집니다.
실전 검증 체크리스트
설정을 믿기 전에 아래를 확인하세요.
- 각 언어 페이지가 자기 자신을 canonical로 가리키는가
- alternate URL이 절대경로인가
- 자기 자신도
hreflang묶음에 들어가는가 - 대응 페이지끼리 서로를 가리키는가
x-default가 같은 route 유형에서 일관적인가- 카테고리와 인덱스도 글과 같은 모델을 따르는가
- 강제 redirect 혼란 없이 사용자가 모든 언어 버전에 접근할 수 있는가
여기서 여러 개가 틀리면, 태그 하나의 문제가 아니라 route 모델 전체가 흔들리는 경우가 많습니다.
FAQ
Q. 영어 페이지 canonical을 한국어 원문으로 보내야 하나요?
보통은 아닙니다. 각 언어 버전이 자기 자신을 canonical로 가지는 것이 기본입니다.
Q. 카테고리 페이지에도 hreflang이 필요한가요?
네. 실제 대응되는 다국어 카테고리가 있다면 필요합니다. 지원 페이지가 아니라 정보 구조의 일부이기 때문입니다.
Q. x-default는 보통 어디를 가리키나요?
대개 기본 언어 버전이나, 언어 선택 페이지처럼 안정된 fallback 경험을 가리킵니다.
Q. 가장 흔한 구현 실수는 무엇인가요?
각 언어 페이지를 독립 페이지로 살리지 않고, canonical로 서로를 눌러버린 뒤 hreflang까지 애매하게 섞어 쓰는 것입니다.
Official References
- https://developers.google.com/search/docs/specialty/international/localized-versions
- https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls
- https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites
Read Next
- 구현 범위를 더 넓게 점검하려면 Technical Blog SEO Checklist for Astro로 이어가세요.
- 크롤링, 메타데이터, 내부 구조까지 함께 보려면 SEO Guide for Technical Blogs가 다음 단계입니다.
- 도메인 정합성까지 함께 의심된다면 Cloudflare DNS Guide도 같이 보는 편이 좋습니다.
Related Posts
먼저 읽어볼 가이드
검색 유입이 많은 핵심 글부터 이어서 보세요.
- 미들웨어 트러블슈팅 가이드: Redis, RabbitMQ, Kafka 중 어디부터 볼까 Redis, RabbitMQ, Kafka가 함께 있는 시스템에서 지금 보이는 장애가 어느 계층에 더 가까운지, 첫 10분 안에 무엇을 확인하고 어떤 글로 들어가야 하는지 정리한 실전 허브 가이드입니다.
- Kubernetes CrashLoopBackOff: 먼저 볼 것들 startup failure, probe, config, resource limit 관점에서 CrashLoopBackOff를 어떻게 나눠서 봐야 하는지 정리한 가이드입니다.
- Astro 기술 블로그 SEO 체크리스트: 트래픽 기다리기 전에 먼저 고칠 것 Astro 기술 블로그를 위한 실전 SEO 체크리스트입니다. 배포 호스트 확인, robots.txt, sitemap, canonical, hreflang, 구조화 데이터, 페이지별 메타데이터, noindex 판단, 검증 명령까지 우선순위대로 정리합니다.
- OpenAI Codex CLI 설치 가이드: 설치, 인증, 첫 작업까지 OpenAI Codex CLI를 실전 기준으로 설치하는 방법을 정리했다. 설치, 로그인, 첫 실행, Windows 주의점, 첫 작업을 어떻게 시작하면 좋은지까지 다룬다.