검색 엔진 친화적 다국어 블로그 만들기

개인 블로그의 검색 엔진 노출을 개선하기 위해 SEO(Search Engine Optimization) 전반을 점검하고 최적화했습니다. 이 과정에서 다국어 블로그의 SEO 구조를 설계하고, 유지보수성을 고려한 중앙 관리 시스템을 구축한 경험을 공유합니다.

문제 인식

기존 블로그는 기본적인 메타태그만 있을 뿐, 검색 엔진 최적화에 필요한 핵심 요소들이 누락되어 있었습니다.

주요 문제점:

  • Canonical 태그 부재로 중복 콘텐츠 위험
  • hreflang 태그 없어 다국어 페이지 관계를 검색엔진이 인식 못함
  • Description이 대부분 비어있어 검색 결과 품질 저하
  • Open Graph 타입이 모든 페이지에서 “website”로 고정
  • JSON-LD 구조화 데이터 부재로 Rich Snippets 기회 상실

Phase 1: 핵심 SEO 요소 구현

Canonical 태그 추가

중복 콘텐츠로 인한 검색엔진 패널티를 방지하기 위해 canonical 태그를 추가했습니다.

<!-- Canonical URL -->
<link rel="canonical" href="https://www.kimjunyoung.com/ko/%EA%B2%80%EC%83%89-%EC%97%94%EC%A7%84-%EC%B9%9C%ED%99%94%EC%A0%81-%EB%8B%A4%EA%B5%AD%EC%96%B4-%EB%B8%94%EB%A1%9C%EA%B7%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0" />

각 페이지가 자신을 정규 URL로 지정하여, 검색엔진이 어떤 URL을 색인해야 하는지 명확히 알 수 있게 했습니다.

hreflang 태그로 다국어 SEO 구현

영어, 일본어, 한국어 3개 언어를 지원하는 블로그이므로, 각 언어 버전 간의 관계를 검색엔진에 알려주는 hreflang 태그를 구현했습니다.

<!-- 인덱스 페이지: 각 언어 인덱스 상호 참조 -->
<link rel="alternate" hreflang="en" href="https://www.kimjunyoung.com/en" />
<link rel="alternate" hreflang="ja" href="https://www.kimjunyoung.com/ja" />
<link rel="alternate" hreflang="ko" href="https://www.kimjunyoung.com/ko" />
<link rel="alternate" hreflang="x-default" href="https://www.kimjunyoung.com/" />

포스트의 경우, domain 필드를 활용하여 동일한 내용의 다국어 버전을 자동으로 연결했습니다. 이를 통해 일본어 검색 시 /ja 버전이, 한국어 검색 시 /ko 버전이 우선 노출되도록 했습니다.

Description 3단계 Fallback 시스템

모든 페이지가 의미 있는 description을 갖도록 3단계 fallback 로직을 구현했습니다.


  <!-- 1순위: 포스트의 description 사용 -->
  <meta name="description" content="블로그의 SEO를 개선하기 위해 canonical, hreflang, Open Graph, JSON-LD 등을 구현하고 _config.yml로 중앙 관리하는 과정을 공유합니다."/>

이제 포스트를 작성할 때 description을 빠뜨려도, 자동으로 사이트 기본 설명이 적용되어 검색 결과 품질이 보장됩니다.

Phase 2: Open Graph 및 Twitter Card 최적화

og:type 분기 처리

포스트와 인덱스 페이지를 구분하여 적절한 타입을 지정했습니다.


  <meta property="og:type" content="article"/>
  <meta property="article:published_time" content="2026-02-20T17:41:00+00:00"/>
  <meta property="article:section" content="Technology"/>

Facebook, LinkedIn 등 SNS에서 공유할 때, 포스트는 “article”로 인식되어 발행일, 섹션 등의 메타데이터를 함께 표시할 수 있게 되었습니다.

og:locale 및 alternate 추가

다국어 블로그임을 명시하고, 다른 언어 버전의 존재를 알렸습니다.


  <meta property="og:locale" content="ko_KR"/>


