hreflang 태그 사용법: 완벽 가이드 + 무료 도구

사이트가 두 개 이상의 언어나 국가를 대상으로 운영된다면, hreflang 태그는 검색 엔진에 어떤 URL이 어떤 독자층용인지 알려줍니다. 유효한 클러스터는 Google이 각 독자층에 알맞은 버전을 보여 주도록 돕지만, 깨진 클러스터는 Google이 중복 페이지 사이를 오가거나 엉뚱한 버전을 노출하게 만듭니다. 이 가이드에서는 문법, 리턴 태그, x-default, 그리고 어노테이션 세트를 소리 없이 무효화하는 실수들을 다루고, 유효한 태그와 XML 사이트맵 대안 형식까지 출력해 주는 무료 hreflang 태그 생성기를 함께 소개합니다.

hreflang 태그란 무엇인가요?

hreflang은 HTML <link> 요소의 속성으로, URL 한 그룹을 같은 콘텐츠의 현지화 버전으로 표시합니다:

<link rel="alternate" hreflang="de-DE" href="https://example.com/de/" />

이 태그는 모든 언어 버전의 <head> 안에 들어갑니다.

중요한 사실이 두 가지 있습니다. hreflang은 지시(directive)가 아니라 힌트입니다 — 유효한 세트는 Google이 올바른 버전을 보여 주는 데 도움을 줄 뿐, 특정 버전을 강제하지 않습니다. 그리고 Google은 페이지의 언어를 감지할 때 hreflang(또는 lang 속성)을 사용하지 않습니다. 언어는 알고리즘으로 판단합니다.

hreflang 문법: 언어, 문자, 지역 코드

값의 순서는 고정되어 있습니다 — 언어, 선택적 문자(script), 선택적 지역 — 각각 ISO 639-1, ISO 15924, ISO 3166-1 Alpha 2를 따릅니다. 코드는 대소문자를 가리지 않으며, 관례상 언어는 소문자, 지역은 대문자로 씁니다.

유효한 코드:

  • en-GB — 영국 사용자를 위한 영어
  • zh-Hans — 중국어, 간체 문자

Google 문서가 특별히 짚는 함정들입니다:

  • en-UK — 잘못된 코드: UK는 공식적으로 할당된 ISO 3166-1 요소가 아니라서 Google이 무시합니다(EU, UN도 마찬가지). en-GB를 사용하세요.
  • gb-en — 순서 오류: 언어가 항상 먼저 옵니다.
  • es-419 — 숫자 형식의 UN 지역 코드는 지원되지 않습니다. ISO 3166-1 Alpha 2만 가능합니다.
  • “벨기에”를 뜻하려고 쓴 be — 지역만 단독으로 쓰는 것은 유효하지 않고, be는 벨라루스어 코드입니다. nl-BE, fr-BE, de-BE를 사용하세요.

다중 로캘 언어에 대한 Google의 안내: 하나의 언어로 여러 로캘(en-IE, en-CA, en-AU)을 타깃한다면, 나머지 모든 사용자를 위한 일반 en 코드(catch-all)를 제공하세요. Google은 이를 “좋은 방법”이라고 말할 뿐 필수 요건은 아니며, 이 catch-all URL은 지역 버전 가운데 하나와 공유해도 됩니다 — en은 en-IE와 같은 URL을 가리킬 수 있습니다.

리턴 태그: 모든 버전이 서로를 가리켜야 하는 이유

리턴 태그는 상호 참조 규칙입니다. 페이지 X가 페이지 Y를 가리키면 Y도 X를 다시 가리켜야 하고, 모든 버전은 자기 자신도 목록에 넣어야 합니다. Google의 규칙: 두 페이지가 서로를 가리키지 않으면 어노테이션은 무시됩니다. 흔히 드는 근거: 리턴 링크가 없다면 누구나 자기 페이지를 당신 페이지의 대체 버전이라고 선언할 수 있기 때문입니다. 영어 버전과 독일어 버전을 갖춘 사이트라면 두 페이지의 <head>에 같은 태그 세트가 들어갑니다:

<link rel="alternate" hreflang="en" href="https://example.com/" />
<link rel="alternate" hreflang="de-DE" href="https://example.com/de/" />

