多语言支持
Hugo 的多语言支持允许您为每个语言和地区提供本地化的内容、图片、日期、货币、数字、百分比和排序规则。Hugo 的多语言框架支持单主机和多主机配置。
基础配置
核心设置
在站点根配置文件中配置多语言基础设置:
# hugo.toml
defaultContentLanguage = 'zh'
defaultContentLanguageInSubdir = false
enableMissingTranslationPlaceholders = false
languageCode = 'zh-CN'
[languages]
[languages.zh]
baseURL = 'https://example.com'
languageName = '中文'
title = '我的网站'
weight = 1
[languages.en]
baseURL = 'https://en.example.com'
languageName = 'English'
title = 'My Website'
weight = 2
配置选项详解
defaultContentLanguage
定义默认内容语言的代码:
defaultContentLanguage = 'zh'
defaultContentLanguageInSubdir
控制默认语言是否使用子目录:
# false: https://example.com/
# true: https://example.com/zh/
defaultContentLanguageInSubdir = false
enableMissingTranslationPlaceholders
在开发时显示缺失翻译的占位符:
# 开发环境建议启用,生产环境关闭
enableMissingTranslationPlaceholders = true
languageCode
站点的语言标签,遵循 RFC 5646 规范:
languageCode = 'zh-CN' # 中文(中国大陆)
# languageCode = 'zh-TW' # 中文(台湾)
# languageCode = 'en-US' # 英语(美国)
语言特定配置
基本语言配置
[languages]
[languages.zh]
languageName = '中文'
languageDirection = 'ltr'
title = '我的中文网站'
weight = 1
disabled = false
# 自定义参数
[languages.zh.params]
description = '这是中文网站的描述'
author = '作者姓名'
# 菜单配置
[[languages.zh.menu.main]]
name = '首页'
url = '/'
weight = 10
[[languages.zh.menu.main]]
name = '关于'
url = '/about/'
weight = 20
[languages.en]
languageName = 'English'
languageDirection = 'ltr'
title = 'My English Website'
weight = 2
[languages.en.params]
description = 'This is the description of my English website'
author = 'Author Name'
[[languages.en.menu.main]]
name = 'Home'
url = '/'
weight = 10
[[languages.en.menu.main]]
name = 'About'
url = '/about/'
weight = 20
高级配置选项
时区配置
[languages.zh]
timeZone = 'Asia/Shanghai'
[languages.en]
timeZone = 'America/New_York'
分页配置
[languages.zh]
paginatePath = '页面' # /blog/页面/2/
[languages.en]
paginatePath = 'page' # /blog/page/2/
权重排序
# 权重越小,在排序时越靠前
[languages.zh]
weight = 1 # 第一位
[languages.en]
weight = 2 # 第二位
[languages.ja]
weight = 3 # 第三位
内容组织策略
目录结构方案
方案一:按语言分目录
content/
├── zh/
│ ├── _index.md
│ ├── about.md
│ └── posts/
│ ├── _index.md
│ ├── post-1.md
│ └── post-2.md
├── en/
│ ├── _index.md
│ ├── about.md
│ └── posts/
│ ├── _index.md
│ ├── post-1.md
│ └── post-2.md
└── ja/
├── _index.md
└── posts/
└── _index.md
方案二:文件名后缀
content/
├── _index.zh.md
├── _index.en.md
├── about.zh.md
├── about.en.md
└── posts/
├── _index.zh.md
├── _index.en.md
├── post-1.zh.md
├── post-1.en.md
├── post-2.zh.md
└── post-2.en.md
内容翻译关联
通过文件名关联
# content/zh/posts/my-post.md
---
title: "我的文章"
date: 2025-06-19
translationKey: "my-post"
---
# content/en/posts/my-post.md
---
title: "My Post"
date: 2025-06-19
translationKey: "my-post"
---
自动关联
Hugo 会自动关联具有相同路径的不同语言版本:
content/
├── zh/
│ └── about.md # 自动关联
├── en/
│ └── about.md # 自动关联
└── ja/
└── about.md # 自动关联
翻译管理
i18n 翻译文件
创建翻译文件存储字符串翻译:
中文翻译文件
# i18n/zh.yaml
- id: "home"
translation: "首页"
- id: "about"
translation: "关于"
- id: "posts"
translation: "文章"
- id: "read_more"
translation: "阅读更多"
- id: "published_on"
translation: "发布于"
- id: "reading_time"
translation: "阅读时间"
other: "{{ .Count }} 分钟"
- id: "page_not_found"
translation: "页面未找到"
- id: "search_placeholder"
translation: "搜索文章..."
英文翻译文件
# i18n/en.yaml
- id: "home"
translation: "Home"
- id: "about"
translation: "About"
- id: "posts"
translation: "Posts"
- id: "read_more"
translation: "Read More"
- id: "published_on"
translation: "Published on"
- id: "reading_time"
one: "{{ .Count }} minute"
other: "{{ .Count }} minutes"
- id: "page_not_found"
translation: "Page Not Found"
- id: "search_placeholder"
translation: "Search posts..."
在模板中使用翻译
<!-- 基本翻译 -->
<h1>{{ i18n "home" }}</h1>
<!-- 带参数的翻译 -->
<p>{{ i18n "published_on" . }} {{ .Date.Format "2006-01-02" }}</p>
<!-- 复数形式 -->
<span>{{ i18n "reading_time" .ReadingTime }}</span>
<!-- 带回退的翻译 -->
{{ i18n "custom_key" | default "Default Text" }}
<!-- 检查翻译是否存在 -->
{{ if i18n "optional_key" }}
<p>{{ i18n "optional_key" }}</p>
{{ end }}
复数规则支持
Hugo 支持不同语言的复数规则:
# i18n/zh.yaml
- id: "items_count"
other: "{{ .Count }} 个项目"
# i18n/en.yaml
- id: "items_count"
one: "{{ .Count }} item"
other: "{{ .Count }} items"
# i18n/ru.yaml
- id: "items_count"
one: "{{ .Count }} элемент"
few: "{{ .Count }} элемента"
many: "{{ .Count }} элементов"
other: "{{ .Count }} элементов"
URL 本地化
路径本地化
通过前置元数据自定义不同语言的 URL:
# content/zh/about.md
---
title: "关于我们"
slug: "guanyu"
url: "/guanyu/"
---
# content/en/about.md
---
title: "About Us"
slug: "about"
url: "/about/"
---
永久链接本地化
# hugo.toml
[languages.zh]
[languages.zh.permalinks]
posts = "/wenzhang/:year/:month/:title/"
[languages.en]
[languages.en.permalinks]
posts = "/posts/:year/:month/:title/"
别名重定向
# content/zh/about.md
---
title: "关于我们"
aliases:
- "/about-us/"
- "/guanyu-women/"
---
# content/en/about.md
---
title: "About Us"
aliases:
- "/guanyu/"
- "/about-zh/"
---
日期和数字本地化
日期格式化
<!-- 使用语言特定的日期格式 -->
{{ .Date.Format "2006年01月02日" }} <!-- 中文 -->
{{ .Date.Format "January 2, 2006" }} <!-- 英文 -->
<!-- 根据当前语言自动格式化 -->
{{ .Date | dateFormat ":date_medium" }}
数字和货币格式化
<!-- 数字格式化 -->
{{ lang.FormatNumber 2 1234.56 }}
<!-- 货币格式化 -->
{{ lang.FormatCurrency 2 "USD" 123.45 }}
<!-- 百分比格式化 -->
{{ lang.FormatPercent 2 0.1234 }}
自定义格式化函数
<!-- 在模板中定义本地化函数 -->
{{ define "formatPrice" }}
{{ if eq .Site.Language.Lang "zh" }}
¥{{ .price }}
{{ else if eq .Site.Language.Lang "en" }}
${{ .price }}
{{ else if eq .Site.Language.Lang "ja" }}
¥{{ .price }}
{{ end }}
{{ end }}
<!-- 使用自定义函数 -->
{{ template "formatPrice" (dict "price" 99.99) }}
模板中的多语言功能
语言切换器
<!-- 基本语言切换器 -->
<nav class="language-switcher">
{{ range .Site.Languages }}
{{ if eq . $.Site.Language }}
<span class="current">{{ .LanguageName }}</span>
{{ else }}
{{ with $.Translations.Get .Lang }}
<a href="{{ .Permalink }}">{{ .Language.LanguageName }}</a>
{{ else }}
<a href="{{ .BaseURL }}">{{ .LanguageName }}</a>
{{ end }}
{{ end }}
{{ end }}
</nav>
<!-- 高级语言切换器 -->
<div class="language-selector">
<button class="current-lang">
{{ .Site.Language.LanguageName }}
</button>
<ul class="lang-options">
{{ range .Site.Languages }}
{{ if ne . $.Site.Language }}
<li>
{{ with $.Translations.Get .Lang }}
<a href="{{ .Permalink }}" hreflang="{{ .Lang }}">
{{ .Language.LanguageName }}
</a>
{{ else }}
<a href="{{ .BaseURL }}" hreflang="{{ .Lang }}">
{{ .LanguageName }}
</a>
{{ end }}
</li>
{{ end }}
{{ end }}
</ul>
</div>
检查翻译可用性
<!-- 检查当前页面是否有其他语言版本 -->
{{ if .Translations }}
<div class="translations">
<h3>{{ i18n "other_languages" }}</h3>
<ul>
{{ range .Translations }}
<li>
<a href="{{ .Permalink }}" hreflang="{{ .Lang }}">
{{ .Language.LanguageName }}: {{ .Title }}
</a>
</li>
{{ end }}
</ul>
</div>
{{ end }}
<!-- 检查特定语言版本 -->
{{ with .Translations.Get "en" }}
<a href="{{ .Permalink }}">Read in English</a>
{{ end }}
语言特定的模板
<!-- 根据语言加载不同的模板部分 -->
{{ $template := printf "partials/header-%s.html" .Site.Language.Lang }}
{{ if templates.Exists $template }}
{{ partial $template . }}
{{ else }}
{{ partial "partials/header.html" . }}
{{ end }}
<!-- 语言特定的样式 -->
{{ if eq .Site.Language.Lang "ar" }}
<link rel="stylesheet" href="/css/rtl.css">
{{ end }}
SEO 优化
hreflang 标签
<!-- 在 head 中添加 hreflang 标签 -->
<head>
{{ range .Translations }}
<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .Permalink }}">
{{ end }}
<link rel="alternate" hreflang="{{ .Site.Language.Lang }}" href="{{ .Permalink }}">
<link rel="alternate" hreflang="x-default" href="{{ .Site.BaseURL }}">
</head>
结构化数据
<!-- 多语言结构化数据 -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "{{ .Title }}",
"description": "{{ .Description }}",
"inLanguage": "{{ .Site.Language.Lang }}",
"url": "{{ .Permalink }}",
{{ if .Translations }}
"sameAs": [
{{ range $index, $translation := .Translations }}
{{ if $index }},{{ end }}
"{{ $translation.Permalink }}"
{{ end }}
],
{{ end }}
"publisher": {
"@type": "Organization",
"name": "{{ .Site.Title }}"
}
}
</script>
部署配置
单主机配置
# hugo.toml - 单主机多语言
baseURL = 'https://example.com'
[languages]
[languages.zh]
languageName = '中文'
weight = 1
[languages.en]
languageName = 'English'
weight = 2
URL 结构:
多主机配置
# hugo.toml - 多主机配置
[languages]
[languages.zh]
baseURL = 'https://example.com'
languageName = '中文'
weight = 1
[languages.en]
baseURL = 'https://en.example.com'
languageName = 'English'
weight = 2
[languages.ja]
baseURL = 'https://ja.example.com'
languageName = '日本語'
weight = 3
环境特定配置
# config/production/hugo.toml
[languages.zh]
baseURL = 'https://example.com'
[languages.en]
baseURL = 'https://en.example.com'
# config/development/hugo.toml
[languages.zh]
baseURL = 'http://localhost:1313'
[languages.en]
baseURL = 'http://localhost:1313'
最佳实践
1. 内容管理策略
- 使用一致的翻译键 (translationKey)
- 建立内容翻译工作流程
- 定期审查和更新翻译内容
- 为每种语言指定负责人
2. 技术实施建议
# 推荐的基础配置
defaultContentLanguage = 'zh'
defaultContentLanguageInSubdir = false
enableMissingTranslationPlaceholders = false
[languages]
[languages.zh]
languageName = '中文'
languageCode = 'zh-CN'
weight = 1
[languages.en]
languageName = 'English'
languageCode = 'en-US'
weight = 2
3. 调试和测试
# 启用翻译警告
hugo server --printI18nWarnings
# 检查缺失翻译
grep -r "i18n" layouts/ | grep -v ".git"
# 构建特定语言
hugo --environment production --buildDrafts=false
4. 性能优化
- 合理组织翻译文件,避免过大的单个文件
- 使用 Hugo 的缓存机制
- 考虑为不同语言使用不同的 CDN 分发
通过 Hugo 的多语言支持,您可以构建真正国际化的静态网站,为全球用户提供本地化的体验。