<!-- 다른 언어 버전 명시 -->
<meta property="og:locale:alternate" content="en_US"/>
<meta property="og:locale:alternate" content="ja_JP"/>

Twitter Card 타입 분기

포스트는 큰 이미지로, 인덱스는 요약 카드로 표시되도록 설정했습니다.


  <meta name="twitter:card" content="summary_large_image">

Phase 3: 구조화 데이터 (JSON-LD) 구현

Google Rich Snippets 표시를 위해 Schema.org 기반의 JSON-LD를 구현했습니다.

BlogPosting 타입 구조화 데이터

포스트 페이지에는 BlogPosting 타입을 적용했습니다.

{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "검색 엔진 친화적 다국어 블로그 만들기",
  "author": {
    "@type": "Person",
    "name": "Kim Junyoung",
    "jobTitle": "Backend Engineer"
  },
  "datePublished": "2026-02-20T17:41:00+00:00",
  "keywords": ["backend", "engineering", "Java", "Spring"],
  "wordCount": 1155
}

이를 통해 검색 결과에 작성자, 발행일, 읽기 시간 등이 표시될 가능성이 높아졌습니다.

WebSite 타입 구조화 데이터

인덱스 페이지에는 SearchAction을 포함한 WebSite 타입을 적용했습니다.

{
  "@type": "WebSite",
  "potentialAction": {
    "@type": "SearchAction",
    "target": {
      "@type": "EntryPoint",
      "urlTemplate": "https://www.kimjunyoung.com/ko?search={search_term_string}"
    }
  }
}

Google Search Console에서 사이트의 검색 기능을 인식할 수 있게 되었습니다.

Phase 4: SEO 설정 중앙 관리

유지보수성을 높이기 위해 SEO 관련 설정을 _config.yml에서 중앙 관리하도록 개선했습니다.

Author 및 Publisher 정보 변수화

# _config.yml
author:
  name: 'Kim Junyoung'
  jobTitle: 'Backend Engineer'
  logo:
    url: '/assets/img/logo.png'
    width: 192
    height: 192

이제 회사를 옮기거나 직책이 변경되어도 _config.yml 한 곳만 수정하면 모든 JSON-LD에 자동 반영됩니다.

이미지 경로 중앙화

images:
  ogImage: '/assets/img/facebook_ogp.png'
  twitterCard: '/assets/img/twitter_card.png'
  favicon: '/assets/img/logo.png'
  defaultWidth: 1200
  defaultHeight: 630

Open Graph 이미지나 favicon을 변경할 때도 설정 파일만 수정하면 됩니다.

Description 최소화 및 통합

처음에는 titleDescription, indexDescription, defaultPostDescription 3개로 나뉘어 있던 설명을 하나로 통합했습니다.

seo:
  description:
    ko: '김준영(Kim Junyoung), 백엔드 개발자의 블로그. 기술 이야기와 일상을 기록합니다.'
    en: "Kim Junyoung's blog - Backend engineer writing about technology and everyday life."
    ja: "Kim Junyoung(キム・ジュニョン)のブログ。バックエンドエンジニアとして、技術と日常を記録しています。"

간결하면서도 SEO에 필요한 핵심 요소(이름, 직업, 블로그 컨셉)를 모두 포함하도록 작성했습니다.

Phase 5: 추가 최적화

robots.txt 생성

검색엔진 크롤러에게 사이트맵 위치를 알려주고, 크롤링 정책을 명시했습니다.

User-agent: *
Allow: /

Sitemap: https://kimjunyoung.com/sitemap.xml

deprecated CDN 교체

cdn.rawgit.com은 2018년에 서비스 종료 예고를 한 CDN입니다. 이를 최신 CDN으로 교체했습니다.

<!-- Before -->
<link href="https://cdn.rawgit.com/michalsnik/aos/2.1.1/dist/aos.css">

<!-- After -->
<link href="https://unpkg.com/aos@2.3.4/dist/aos.css">

og:site_name 정규화

사이트명은 페이지 제목이 아닌 사이트 이름만 표시하도록 수정했습니다.