두 페이지 모두 이 두 줄을 담습니다. 어느 한 버전에서라도 세트를 빠뜨리면 클러스터가 깨지기 시작합니다. Google 문서의 완화 안: 완전한 양방향 세트를 유지하기 어려울 때는 일부 페이지에서 일부 언어를 생략해도 됩니다 — 여전히 서로를 가리키는 쌍은 계속 작동합니다. 명시된 우선순위는 새로 추가하는 언어 버전을 사이트의 원래(주력) 언어와 양방향으로 연결하는 것입니다 — 프랑스어 .fr 페이지에서 시작해 성장한 사이트라면 새 스페인어 버전을 프랑스어 페이지와 먼저 연결하고, 그다음 서로 연결하세요.

x-default란 무엇이고 언제 필요한가요?

x-default는 예약된 값으로, 나열한 언어 중 어느 것도 사용자의 브라우저 설정과 일치하지 않을 때 제공할 URL을 지정합니다 — link 태그 하나만 추가하고 언어 코드는 없습니다:

<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/select-language/" />

x-default는 선택 사항이지만 권장됩니다 — 언어 선택 페이지와 자동 리디렉션 홈페이지를 위해 설계되었습니다. 기본 언어 버전을 가리키는 것 역시 표준 패턴이며, 생성기가 기본으로 예상하는 방식이기도 합니다.

hreflang 태그를 구현하는 세 가지 방법

Google은 이 세 가지 방법을 완전히 동등하게 취급합니다. 공식 문서에서는 세 가지를 동시에 사용해도 “검색에서 이득은 없다(no benefit in Search)”고 말하며, 하나만 선택하는 것보다 관리가 더 어렵다고 덧붙입니다.

1. head 안에 넣는 HTML link 태그

소규모 사이트를 위한 방법입니다. 모든 버전의 잘 구성된(well-formed) <head> 안에 전체 세트를 넣으세요. Google의 규칙 두 가지: 태그는 실제로 head 안에 있어야 합니다(CMS가 마크업을 재작성한다면 렌더링된 HTML을 검증하세요). 그리고 hreflang을 media 같은 속성과 한 태그에 함께 넣지 마세요.

2. XML 사이트맵 어노테이션

규모가 클 때는 hreflang을 HTML 바깥으로 빼세요. 각 <url> 항목 안에 <loc>와 함께, 자기 자신을 포함한 모든 버전의 xhtml:link 자식 요소를 추가합니다:

<url>
  <loc>https://example.com/</loc>
  <xhtml:link rel="alternate" hreflang="en" href="https://example.com/" />
  <xhtml:link rel="alternate" hreflang="de-DE" href="https://example.com/de/" />
</url>

xmlns:xhtml="http://www.w3.org/1999/xhtml" 네임스페이스를 선언하고, 모든 버전에 대해 <url> 블록을 반복하세요. 자식 요소의 순서는 상관없습니다. Google은 xhtml:link 자식 요소가 사이트맵 URL 제한에 포함되지 않는다고 확인해 줍니다 — 프로토콜의 URL 상한 50,000개는 <url> 항목만 셉니다.

3. HTTP Link 헤더

PDF처럼 HTML이 아닌 파일에는 파일이 제공되는 지점에서 Link 헤더를 설정하세요 — nginx라면 해당 location에 add_header 규칙을 추가합니다:

add_header Link '<https://example.com/file.pdf>; rel="alternate"; hreflang="en",
                <https://example.com/de/file.pdf>; rel="alternate"; hreflang="de"';

Apache의 Header set이나 CDN의 응답 헤더 규칙으로도 같은 결과를 얻을 수 있습니다.

무료 도구로 hreflang 태그 생성하기

hreflang 태그 생성기는 세트를 만들고 입력하는 동시에 검증합니다 — 가입이 필요 없고 브라우저에서 바로 실행됩니다.

1단계: 완전한 세트 만들기

