@ouraihub/hugo 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +149 -0
- package/layouts/partials/SEO-USAGE.md +339 -0
- package/layouts/partials/lazy-image.html +35 -0
- package/layouts/partials/navigation.html +269 -0
- package/layouts/partials/search-modal.html +317 -0
- package/layouts/partials/seo-meta.html +91 -0
- package/layouts/partials/seo-schema.html +117 -0
- package/layouts/partials/theme-toggle.html +30 -0
- package/package.json +38 -0
- package/static/js/theme-init.js +375 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OurAI Hub
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# @ouraihub/hugo
|
|
2
|
+
|
|
3
|
+
Hugo 主题组件包,提供开箱即用的主题切换功能。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @ouraihub/hugo @ouraihub/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 使用方式
|
|
12
|
+
|
|
13
|
+
### 1. 在 Hugo 模板中引入 partial
|
|
14
|
+
|
|
15
|
+
在你的 Hugo 布局文件中(如 `layouts/partials/header.html`):
|
|
16
|
+
|
|
17
|
+
```html
|
|
18
|
+
{{ partial "theme-toggle.html" . }}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 2. 在 Hugo 配置中引入 JS 脚本
|
|
22
|
+
|
|
23
|
+
在 `config.toml` 或 `config.yaml` 中配置静态资源:
|
|
24
|
+
|
|
25
|
+
```toml
|
|
26
|
+
# config.toml
|
|
27
|
+
[outputs]
|
|
28
|
+
home = ["HTML", "JSON"]
|
|
29
|
+
|
|
30
|
+
[params]
|
|
31
|
+
# 其他配置...
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
在你的基础模板(`layouts/_default/baseof.html`)中引入脚本:
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<!DOCTYPE html>
|
|
38
|
+
<html>
|
|
39
|
+
<head>
|
|
40
|
+
<!-- 其他 head 内容 -->
|
|
41
|
+
</head>
|
|
42
|
+
<body>
|
|
43
|
+
{{ block "main" . }}{{ end }}
|
|
44
|
+
|
|
45
|
+
<!-- 在 body 末尾引入主题初始化脚本 -->
|
|
46
|
+
<script src="/js/theme-init.js"></script>
|
|
47
|
+
</body>
|
|
48
|
+
</html>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 3. 配置 CSS 变量
|
|
52
|
+
|
|
53
|
+
在你的全局样式中定义主题相关的 CSS 变量:
|
|
54
|
+
|
|
55
|
+
```css
|
|
56
|
+
:root {
|
|
57
|
+
--ui-border: #e0e0e0;
|
|
58
|
+
--ui-background: #ffffff;
|
|
59
|
+
--ui-background-hover: #f5f5f5;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
[data-theme="dark"] {
|
|
63
|
+
--ui-border: #333333;
|
|
64
|
+
--ui-background: #1a1a1a;
|
|
65
|
+
--ui-background-hover: #2a2a2a;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 配置选项
|
|
70
|
+
|
|
71
|
+
主题切换按钮支持以下自定义属性:
|
|
72
|
+
|
|
73
|
+
| 属性 | 默认值 | 说明 |
|
|
74
|
+
|------|--------|------|
|
|
75
|
+
| `data-ui-storage-key` | `theme` | localStorage 存储键名 |
|
|
76
|
+
| `data-ui-attribute` | `data-theme` | 应用主题的 HTML 属性名 |
|
|
77
|
+
| `aria-label` | `切换主题` | 无障碍标签 |
|
|
78
|
+
|
|
79
|
+
### 自定义示例
|
|
80
|
+
|
|
81
|
+
如果需要自定义存储键或属性名,可以修改 partial:
|
|
82
|
+
|
|
83
|
+
```html
|
|
84
|
+
<button
|
|
85
|
+
data-ui-component="theme-toggle"
|
|
86
|
+
data-ui-storage-key="my-theme"
|
|
87
|
+
data-ui-attribute="data-color-scheme"
|
|
88
|
+
class="theme-toggle-btn"
|
|
89
|
+
aria-label="切换主题"
|
|
90
|
+
>
|
|
91
|
+
<span class="theme-icon-light">☀️</span>
|
|
92
|
+
<span class="theme-icon-dark">🌙</span>
|
|
93
|
+
</button>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 工作原理
|
|
97
|
+
|
|
98
|
+
### ThemeManager 类
|
|
99
|
+
|
|
100
|
+
核心逻辑由 `ThemeManager` 类提供,支持三种主题模式:
|
|
101
|
+
|
|
102
|
+
- **light**: 浅色主题
|
|
103
|
+
- **dark**: 深色主题
|
|
104
|
+
- **system**: 跟随系统设置(默认)
|
|
105
|
+
|
|
106
|
+
### 自动初始化
|
|
107
|
+
|
|
108
|
+
`theme-init.js` 脚本会在 DOM 加载完成后自动:
|
|
109
|
+
|
|
110
|
+
1. 扫描所有 `[data-ui-component="theme-toggle"]` 元素
|
|
111
|
+
2. 为每个元素创建 `ThemeManager` 实例
|
|
112
|
+
3. 绑定点击事件以切换主题
|
|
113
|
+
4. 监听系统主题变化
|
|
114
|
+
|
|
115
|
+
### 持久化
|
|
116
|
+
|
|
117
|
+
用户选择的主题会自动保存到 localStorage,下次访问时自动恢复。
|
|
118
|
+
|
|
119
|
+
## 样式定制
|
|
120
|
+
|
|
121
|
+
主题切换按钮使用 CSS 变量,可以通过修改 `theme-toggle.html` 中的样式来自定义外观:
|
|
122
|
+
|
|
123
|
+
```css
|
|
124
|
+
.theme-toggle-btn {
|
|
125
|
+
/* 自定义按钮样式 */
|
|
126
|
+
border: 1px solid var(--ui-border, #e0e0e0);
|
|
127
|
+
background: var(--ui-background, #ffffff);
|
|
128
|
+
padding: 0.5rem;
|
|
129
|
+
border-radius: 0.25rem;
|
|
130
|
+
cursor: pointer;
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## 无障碍支持
|
|
135
|
+
|
|
136
|
+
- 按钮包含 `aria-label` 属性,屏幕阅读器可以正确识别
|
|
137
|
+
- 支持键盘导航(Tab 键)
|
|
138
|
+
- 支持 Enter/Space 键激活
|
|
139
|
+
|
|
140
|
+
## 浏览器兼容性
|
|
141
|
+
|
|
142
|
+
- Chrome/Edge: ✅ 完全支持
|
|
143
|
+
- Firefox: ✅ 完全支持
|
|
144
|
+
- Safari: ✅ 完全支持(iOS 13+)
|
|
145
|
+
- IE 11: ⚠️ 需要 polyfill
|
|
146
|
+
|
|
147
|
+
## 许可证
|
|
148
|
+
|
|
149
|
+
MIT
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# Hugo SEO Partials 使用指南
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
本项目提供了两个 SEO 相关的 Hugo partial 文件:
|
|
6
|
+
- `seo-meta.html` - 基本 meta 标签、Open Graph、Twitter Card、Canonical URL
|
|
7
|
+
- `seo-schema.html` - Schema.org JSON-LD 结构化数据
|
|
8
|
+
|
|
9
|
+
## 快速开始
|
|
10
|
+
|
|
11
|
+
### 1. 在 baseof.html 中引入
|
|
12
|
+
|
|
13
|
+
在你的 `layouts/_default/baseof.html` 文件的 `<head>` 部分添加:
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<!DOCTYPE html>
|
|
17
|
+
<html lang="{{ .Site.Language.Lang }}">
|
|
18
|
+
<head>
|
|
19
|
+
{{- /* SEO Meta 标签 */ -}}
|
|
20
|
+
{{- partial "seo-meta.html" . -}}
|
|
21
|
+
|
|
22
|
+
{{- /* Schema.org 结构化数据 */ -}}
|
|
23
|
+
{{- partial "seo-schema.html" . -}}
|
|
24
|
+
|
|
25
|
+
<title>{{ .Title }} | {{ .Site.Title }}</title>
|
|
26
|
+
|
|
27
|
+
{{- /* 其他 head 内容 */ -}}
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
{{- block "main" . }}{{- end }}
|
|
31
|
+
</body>
|
|
32
|
+
</html>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. 在 config.toml 中配置站点级别的 SEO 参数
|
|
36
|
+
|
|
37
|
+
```toml
|
|
38
|
+
[params]
|
|
39
|
+
description = "你的网站描述"
|
|
40
|
+
author = "作者名称"
|
|
41
|
+
defaultImage = "/images/default-og-image.jpg"
|
|
42
|
+
logo = "/images/logo.png"
|
|
43
|
+
keywords = ["关键词1", "关键词2", "关键词3"]
|
|
44
|
+
|
|
45
|
+
# Twitter 配置
|
|
46
|
+
twitterSite = "@your_twitter_handle"
|
|
47
|
+
twitterCreator = "@your_twitter_handle"
|
|
48
|
+
|
|
49
|
+
# Organization Schema 配置(可选)
|
|
50
|
+
organizationDescription = "组织描述"
|
|
51
|
+
socialLinks = [
|
|
52
|
+
"https://twitter.com/yourhandle",
|
|
53
|
+
"https://github.com/yourhandle",
|
|
54
|
+
"https://linkedin.com/in/yourhandle"
|
|
55
|
+
]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 3. 在页面 Front Matter 中自定义 SEO 数据
|
|
59
|
+
|
|
60
|
+
#### 基本页面示例
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
---
|
|
64
|
+
title: "页面标题"
|
|
65
|
+
description: "页面描述,用于 meta description 和 Open Graph"
|
|
66
|
+
date: 2026-05-13
|
|
67
|
+
author: "作者名称"
|
|
68
|
+
image: "/images/page-image.jpg"
|
|
69
|
+
imageAlt: "图片描述"
|
|
70
|
+
keywords: ["关键词1", "关键词2"]
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
页面内容...
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### 文章页面示例(使用 Article Schema)
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
---
|
|
80
|
+
title: "文章标题"
|
|
81
|
+
description: "文章摘要"
|
|
82
|
+
date: 2026-05-13
|
|
83
|
+
lastmod: 2026-05-13
|
|
84
|
+
author: "作者名称"
|
|
85
|
+
image: "/images/article-cover.jpg"
|
|
86
|
+
imageAlt: "封面图描述"
|
|
87
|
+
tags: ["标签1", "标签2", "标签3"]
|
|
88
|
+
schemaType: "Article" # 使用 Article 类型的 Schema
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
文章内容...
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### 首页示例(使用 Organization Schema)
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
---
|
|
98
|
+
title: "网站首页"
|
|
99
|
+
description: "网站描述"
|
|
100
|
+
schemaType: "Organization" # 使用 Organization 类型的 Schema
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
首页内容...
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 配置参数说明
|
|
107
|
+
|
|
108
|
+
### seo-meta.html 支持的参数
|
|
109
|
+
|
|
110
|
+
#### 页面级别参数(Front Matter)
|
|
111
|
+
|
|
112
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
113
|
+
|------|------|--------|------|
|
|
114
|
+
| `title` | string | `.Site.Title` | 页面标题 |
|
|
115
|
+
| `description` | string | `.Summary` 或 `.Site.Params.description` | 页面描述 |
|
|
116
|
+
| `author` | string | `.Site.Params.author` | 作者名称 |
|
|
117
|
+
| `image` | string | `.Site.Params.defaultImage` | Open Graph 和 Twitter Card 图片 |
|
|
118
|
+
| `imageAlt` | string | `title` | 图片替代文本 |
|
|
119
|
+
| `keywords` | array | `.Site.Params.keywords` | 关键词列表 |
|
|
120
|
+
| `robots` | string | `"index, follow"` | 搜索引擎爬虫指令 |
|
|
121
|
+
| `canonical` | string | `.Permalink` | Canonical URL(自定义) |
|
|
122
|
+
| `twitterCard` | string | `"summary_large_image"` | Twitter Card 类型 |
|
|
123
|
+
| `twitterCreator` | string | `.Site.Params.twitterCreator` | Twitter 创作者账号 |
|
|
124
|
+
| `tags` | array | - | 文章标签(用于 Open Graph) |
|
|
125
|
+
|
|
126
|
+
#### 站点级别参数(config.toml)
|
|
127
|
+
|
|
128
|
+
| 参数 | 类型 | 说明 |
|
|
129
|
+
|------|------|------|
|
|
130
|
+
| `.Site.Title` | string | 网站标题 |
|
|
131
|
+
| `.Site.Params.description` | string | 网站默认描述 |
|
|
132
|
+
| `.Site.Params.author` | string | 默认作者 |
|
|
133
|
+
| `.Site.Params.defaultImage` | string | 默认 Open Graph 图片 |
|
|
134
|
+
| `.Site.Params.keywords` | array | 默认关键词 |
|
|
135
|
+
| `.Site.Params.twitterSite` | string | Twitter 网站账号 |
|
|
136
|
+
| `.Site.Params.twitterCreator` | string | Twitter 创作者账号 |
|
|
137
|
+
| `.Site.Language.Lang` | string | 语言代码(如 "zh-CN") |
|
|
138
|
+
|
|
139
|
+
### seo-schema.html 支持的参数
|
|
140
|
+
|
|
141
|
+
#### 页面级别参数(Front Matter)
|
|
142
|
+
|
|
143
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
144
|
+
|------|------|--------|------|
|
|
145
|
+
| `schemaType` | string | `"WebPage"` | Schema 类型:`"Article"`, `"WebPage"`, `"Organization"` |
|
|
146
|
+
| `title` | string | `.Site.Title` | 标题 |
|
|
147
|
+
| `description` | string | `.Summary` 或 `.Site.Params.description` | 描述 |
|
|
148
|
+
| `author` | string | `.Site.Params.author` | 作者(Article 类型) |
|
|
149
|
+
| `image` | string | `.Site.Params.defaultImage` | 图片 URL |
|
|
150
|
+
| `tags` | array | - | 关键词(Article 类型) |
|
|
151
|
+
|
|
152
|
+
#### 站点级别参数(config.toml)
|
|
153
|
+
|
|
154
|
+
| 参数 | 类型 | 说明 |
|
|
155
|
+
|------|------|------|
|
|
156
|
+
| `.Site.Title` | string | 网站/组织名称 |
|
|
157
|
+
| `.Site.BaseURL` | string | 网站 URL |
|
|
158
|
+
| `.Site.Params.logo` | string | 组织 Logo |
|
|
159
|
+
| `.Site.Params.organizationDescription` | string | 组织描述(Organization 类型) |
|
|
160
|
+
| `.Site.Params.socialLinks` | array | 社交媒体链接(Organization 类型) |
|
|
161
|
+
|
|
162
|
+
## Schema 类型说明
|
|
163
|
+
|
|
164
|
+
### WebPage(默认)
|
|
165
|
+
|
|
166
|
+
适用于普通页面,包含基本的页面信息。
|
|
167
|
+
|
|
168
|
+
```yaml
|
|
169
|
+
---
|
|
170
|
+
title: "关于我们"
|
|
171
|
+
description: "公司介绍"
|
|
172
|
+
schemaType: "WebPage" # 可省略,这是默认值
|
|
173
|
+
---
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Article
|
|
177
|
+
|
|
178
|
+
适用于博客文章、新闻等内容页面,包含发布时间、作者、标签等信息。
|
|
179
|
+
|
|
180
|
+
```yaml
|
|
181
|
+
---
|
|
182
|
+
title: "如何使用 Hugo 构建网站"
|
|
183
|
+
description: "详细教程"
|
|
184
|
+
date: 2026-05-13
|
|
185
|
+
author: "张三"
|
|
186
|
+
tags: ["Hugo", "教程", "静态网站"]
|
|
187
|
+
schemaType: "Article"
|
|
188
|
+
---
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Organization
|
|
192
|
+
|
|
193
|
+
适用于首页或关于页面,展示组织信息和社交媒体链接。
|
|
194
|
+
|
|
195
|
+
```yaml
|
|
196
|
+
---
|
|
197
|
+
title: "公司首页"
|
|
198
|
+
description: "我们是一家..."
|
|
199
|
+
schemaType: "Organization"
|
|
200
|
+
---
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
需要在 `config.toml` 中配置:
|
|
204
|
+
|
|
205
|
+
```toml
|
|
206
|
+
[params]
|
|
207
|
+
organizationDescription = "组织描述"
|
|
208
|
+
socialLinks = [
|
|
209
|
+
"https://twitter.com/yourhandle",
|
|
210
|
+
"https://github.com/yourhandle"
|
|
211
|
+
]
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## 高级用法
|
|
215
|
+
|
|
216
|
+
### 自定义 Canonical URL
|
|
217
|
+
|
|
218
|
+
如果你的内容在多个地方发布,可以指定原始 URL:
|
|
219
|
+
|
|
220
|
+
```yaml
|
|
221
|
+
---
|
|
222
|
+
title: "文章标题"
|
|
223
|
+
canonical: "https://original-site.com/article"
|
|
224
|
+
---
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### 禁止搜索引擎索引
|
|
228
|
+
|
|
229
|
+
```yaml
|
|
230
|
+
---
|
|
231
|
+
title: "草稿页面"
|
|
232
|
+
robots: "noindex, nofollow"
|
|
233
|
+
---
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### 使用外部图片
|
|
237
|
+
|
|
238
|
+
图片 URL 支持相对路径和绝对路径:
|
|
239
|
+
|
|
240
|
+
```yaml
|
|
241
|
+
---
|
|
242
|
+
# 相对路径(会自动转换为绝对 URL)
|
|
243
|
+
image: "/images/cover.jpg"
|
|
244
|
+
|
|
245
|
+
# 或使用完整 URL
|
|
246
|
+
image: "https://cdn.example.com/images/cover.jpg"
|
|
247
|
+
---
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## 验证 SEO 配置
|
|
251
|
+
|
|
252
|
+
### 1. 验证 Open Graph
|
|
253
|
+
|
|
254
|
+
使用 [Facebook Sharing Debugger](https://developers.facebook.com/tools/debug/)
|
|
255
|
+
|
|
256
|
+
### 2. 验证 Twitter Card
|
|
257
|
+
|
|
258
|
+
使用 [Twitter Card Validator](https://cards-dev.twitter.com/validator)
|
|
259
|
+
|
|
260
|
+
### 3. 验证 Schema.org
|
|
261
|
+
|
|
262
|
+
使用 [Google Rich Results Test](https://search.google.com/test/rich-results)
|
|
263
|
+
|
|
264
|
+
## 最佳实践
|
|
265
|
+
|
|
266
|
+
1. **图片尺寸**
|
|
267
|
+
- Open Graph: 1200x630px(推荐)
|
|
268
|
+
- Twitter Card: 1200x675px(推荐)
|
|
269
|
+
|
|
270
|
+
2. **描述长度**
|
|
271
|
+
- Meta description: 150-160 字符
|
|
272
|
+
- Open Graph description: 200 字符以内
|
|
273
|
+
|
|
274
|
+
3. **标题长度**
|
|
275
|
+
- 页面标题: 60 字符以内
|
|
276
|
+
- Open Graph 标题: 60-90 字符
|
|
277
|
+
|
|
278
|
+
4. **必需字段**
|
|
279
|
+
- 每个页面都应该有 `title` 和 `description`
|
|
280
|
+
- 文章页面应该有 `date` 和 `author`
|
|
281
|
+
- 尽量为每个页面提供 `image`
|
|
282
|
+
|
|
283
|
+
5. **HTML 转义**
|
|
284
|
+
- 所有用户输入的内容都会自动进行 HTML 转义
|
|
285
|
+
- 使用 `plainify` 移除 HTML 标签
|
|
286
|
+
- 使用 `jsonify` 确保 JSON-LD 格式正确
|
|
287
|
+
|
|
288
|
+
## 故障排查
|
|
289
|
+
|
|
290
|
+
### 问题:Open Graph 图片不显示
|
|
291
|
+
|
|
292
|
+
**解决方案**:
|
|
293
|
+
1. 确保图片 URL 是绝对路径
|
|
294
|
+
2. 检查图片是否可以公开访问
|
|
295
|
+
3. 图片大小应小于 8MB
|
|
296
|
+
4. 使用 Facebook Debugger 清除缓存
|
|
297
|
+
|
|
298
|
+
### 问题:Schema.org 验证失败
|
|
299
|
+
|
|
300
|
+
**解决方案**:
|
|
301
|
+
1. 使用 Google Rich Results Test 查看具体错误
|
|
302
|
+
2. 确保必需字段都已填写
|
|
303
|
+
3. 检查日期格式是否正确(ISO 8601)
|
|
304
|
+
4. 确保 JSON 格式正确(无多余逗号)
|
|
305
|
+
|
|
306
|
+
### 问题:搜索引擎不索引页面
|
|
307
|
+
|
|
308
|
+
**解决方案**:
|
|
309
|
+
1. 检查 `robots` meta 标签
|
|
310
|
+
2. 确认 `robots.txt` 没有禁止爬取
|
|
311
|
+
3. 检查 Canonical URL 是否正确
|
|
312
|
+
4. 使用 Google Search Console 提交站点地图
|
|
313
|
+
|
|
314
|
+
## 示例项目
|
|
315
|
+
|
|
316
|
+
完整的示例项目结构:
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
my-hugo-site/
|
|
320
|
+
├── config.toml
|
|
321
|
+
├── content/
|
|
322
|
+
│ ├── _index.md # 首页(Organization Schema)
|
|
323
|
+
│ ├── about.md # 关于页面(WebPage Schema)
|
|
324
|
+
│ └── posts/
|
|
325
|
+
│ └── my-post.md # 文章(Article Schema)
|
|
326
|
+
└── layouts/
|
|
327
|
+
├── _default/
|
|
328
|
+
│ └── baseof.html # 引入 SEO partials
|
|
329
|
+
└── partials/
|
|
330
|
+
├── seo-meta.html
|
|
331
|
+
└── seo-schema.html
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## 相关资源
|
|
335
|
+
|
|
336
|
+
- [Open Graph Protocol](https://ogp.me/)
|
|
337
|
+
- [Twitter Cards Documentation](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/abouts-cards)
|
|
338
|
+
- [Schema.org Documentation](https://schema.org/)
|
|
339
|
+
- [Google Search Central](https://developers.google.com/search)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{{- $src := .src | default "" -}}
|
|
2
|
+
{{- $alt := .alt | default "" -}}
|
|
3
|
+
{{- $placeholder := .placeholder | default "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Crect fill='%23f0f0f0' width='400' height='300'/%3E%3C/svg%3E" -}}
|
|
4
|
+
{{- $class := .class | default "" -}}
|
|
5
|
+
{{- $width := .width | default "" -}}
|
|
6
|
+
{{- $height := .height | default "" -}}
|
|
7
|
+
{{- $loading := .loading | default "lazy" -}}
|
|
8
|
+
|
|
9
|
+
<img
|
|
10
|
+
data-ui-component="lazy-image"
|
|
11
|
+
data-src="{{ $src }}"
|
|
12
|
+
src="{{ $placeholder }}"
|
|
13
|
+
alt="{{ $alt }}"
|
|
14
|
+
class="lazy-image {{ $class }}"
|
|
15
|
+
{{- if $width }} width="{{ $width }}"{{ end -}}
|
|
16
|
+
{{- if $height }} height="{{ $height }}"{{ end -}}
|
|
17
|
+
loading="{{ $loading }}"
|
|
18
|
+
decoding="async"
|
|
19
|
+
/>
|
|
20
|
+
|
|
21
|
+
<style>
|
|
22
|
+
.lazy-image {
|
|
23
|
+
opacity: 0;
|
|
24
|
+
transition: opacity 0.3s ease-in;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.lazy-image.loaded {
|
|
28
|
+
opacity: 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.lazy-image.error {
|
|
32
|
+
opacity: 0.5;
|
|
33
|
+
border: 2px dashed var(--ui-error, #dc2626);
|
|
34
|
+
}
|
|
35
|
+
</style>
|