한 페이지에 한 언어: IP 국가 판정과 한/영 병기를 버리고 브라우저 언어 + hreflang 으로 바꾼 이유
웹 서비스 6개의 초기 언어를 정하는 방식이 제각각이었습니다. IP 국가로 정하던 곳은 구글봇에게만 영어가 나가 검색 결과 언어를 통제할 수 없었고, 한/영을 한 페이지에 병기하던 랜딩은 구글이 기대하는 "페이지 하나에 언어 하나" 와 어긋났습니다. 전 웹을 한 규칙으로 통일한 과정을 씁니다.
제각각이던 초기 언어
웹 서비스 6개가 각자 다른 방식으로 첫 언어를 정하고 있었습니다.
- 온라인 도구 디렉토리: Cloudflare 가 붙여 주는
CF-IPCountry헤더로 국가를 보고 한국이면 한국어 - 포트폴리오·쇼케이스: 브라우저 타임존이 서울이면 한국어
- 에러코드 조회: 감지 자체가 없어서 해외 방문자도 한국어
- 루트 랜딩: 한 페이지에 한국어와 영어를 병기
각각 이유는 있었지만 전부 문제가 있었습니다.
IP 국가 판정의 문제
영어 브라우저를 쓰는 한국 거주자가 한국어를 받습니다. 그건 참을 수 있습니다. 진짜 문제는 구글봇입니다. 구글봇은 미국에서 오므로 항상 영어 페이지를 받았습니다. 한국어 검색 결과에 한국어 제목이 나갈 방법이 없었습니다. 검색 결과에 어떤 언어가 나갈지를 서버가 통제하지 못하는 구조였습니다. langFromCountry() 함수를 지웠습니다.
타임존 판정도 같은 이유로 버렸습니다. 클라이언트에서 JS 로 판정하면 크롤러가 보는 첫 HTML 은 판정 전 상태입니다.
병기의 문제
루트 랜딩은 한 페이지에 한국어 문단과 영어 문단을 나란히 두고 있었습니다. 처음 광고 심사에서 "본문이 짧다"는 오진을 하고 분량을 늘리려다 그렇게 된 것으로 추정합니다. 그런데 구글은 페이지 하나에 언어 하나를 기대합니다. 병기된 페이지는 어느 언어 결과에 넣을지 애매하고, lang 속성도 하나만 줄 수 있습니다.
통일한 규칙
2026년 8월 11일에 전 웹 공통 표준으로 정하고, 8월 28일에 예외였던 루트까지 맞췄습니다.
- 초기 언어는 브라우저 언어.
Accept-Language가ko*면 한국어, 그 외는 영어. 서버 렌더링(SSR) 사이트는 헤더로, 정적 사이트는 첫 로드 JS 로 판정하되 어느 쪽이든 각 언어가 자기 URL 을 가집니다. - 언어마다 URL 을 따로 둡니다.
/= 한국어(lang="ko"),/en/= 영어(lang="en"). 변환기 웹도/mdhtml/와/mdhtml/en/로 나눴습니다. - 양쪽 페이지에
hreflang을 서로 걸고x-default는 한국어로, 각자 self canonical 과og:locale을 둡니다. - 헤더에 언어 전환 링크를 둡니다. 자동 판정이 틀렸을 때 사용자가 한 번에 바꿀 수 있어야 합니다.
- 사이트맵에 두 URL 을 모두 넣습니다.
루트는 병기본을 원본으로 두고, 카드 22장(앱 16 + 웹 6)의 한국어·영어 문장을 분리해 두 페이지를 생성하는 스크립트로 만들었습니다. 병기본은 백업으로만 남깁니다.
폰트도 같이 통일
같은 날 폰트도 하나로 정리했습니다. Pretendard 가변 폰트의 동적 서브셋 CSS 하나만 씁니다. 포트폴리오의 Geist, 쇼케이스 제목의 Clash Display, 디렉토리의 Inter + Space Grotesk, 변환기의 Roboto + Noto Sans KR 을 전부 걷어냈습니다. 페이지마다 폰트가 다르면 한 사이트로 보이지 않습니다.
예외는 코드용 고정폭 폰트입니다. Pretendard 는 가변폭이라 코드 정렬이 깨지고, 웹 SSH 는 xterm.js 터미널이라 고정폭이 아니면 화면이 망가집니다. JetBrains Mono 는 유지합니다.
확인
라이브에서 curl -H "Accept-Language: en" 과 ko 로 각각 받아 <html lang> 과 첫 문단 언어를 확인했고, 두 페이지의 hreflang 이 서로를 가리키는지, 사이트맵에 둘 다 있는지 봤습니다. 검색 결과 반영은 재크롤 뒤의 일이라 기다립니다.
정리
- IP 국가 판정은 구글봇에게 항상 한 언어만 보여 줍니다. 버립니다.
- 한 페이지 한 언어. 언어마다 URL 과
lang, hreflang, canonical. - 초기 언어는 브라우저 언어, 전환 링크는 헤더에.
- 폰트도 사이트 전체에서 하나. 코드용 고정폭만 예외.