버전마다 한 행씩 추가하세요 — 왼쪽에 언어 코드, 오른쪽에 절대 URL — 어노테이션을 다는 페이지가 자기 자신을 가리키는 행도 반드시 포함합니다. 자기 참조는 필수이고, 이렇게 만든 동일한 세트를 모든 버전의 head에 붙여넣습니다(4단계) — 그러니 한 번만, 완전한 상태로 만들어 두세요. 코드는 언어-문자-지역 패턴으로 실시간 검증됩니다 — en, pt-BR, zh-Hans는 통과, gb-en은 경고 표시 — 대소문자도 자동으로 정규화됩니다(en-gb는 en-GB로 바뀝니다).

2단계: x-default URL 설정

폴백 URL을 입력하세요 — 기본 언어 버전 또는 언어 선택 페이지 — 비워 두면 x-default를 생략합니다. URL이 세트 바깥에 있으면 경고가 뜹니다. 언어 선택 페이지라면 설계상 언어 클러스터 밖에 있으므로 정상이고 올바른 동작입니다. 선택 페이지가 아닌데 경고가 뜬다면 대개 오타입니다.

3단계: 생성하고 검증 결과 확인하기

Generate hreflang tags를 클릭하세요. 체크리스트는 중복 언어 코드를 오류로 표시하고, 절대 URL이 아니면 거부하며, 자기 참조와 항목이 하나뿐인 세트에 경고를 보냅니다. 항목이 하나뿐이라면 대개 다른 버전이 빠진 것입니다 — 추가하세요. hreflang은 두 개 이상의 버전이 서로를 참조할 때만 효과가 있고, 대체 버전이 없는 페이지에는 hreflang이 아예 필요 없습니다. 빨간 표시를 모두 수정한 뒤 다시 생성하세요.

4단계: 필요한 형식으로 출력 복사하기

출력은 두 개의 탭에 담깁니다. HTML link tags는 <head>에 바로 쓸 수 있습니다 — 동일한 블록을 모든 버전에 붙여넣으세요. XML sitemap은 완전한 사이트맵이 아니라 <url> 블록을 출력합니다. 전체 사이트맵의 <urlset> 요소 안에 붙여넣으세요(네임스페이스는 위 참고). 예를 들어 XML 사이트맵 생성기로 만든 기본 파일을 사용할 수 있습니다. Copy code와 Download file 버튼으로 출력을 옮기고, 다국어 head의 나머지 부분은 meta 태그 생성기가 책임집니다.

hreflang에서 흔히 하는 실수와 해결 방법

실수 1: 자기 참조 항목 누락

가장 흔한 오류입니다. 페이지 자신만 빼고 모든 버전을 나열하는 경우죠. Google의 규칙은 정반대입니다 — 모든 버전은 자기 자신과 다른 모든 버전을 나열해야 합니다. 해결: 현재 페이지의 행을 추가하세요.

실수 2: 단방향 어노테이션 (리턴 태그 누락)

독일어 페이지가 영어 페이지를 나열했는데 반대 방향은 추가하지 않은 경우입니다 — Google은 단방향 쌍을 무시합니다. 해결: 모든 버전에 동일한 세트를 넣고, 출시나 URL 변경 후에는 양쪽을 다시 확인하세요.

실수 3: 잘못되거나 순서가 틀린 코드

en-UK, es-419, gb-en, 지역만 단독으로 쓴 코드 — Google은 유효하지 않은 지역이나 형식이 틀린 코드를 조용히 무시해서 클러스터의 그 부분을 사용 불가로 만듭니다. 해결: 언어가 먼저(ISO 639-1), 지역이 그다음(ISO 3166-1 Alpha 2). 생성기가 코드를 실시간으로 검증합니다.

실수 4: canonical과 충돌하는 hreflang

각 버전은 자기 참조 canonical을 가져야 합니다. 독일어 페이지의 canonical이 영어 페이지를 가리키면, hreflang이 그 페이지를 대등한 대체 버전으로 부르는 바로 그 순간 중복이라고 선언하는 셈입니다 — 이렇게 상충하는 신호는 세트 전체가 작동을 멈추게 만들 수 있습니다. 해결: 모든 페이지에 self-canonical을 두고, 그룹화는 hreflang에 맡기세요.

실수 5: 세트 안의 리디렉션 URL 또는 상대 URL