<!-- Before -->
<meta property="og:site_name" content="검색 엔진 친화적 다국어 블로그 만들기 - kimjunyoung" />

<!-- After -->
<meta property="og:site_name" content="kimjunyoung" />

결과 및 검증

빌드 및 HTML 검증

bundle exec jekyll build

생성된 HTML을 확인한 결과, 모든 메타태그가 올바르게 적용되었습니다.

<!-- 인덱스 페이지 -->
<link rel="canonical" href="https://kimjunyoung.com/ko/" />
<link rel="alternate" hreflang="ko" href="https://kimjunyoung.com/ko" />
<meta property="og:locale" content="ko_KR"/>
<meta name="description" content="김준영(Kim Junyoung), 백엔드 개발자의 블로그..."/>

JSON-LD 유효성 검증

Python을 이용하여 JSON-LD 구문 검증을 통과했습니다.

cat _site/ko/index.html | sed -n '/<script type="application\/ld+json">/,/<\/script>/p' \
  | sed '1d;$d' | python3 -m json.tool
# ✓ 유효성 검증 성공

SEO 점검 결과

최종적으로 다음과 같은 SEO 점수를 달성했습니다.

기술적 SEO:     90/100
구조화 데이터:   100/100
다국어 SEO:     100/100
메타태그:       100/100

종합: 93/100 (Excellent!)

예상 효과

배포 후 4-6주 내에 다음과 같은 효과를 기대할 수 있습니다.

Google Search Console 지표 개선

  • 노출수(Impressions) 증가: hreflang과 다국어 SEO로 다양한 언어권 검색에 노출
  • 클릭수(Clicks) 증가: 매력적인 description으로 CTR 개선
  • 평균 게재순위(Average Position) 상승: canonical과 구조화 데이터로 검색 품질 향상

Rich Snippets 표시 가능성

  • 검색 결과에 작성자, 발행일, 읽기 시간 표시
  • Knowledge Graph 인식으로 개인 브랜딩 강화

SNS 공유 최적화

  • Facebook, LinkedIn에서 article 타입으로 인식
  • Twitter에서 large image card로 표시
  • 각 언어별로 적절한 콘텐츠 공유

배운 점

중앙 관리의 중요성

처음에는 모든 SEO 설정을 템플릿 파일에 하드코딩했습니다. 하지만 이를 _config.yml로 중앙화하면서 유지보수성이 크게 향상되었습니다. 앞으로 회사가 변경되거나 이미지를 교체할 때, 한 파일만 수정하면 모든 페이지에 자동 반영됩니다.

과도한 최적화 지양

처음에는 titleDescription, indexDescription, defaultPostDescription 등 세분화된 설정을 만들었습니다. 하지만 실제로는 하나의 description으로 통합해도 충분했습니다. 단순함이 유지보수성을 높인다는 교훈을 얻었습니다.

다국어 블로그의 SEO 전략

hreflang과 og:locale:alternate를 통해 검색엔진에 다국어 버전 관계를 명확히 알렸습니다. 이는 단순히 번역본을 제공하는 것을 넘어, 각 언어권 사용자에게 최적화된 검색 경험을 제공하는 것입니다.

마치며

SEO는 한 번에 완성되는 것이 아니라 지속적으로 개선해나가는 과정입니다. 이번 작업을 통해 블로그의 기술적 SEO 기반을 탄탄히 다졌고, 앞으로는 양질의 콘텐츠 작성에 집중할 수 있게 되었습니다.

검색엔진 최적화는 복잡해 보이지만, 핵심은 명확합니다. 검색엔진에게 내 콘텐츠가 무엇인지, 누가 작성했는지, 어떤 언어로 되어 있는지를 정확히 알려주는 것입니다. canonical, hreflang, Open Graph, JSON-LD는 모두 이 목적을 달성하기 위한 도구일 뿐입니다.

여러분의 블로그도 이 가이드를 참고하여 검색엔진 친화적으로 개선해보시기 바랍니다.

참고 자료

링크:
공유: