TL;DR - 핵심 요약
- URL 구조는 서브디렉토리(Subdirectory) 방식(
/ko/,/en/,/ja/)이 도메인 권위를 통합하여 20-30% 랭킹 개선 효과 - hreflang에서 한국어 코드는
"kr"이 아니라"ko"— 가장 흔한 실수이며, 잘못 설정하면 Google이 완전히 무시 - 네이버는 hreflang을 지원하지 않음 — 한국어 버전을 네이버 서치어드바이저에 별도 등록 필수
- Google International Targeting report는 2022년 폐지 — 현재는 hreflang과 Search Console 도메인 속성으로 관리
- Next.js 정적 내보내기(
output: "export")에서는 미들웨어가 작동하지 않음 —[locale]동적 세그먼트 +next-intl패턴 사용 - CDN 없이 싱가포르 서버를 쓰면 한국 사용자에게 50-80ms, 일본 사용자에게 80-120ms 지연 추가 — Cloudflare 무료 티어만으로 해결 가능
다국어 사이트, 왜 기술 SEO가 먼저인가
한/영/일 다국어 사이트를 만들 때 가장 먼저 마주치는 질문은 "번역을 어떻게 할까"입니다. 하지만 실제로 더 큰 문제는 번역 이전에 있습니다. URL 구조를 잘못 잡으면 도메인 권위가 분산되고, hreflang 한 글자 틀리면 Google이 언어 버전을 인식하지 못하며, canonical URL 설정이 빠지면 중복 콘텐츠로 판정됩니다.
이 글은 한국어, 영어, 일본어 3개 언어 사이트를 기술적으로 올바르게 구축하는 방법을 다룹니다. 번역 품질이나 콘텐츠 전략이 아닌, 검색엔진이 다국어 사이트를 정확히 이해하도록 만드는 기술 설정에 집중합니다.
1. URL 구조 선택: 서브디렉토리 vs ccTLD vs 서브도메인
다국어 사이트의 URL 구조는 세 가지 선택지가 있습니다.
| 방식 | 예시 | 도메인 권위 | 구현 난이도 | 비용 |
|---|---|---|---|---|
| 서브디렉토리 | example.com/ko/, /en/, /ja/ | 통합 (하나의 도메인) | 낮음 | 낮음 |
| ccTLD | example.kr, example.com, example.jp | 분산 (각각 별도) | 높음 | 높음 |
| 서브도메인 | ko.example.com, en.example.com | 부분 분산 | 중간 | 중간 |
서브디렉토리를 권장하는 이유
Backlinko의 1,180만 검색 결과 분석과 SE Ranking의 2만 키워드 연구에 따르면, 서브디렉토리 방식은 ccTLD나 서브도메인 대비 20-30% 랭킹 개선 효과를 보였습니다. 이유는 단순합니다 — 하나의 도메인에 백링크, 콘텐츠, 사용자 신호가 집중되기 때문입니다.
출처: Backlinko - Search Engine Ranking Study · SE Ranking - Subdirectory vs Subdomain
Google 공식 문서에서는 세 가지 방식을 모두 동등하게 처리한다고 명시합니다. 그러나 실무에서는 도메인 권위 통합 효과가 서브디렉토리에서 가장 뚜렷합니다.
Samsung, Hyundai, LG 등 한국 대기업들도 서브디렉토리 방식을 사용합니다(samsung.com/kr/, samsung.com/us/, samsung.com/jp/).
ccTLD의 약화 추세
2025년 4월, Google은 자사 ccTLD(google.co.kr, google.co.jp 등)를 google.com으로 통합하는 작업을 진행했습니다. ccTLD가 지역 신호로서의 의미를 잃어가고 있다는 방증입니다. 새로 다국어 사이트를 구축한다면, ccTLD보다 서브디렉토리가 미래 지향적인 선택입니다.
2. hreflang 구현: 검색엔진에 언어 버전 알리기
hreflang(Hreflang)은 Google에 "이 페이지의 한국어/영어/일본어 버전이 각각 여기에 있다"고 알려주는 HTML 속성입니다.
핵심 규칙
- 모든 페이지가 자기 자신을 포함해야 합니다 — 한국어 페이지의 hreflang에 한국어 URL도 반드시 포함
- 상호 참조가 필수입니다 — 한국어 → 영어를 선언했으면, 영어 → 한국어도 선언해야 함
x-default를 설정합니다 — 매칭되는 언어가 없는 사용자를 위한 기본 페이지
가장 흔한 실수: "kr" vs "ko"
hreflang에서 한국어를 지정할 때 "kr"을 사용하는 사이트가 매우 많습니다. 이것은 틀린 코드입니다.
ko= 언어 코드 (ISO 639-1) — hreflang에 사용kr= 국가 코드 (ISO 3166-1) — hreflang의 지역 지정에만 사용
<!-- 틀린 설정 — Google이 무시함 -->
<link rel="alternate" hreflang="kr" href="https://example.com/ko/" />
<!-- 올바른 설정 -->
<link rel="alternate" hreflang="ko" href="https://example.com/ko/" />
<!-- 언어 + 지역을 함께 쓸 때 -->
<link rel="alternate" hreflang="ko-KR" href="https://example.com/ko/" />
일본어도 마찬가지입니다. jp가 아니라 ja입니다.
HTML <head> 구현 방식
정적 사이트나 페이지 수가 적은 경우, HTML <head>에 직접 삽입하는 것이 가장 간단합니다.
<head>
<!-- 한국어 페이지에서 -->
<link rel="alternate" hreflang="ko" href="https://example.com/ko/about/" />
<link rel="alternate" hreflang="en" href="https://example.com/en/about/" />
<link rel="alternate" hreflang="ja" href="https://example.com/ja/about/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/en/about/" />
</head>
영어 페이지와 일본어 페이지에도 동일한 4줄이 들어가야 합니다. 상호 참조가 없으면 Google은 hreflang을 무시합니다.
XML 사이트맵 구현 방식
페이지 수가 많은 경우, XML 사이트맵에 hreflang을 포함하는 것이 관리하기 편합니다.
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>https://example.com/ko/about/</loc>
<xhtml:link rel="alternate" hreflang="ko"
href="https://example.com/ko/about/" />
<xhtml:link rel="alternate" hreflang="en"
href="https://example.com/en/about/" />
<xhtml:link rel="alternate" hreflang="ja"
href="https://example.com/ja/about/" />
<xhtml:link rel="alternate" hreflang="x-default"
href="https://example.com/en/about/" />
</url>
<url>
<loc>https://example.com/en/about/</loc>
<xhtml:link rel="alternate" hreflang="ko"
href="https://example.com/ko/about/" />
<xhtml:link rel="alternate" hreflang="en"
href="https://example.com/en/about/" />
<xhtml:link rel="alternate" hreflang="ja"
href="https://example.com/ja/about/" />
<xhtml:link rel="alternate" hreflang="x-default"
href="https://example.com/en/about/" />
</url>
<url>
<loc>https://example.com/ja/about/</loc>
<xhtml:link rel="alternate" hreflang="ko"
href="https://example.com/ko/about/" />
<xhtml:link rel="alternate" hreflang="en"
href="https://example.com/en/about/" />
<xhtml:link rel="alternate" hreflang="ja"
href="https://example.com/ja/about/" />
<xhtml:link rel="alternate" hreflang="x-default"
href="https://example.com/en/about/" />
</url>
</urlset>
각 <url> 블록 안에 모든 언어 버전을 상호 참조하는 것이 핵심입니다. 하나라도 빠지면 해당 쌍의 hreflang이 작동하지 않습니다.
네이버와 hreflang
네이버는 hreflang을 지원하지 않습니다. 네이버는 자체 크롤링 로직으로 언어를 판단하며, hreflang 태그를 해석하지 않습니다. 한국어 버전의 네이버 노출이 필요하다면, 한국어 사이트를 네이버 서치어드바이저에 별도로 등록하고 사이트맵과 RSS를 제출해야 합니다.
3. 언어별 기술 SEO 설정
다국어 사이트에서 놓치기 쉬운 것이 언어별로 독립적인 기술 SEO 요소입니다.
canonical URL: 언어별로 각각 지정
각 언어 페이지는 자기 자신의 URL을 canonical로 지정해야 합니다. 한국어 페이지의 canonical이 영어 페이지를 가리키면, Google은 한국어 페이지를 중복으로 판단하고 색인에서 제외합니다.
<!-- /ko/about/ 페이지 -->
<link rel="canonical" href="https://example.com/ko/about/" />
<!-- /en/about/ 페이지 -->
<link rel="canonical" href="https://example.com/en/about/" />
<!-- /ja/about/ 페이지 -->
<link rel="canonical" href="https://example.com/ja/about/" />
이미지 alt 텍스트 번역
이미지 alt 텍스트는 접근성뿐 아니라 이미지 검색 SEO에 직접 영향을 줍니다. 언어별로 반드시 번역해야 합니다.
<!-- 한국어 -->
<img src="/images/seo-audit.png" alt="SEO 기술 진단 대시보드 화면" />
<!-- 영어 -->
<img src="/images/seo-audit.png" alt="SEO technical audit dashboard screenshot" />
<!-- 일본어 -->
<img src="/images/seo-audit.png" alt="SEO技術監査ダッシュボードの画面" />
XML 사이트맵 전략
두 가지 접근이 가능합니다.
| 전략 | 설명 | 권장 상황 |
|---|---|---|
| 단일 사이트맵 + hreflang | 하나의 sitemap.xml에 모든 언어 URL과 hreflang 포함 | 페이지 수 적음 (500개 미만) |
| 언어별 사이트맵 | /ko/sitemap.xml, /en/sitemap.xml, /ja/sitemap.xml 분리 | 페이지 수 많음, 업데이트 빈도 다름 |
어떤 방식이든 Google Search Console에는 하나의 도메인 속성(example.com)으로 등록하면 됩니다. hreflang이 올바르게 설정되어 있으면 Google이 언어 변형을 자동 인식합니다.
Google Search Console 설정
이전에 존재했던 International Targeting report는 2024년에 폐지되었습니다. 현재는 hreflang 설정이 유일한 국제 타게팅 수단입니다. Search Console에서 확인할 수 있는 것은 다음과 같습니다.
- URL 검사 도구: 특정 URL의 hreflang 인식 여부 확인
- 색인 생성 범위 보고서: 언어별 색인 상태 확인
- 실적 보고서: 국가별 필터로 각 언어 버전의 트래픽 분석
4. 콘텐츠 현지화: 번역이 아닌 적응
기계적 번역만으로는 다국어 SEO가 완성되지 않습니다. 각 언어권 사용자의 검색 행동과 콘텐츠 소비 패턴이 다릅니다.
검색 키워드의 차이
같은 주제라도 각 언어에서 사용하는 검색어가 다릅니다.
| 개념 | 한국어 검색어 | 영어 검색어 | 일본어 검색어 |
|---|---|---|---|
| SEO 최적화 | "SEO 최적화", "검색엔진 최적화" | "SEO optimization", "search engine optimization" | "SEO対策", "検索エンジン最適化" |
| 속도 최적화 | "사이트 속도 개선" | "page speed optimization" | "ページ速度改善", "サイト高速化" |
| 기술 SEO | "기술 SEO", "테크니컬 SEO" | "technical SEO" | "テクニカルSEO", "SEO技術対策" |
일본어에서 "SEO対策"(SEO 대책)은 영어의 "SEO"보다 훨씬 높은 검색량을 가집니다. 단순히 키워드를 번역하면 실제 검색 수요와 맞지 않습니다.
날짜 형식
한국어: 2026년 5월 21일
영어: May 21, 2026
일본어: 2026年5月21日
콘텐츠 스타일 차이
| 요소 | 한국어 | 영어 | 일본어 |
|---|---|---|---|
| 문단 길이 | 중간 | 짧고 스캐닝 가능 | 길고 상세한 설명 |
| 어조 | 전문적 존댓말 (~합니다) | 직접적, 행동 중심 | 경어(Keigo) 필수, 4가지 문자 체계 혼용 |
| CTA 스타일 | "무료 진단 신청" | "Get Started Free" | "無料診断のお申し込み" |
| 기대 정보량 | 핵심 위주 | 요점 위주, 간결 | 배경 설명 포함, 상세 |
일본어 콘텐츠에서 경어(Keigo)를 빠뜨리면 신뢰도가 크게 하락합니다. 또한 일본 사용자는 영어권 대비 더 상세한 설명과 배경 정보를 기대합니다. "간결함이 미덕"인 영어 콘텐츠를 그대로 일본어로 번역하면, 정보가 부족하다는 인상을 줍니다.
5. Next.js App Router에서 다국어 구현
Next.js App Router에서 다국어를 구현하는 실무 패턴을 다룹니다. 특히 정적 내보내기(output: "export")를 사용하는 경우의 제약사항에 주의해야 합니다.
프로젝트 구조
src/
├── app/
│ └── [locale]/
│ ├── layout.tsx
│ ├── page.tsx
│ └── about/
│ └── page.tsx
├── i18n/
│ ├── request.ts
│ └── routing.ts
└── messages/
├── ko.json
├── en.json
└── ja.json
next-intl 설정 (정적 내보내기 호환)
next.config.ts:
import createNextIntlPlugin from 'next-intl/plugin';
const withNextIntl = createNextIntlPlugin();
const nextConfig = {
output: 'export', // 정적 내보내기
};
export default withNextIntl(nextConfig);
src/i18n/routing.ts:
import { defineRouting } from 'next-intl/routing';
export const routing = defineRouting({
locales: ['ko', 'en', 'ja'],
defaultLocale: 'ko',
});
src/i18n/request.ts:
import { getRequestConfig } from 'next-intl/server';
import { routing } from './routing';
export default getRequestConfig(async ({ requestLocale }) => {
let locale = await requestLocale;
if (!locale || !routing.locales.includes(locale as 'ko' | 'en' | 'ja')) {
locale = routing.defaultLocale;
}
return {
locale,
messages: (await import(`../messages/${locale}.json`)).default,
};
});
정적 파라미터 생성
src/app/[locale]/layout.tsx:
import { NextIntlClientProvider } from 'next-intl';
import { getMessages } from 'next-intl/server';
import { routing } from '@/i18n/routing';
export function generateStaticParams() {
return routing.locales.map((locale) => ({ locale }));
}
export default async function LocaleLayout({
children,
params,
}: {
children: React.ReactNode;
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
const messages = await getMessages();
return (
<html lang={locale}>
<body>
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
);
}
hreflang 메타데이터 생성
개별 페이지 레벨에서 생성합니다 (레이아웃이 아닌 page.tsx에서). Next.js App Router에서 metadata는 세그먼트별로 평가되므로, hreflang alternate URL에 전체 경로를 포함해야 합니다:
// src/app/[locale]/blog/[slug]/page.tsx
import type { Metadata } from 'next';
export async function generateMetadata({
params,
}: {
params: Promise<{ locale: string; slug: string }>;
}): Promise<Metadata> {
const { locale, slug } = await params;
const baseUrl = 'https://example.com';
const path = `/blog/${slug}`;
return {
alternates: {
canonical: `${baseUrl}/${locale}${path}`,
languages: {
ko: `${baseUrl}/ko${path}`,
en: `${baseUrl}/en${path}`,
ja: `${baseUrl}/ja${path}`,
'x-default': `${baseUrl}/en${path}`,
},
},
};
}
주의: layout.tsx에서 alternates를 설정하면 해당 레이아웃의 경로(/ko, /en, /ja)만 가리키게 되어, 하위 페이지(/ko/blog/seo-guide)의 정확한 alternate URL이 생성되지 않습니다. 반드시 leaf page에서 전체 경로를 포함하여 설정하세요.
정적 내보내기 시 주의사항
output: "export" 설정을 사용하면 미들웨어가 작동하지 않습니다. next-intl의 미들웨어 기반 로케일 감지는 사용할 수 없으며, 대신 generateStaticParams로 모든 로케일 경로를 사전 생성해야 합니다.
루트 경로(/)에서 /ko/로의 리다이렉트는 nginx에서 처리합니다.
# nginx.conf
server {
location = / {
return 302 /ko/;
}
}
6. CDN과 멀티 리전 성능 최적화
다국어 사이트는 물리적으로 다른 지역의 사용자에게 서비스합니다. 서버가 한 곳에 있으면, 원거리 사용자의 TTFB(Time to First Byte)가 크게 증가합니다.
CDN 없이 싱가포르 서버를 쓸 때
| 사용자 위치 | 추가 지연 시간 | 체감 |
|---|---|---|
| 한국 | +50-80ms | LCP에 직접 영향 |
| 일본 | +80-120ms | 모바일에서 체감 가능 |
| 미국 서부 | +150-200ms | CWV 기준 미달 가능 |
Cloudflare 무료 티어로 해결
Cloudflare(Cloudflare)의 무료 티어만으로도 300개 이상의 PoP(Point of Presence)을 활용할 수 있습니다. 서울과 도쿄에 PoP이 있어, 한국과 일본 사용자에게 50ms 미만의 TTFB를 제공할 수 있습니다.
설정은 간단합니다.
- Cloudflare에 도메인 등록
- 네임서버를 Cloudflare로 변경
- 정적 자산에 대해 캐싱 활성화
Cache-Control헤더 설정으로 HTML/CSS/JS 캐시 정책 관리
정적 내보내기(output: "export") 사이트의 경우, 모든 HTML이 정적 파일이므로 CDN 캐싱 효과가 극대화됩니다.
7. 실행 체크리스트
URL 구조
- 서브디렉토리 방식 채택 (
/ko/,/en/,/ja/) - 루트 URL(
/)에서 기본 언어로 리다이렉트 설정 - 모든 내부 링크에 언어 경로 포함 확인
hreflang
- 언어 코드 확인:
ko(한국어),en(영어),ja(일본어) —kr,jp사용 금지 - 모든 페이지에서 자기 자신을 포함한 상호 참조 설정
-
x-default설정 완료 - HTML
<head>또는 XML 사이트맵 중 하나의 방식으로 통일
canonical 및 메타데이터
- 각 언어 페이지에 자기 자신의 canonical URL 설정
- title, meta description 언어별 고유 작성
- 이미지 alt 텍스트 언어별 번역
네이버 대응
- 한국어 사이트를 네이버 서치어드바이저에 별도 등록
- 한국어 XML 사이트맵 및 RSS 피드 제출
- hreflang에 의존하지 않고 네이버 독립 설정 완료
콘텐츠 현지화
- 키워드 리서치를 언어별로 독립 수행
- 날짜, 통화, 단위 형식 현지화
- 일본어 콘텐츠에 경어(Keigo) 적용 확인
성능
- CDN 설정 (Cloudflare 등)
- 각 언어 대상 지역에서 TTFB 50ms 이하 확인
- Core Web Vitals 언어별 측정
자주 묻는 질문 (FAQ)
Q1. hreflang을 설정하면 Google이 자동으로 언어별 검색 결과를 보여주나요?
hreflang은 Google에 "이 페이지의 다른 언어 버전"을 알려주는 힌트입니다. Google은 이를 참고하지만, 반드시 따르지는 않습니다. 사용자의 위치, 검색 언어 설정, 콘텐츠 품질 등을 종합적으로 고려하여 어떤 언어 버전을 보여줄지 결정합니다. hreflang을 올바르게 설정하면 적절한 언어 버전이 노출될 가능성이 높아지지만, 보장은 아닙니다.
Q2. 모든 페이지를 3개 언어로 만들어야 하나요?
아닙니다. 모든 페이지가 3개 언어로 존재할 필요는 없습니다. 한국어로만 의미 있는 콘텐츠(예: 한국 세무 관련)는 한국어로만 유지해도 됩니다. 다만, hreflang은 실제로 존재하는 언어 버전에 대해서만 선언해야 합니다. 존재하지 않는 URL을 hreflang에 포함하면 Google이 전체 hreflang 설정의 신뢰도를 낮게 평가합니다.
Q3. Google International Targeting report가 없어졌는데, 국가 타게팅은 어떻게 하나요?
2024년에 폐지된 International Targeting report를 대체하는 도구는 현재 없습니다. Google은 hreflang 태그와 콘텐츠의 언어 자체를 기반으로 타게팅을 결정합니다. Search Console에서는 도메인 속성으로 등록하면 국가별 실적 데이터를 확인할 수 있고, URL 검사 도구로 개별 페이지의 hreflang 인식 상태를 확인할 수 있습니다.
Q4. 네이버에서 영어/일본어 페이지도 노출되나요?
네이버는 기본적으로 한국어 콘텐츠를 우선 색인합니다. 영어나 일본어 페이지가 네이버에 색인될 수는 있지만, 검색 결과에서 노출 가능성은 매우 낮습니다. 네이버 최적화는 한국어 버전에 집중하고, 영어/일본어 버전은 Google과 해당 언어권 검색엔진에 맡기는 것이 현실적입니다.
Q5. 기계 번역으로 다국어 사이트를 만들어도 SEO에 불이익이 없나요?
Google은 기계 번역 자체를 페널티 대상으로 삼지 않습니다. 그러나 품질이 낮은 번역은 사용자 행동 지표(이탈률, 체류 시간)에 부정적 영향을 주고, 이는 간접적으로 랭킹에 반영됩니다. 특히 일본어는 경어 체계가 복잡하여 기계 번역의 품질 문제가 두드러집니다. 핵심 페이지(랜딩 페이지, 서비스 소개)는 전문 번역 또는 네이티브 검수를 권장합니다. 블로그 콘텐츠는 AI 번역 + 네이티브 검수 조합이 비용 효율적입니다.
마무리
다국어 사이트 SEO의 기술적 토대는 세 가지로 요약됩니다. 첫째, 서브디렉토리로 도메인 권위를 통합하고. 둘째, hreflang으로 검색엔진에 언어 버전을 정확히 알려주고. 셋째, 각 언어별로 독립적인 canonical, 메타데이터, 콘텐츠를 구성하는 것입니다.
기술 설정이 올바르게 되어 있어야 콘텐츠 현지화와 키워드 전략이 제대로 작동합니다. 번역에 투자하기 전에, 이 글의 체크리스트로 기술 토대부터 점검하시기 바랍니다.
다국어 사이트 SEO 진단이 필요하시면 XEO 무료 진단을 신청하세요.