대체 URL은 반드시 완전한 절대 URL이어야 합니다 — https://example.com/de/처럼 쓰고 /de/나 //example.com/de/는 쓰지 마세요 — 그리고 리디렉션 체인이 아니라 200을 반환해야 합니다. 다른 곳으로 301 리디렉션되는 de-DE 항목은 Google이 먼저 체인을 해석하게 만듭니다. 점검 시 리디렉션 체인 검사기로 URL을 확인하고, 렌더링된 소스에서 태그가 잘 구성된 head 안에 있는지 확인하세요.

자주 묻는 질문

hreflang 태그가 순위를 높여 주나요?

직접적으로는 아닙니다 — hreflang은 순위 상승 요소가 아니라 Google이 올바른 버전을 제공하도록 돕는 라우팅 신호입니다. 이득은 간접적이지만 분명합니다. 중복 버전끼리 경쟁하는 일이 줄고, 사용자가 자기 언어로 된 페이지에 도착합니다.

hreflang 태그는 반드시 head 안에 넣어야 하나요?

HTML 방식을 쓸 때만 그렇습니다 — 이 방식에서는 태그가 잘 구성된 head 안에 들어가야 하고, head 마크업을 제어할 수 없다면 사이트맵 방식과 HTTP 헤더 방식이 동등한 대안입니다.

x-default는 필수인가요?

아니요. 선택 사항이며 언어 선택 페이지와 자동 리디렉션 홈페이지에서 가장 잘 작동합니다. 그 외 대부분 사이트는 기본 언어 버전을 가리키는데, 이 역시 안전한 패턴입니다.

hreflang URL은 서로 다른 도메인에 있어도 되나요?

네 — 대체 URL이 도메인을 공유할 필요는 없습니다. 그래서 example.de나 example.co.jp 같은 ccTLD에서 hreflang이 표준입니다. ccTLD나 국가별 서브도메인은 Google에 지리적 힌트를 줄 뿐, 어떤 URL이 서로의 대체 버전인지는 알려 주지 않습니다. 모든 버전을 명시적으로 매핑하세요.

hreflang 태그는 어떻게 확인하고, 수정에는 얼마나 걸리나요?

각 버전의 렌더링된 소스를 보고 자기 참조를 포함한 전체 세트가 head 안에 있는지 확인하세요. 서드파티 hreflang 테스터가 실제 페이지를 검증합니다(Google은 Aleyda Solis의 생성기와 Merkle hreflang 테스터를 언급합니다). 크롤러를 쓰면 사이트 전체 검사로 확장할 수 있습니다. Search Console의 International Targeting 리포트는 2022년에 폐지되어 전용 hreflang 오류 리포트는 더 이상 없습니다. 수정 사항은 클러스터의 모든 URL이 다시 크롤링될 때 적용됩니다 — 보통 며칠에서 몇 주 걸립니다.

en-US와 en-GB처럼 같은 언어 페이지에도 hreflang을 쓸 수 있나요?

네 — Google의 공식 사용 사례에도 한 언어의 지역 변형이 포함됩니다. 미국, 영국, 아일랜드를 각각 타깃하는 영어 콘텐츠가 그렇습니다. 번역은 필요하지 않습니다. 태그는 Google에 어느 지역 변형을 보여 줄지 알려 줄 뿐이며, 차이가 통화나 배송 정보뿐인 경우도 있습니다.

세트의 한 버전이 noindex이거나 차단되어 있으면 어떻게 되나요?

클러스터의 모든 URL은 크롤링과 색인이 가능해야 합니다. noindex이거나 차단된 페이지는 대체 버전으로 표시될 수 없고, 죽은 항목 하나가 나머지 연결까지 약화시킵니다. 차단을 해제하거나, 모든 페이지의 세트에서 그 버전을 빼세요.

hreflang URL은 canonical URL과 정확히 일치해야 하나요?

그래야 합니다. 각 항목은 해당 버전의 canonical이 가리키는 URL을 나열합니다 — 프로토콜, 호스트, 트레일링 슬래시까지 같아야 합니다. 항목은 완전한 절대 URL이어야 하고, 정규 URL이 아닌 대상(트래킹 매개변수, 잘못 붙은 트레일링 슬래시)은 Google이 쌍을 만들기 전에 중복을 먼저 해석하게 만듭니다. 정확히 일치하는 URL과 self-canonical이 클러스터를 깨끗하게 유지합니다.