hugo site 다국어 지원하기
요약: Hugo 다국어 블로그에서 baseURL, sitemap, robots, JSON-LD, Open Graph, meta description을 설정하고 hreflang·canonical로 중복 이슈를 막는 방법을 정리했습니다. slug·translationKey 트러블슈팅까지 한 번에 확인하세요.

목표
Hugo 블로그에 다국어 지원과 SEO 최적화를 적용하여 검색 엔진 노출을 극대화하고 다국어 사용자에게 적절한 언어 버전을 제공한다.
SEO 설정
SEO(Search Engine Optimization, 검색 엔진 최적화)는 Google 등 검색 엔진이 사이트의 콘텐츠를 잘 이해하고 검색 결과에 노출시킬 수 있도록 사이트 구조와 메타데이터를 최적화하는 작업이다.
이 문서는 블로그에 적용된 SEO 설정을 정리한다.
1. 절대 URL - Hugo baseURL 설정
- 파일:
hugo/hugo.toml - 내용:
baseURL = 'https://blog.plzhans.com' - sitemap.xml, RSS 피드, Open Graph 등에서 올바른 절대 URL이 생성됨
- Sitemap (
sitemap.xml), RSS 피드 (index.xml)는 Hugo가 자동 생성 hugo server(개발)에서는 자동으로localhost:1313을 사용하므로 별도 처리 불필요
2. robots.txt 자동 생성
- 파일:
hugo/hugo.toml - 내용:
enableRobotsTXT = true - Hugo 빌드 시
robots.txt자동 생성 (모든 크롤러 허용 + Sitemap URL 포함)
3. Schema.org 구조화 데이터 (JSON-LD)
- 파일:
hugo/layouts/_default/single.html - 글 페이지(
type != "page")에BlogPostingJSON-LD 삽입 - 포함 항목: headline, datePublished, dateModified, author, description, mainEntityOfPage
- Google 검색 결과에서 리치 스니펫(작성자, 날짜 등) 표시 가능
4. og:image (대표 이미지) / Open Graph
- 파일:
src/services/NotionExportService.mjs - Notion 동기화 시 콘텐츠의 첫 번째 이미지를 감지하여 front matter
images필드에 자동 추가 - Open Graph 메타 태그는 Hugo 내장 템플릿(
_internal/opengraph.html)으로 출력되며,images를og:image로 사용
5. meta description / Twitter Card
- 파일:
src/services/NotionExportService.mjs - Notion의 “요약” 프로퍼티를 front matter
description필드로 출력 - Hugo 내장 opengraph/twitter_cards 템플릿 및 baseof.html의 meta description에서 사용
- Twitter Card 메타 태그는 Hugo 내장 템플릿(
_internal/twitter_cards.html)으로 출력 - 기타 메타 태그(author, viewport)도 테마에서 기본 제공
6. Canonical URL
- 파일:
hugo/layouts/_default/baseof.html - 테마(
m10c)의baseof.html을 오버라이드하여<link rel="canonical">태그 추가 .Permalink을 canonical URL로 사용- 다국어 hreflang 태그도 함께 포함 (번역 페이지 존재 시
alternate+x-default출력)
7. Google Analytics (GA4)
- 테마(
m10c)에서 기본 제공 - Google Search Console 인증 시 GA 연동으로 인증 가능
다국어 SEO 핵심 요소
HTML lang 속성
페이지 언어를 명시하여 검색 엔진과 스크린 리더에 언어 정보를 제공한다.
1<html lang="ko">
link rel alternate hreflang
각 언어별 페이지 URL을 검색 엔진에 알려 중복 콘텐츠 문제를 방지한다.
1<link rel="alternate" hreflang="ko" href="https://blog.plzhans.com/ko/post/example/">
2<link rel="alternate" hreflang="en" href="https://blog.plzhans.com/en/post/example/">
3<link rel="alternate" hreflang="ja" href="https://blog.plzhans.com/ja/post/example/">
4<link rel="alternate" hreflang="x-default" href="https://blog.plzhans.com/ko/post/example/">
Canonical URL (다국어)
각 언어를 전문 번역으로 작성했다면 canonical을 생략하여 모든 언어 버전을 독립 원본으로 인정받을 수 있다.
1<link rel="canonical" href="https://blog.plzhans.com/ko/post/example/">
Hugo 다국어 구현
1. 테마 다국어 지원 확인
lang 속성 확인 (themes/{테마}/layouts/_default/baseof.html)
1<!doctype html>
2<html lang=" .Site.Language.Lang ">
relLangURL 지원 확인
홈 링크가 언어별 URL을 유지하는지 확인한다. 미지원 시 baseof.html을 오버라이딩한다.
1<body>
2 <header class="app-header">
3 <a href=" .Site.Home.RelPermalink "><img class="app-header-avatar" src="..." alt="..." /></a>
2. hugo.toml 다국어 설정
1# 기본 콘텐츠 언어
2defaultContentLanguage = "ko"
3# 기본 언어도 서브디렉토리에 포함 (/ko/)
4defaultContentLanguageInSubdir = true
5
6[languages]
7 [languages.ko]
8 weight = 1
9 languageName = "한국어"
10
11 [languages.en]
12 weight = 2
13 languageName = "English"
14
15 [languages.ja]
16 weight = 3
17 languageName = "日本語"
3. canonical 태그 추가
테마가 미지원 시 baseof.html을 오버라이딩한다.
1<link rel="canonical" href=" .Permalink " />
4. hreflang 태그 생성
콘텐츠 파일에 translationKey 설정
1---
2id: "80"
3translationKey: "80"
4slug: "80-redis-dump-vs-aof"
5title: "Redis dump vs aof"
6---
baseof.html에 hreflang 추가 (테마 미지원 시 오버라이딩)
1<link rel="alternate" hreflang=" .Language.Lang " href=" .Permalink " />
2<link rel="alternate" hreflang="x-default" href=" .Permalink " />
트러블슈팅
URL 중복 충돌
Hugo에서 게시물 주소를 설정할 때 url 대신 slug를 사용해야 한다.
원인
slug로 설정하면/ko/,/en/등 언어 접두사가 자동으로 추가됨url로 강제 지정하면 Hugo가 언어 코드를 자동으로 추가하지 않음url사용 시/ko/post/example,/en/post/example처럼 각 언어별로 url 자체에 언어 코드를 직접 넣어줘야 함url에 언어 코드 없이 동일한 경로를 지정하면 서로 다른 언어의 게시물이 동일한 URL을 가지게 되어 충돌 발생
해결
url대신slug사용으로 전환hugo.toml에서defaultContentLanguageInSubdir = true설정하여 기본 언어를 포함한 모든 언어가 서브디렉토리 구조를 갖도록 함
참고
slug만 지정하면 언어 코드는 자동 추가되지만, slug 자체가 특정 언어로 작성된 경우 각 언어별로 번역해야 한다. slug는 영어로 작성하는 것을 권장한다.
translationKey 추가했으나 hreflang 미생성
원인
- 테마가 hreflang 태그 생성을 지원하지 않음.
해결
- baseof.html에 hreflang 관련 코드를 오버라이딩하여 추가