为Hexo + NexT主题博客自动生成SEO友好的Meta Description标签

我的博客都是在obsidian里面编写,然后通过Hexo + Next生成的静态网页。

最近发现搜索引擎提示我的博客网页缺少 <meta name="description" content="xxxxx"> 这样的标签,并且被标记为Error,不利于被搜索引擎推广。于是我就想为我的博客页面添加description标签。

网上找了一圈,发现Hexo + Next这个方法好像不能直接支持为每一篇博客自定义description这个标签,后来干脆就问了一下Claude 3.5 Sonnet.

我的问题是: 我有一个静态博客,是用Hexo工具+ Next主题构建的,但是默认情况下,生成的静态页面不包含 <meta name='description' content='Descriptive, keyword-rich text that talks about the page content goes here.'> 这样的标签,不利于SEO,我想为每一篇博客添加这个标签,你想一下应该怎么做?

Claude 3.5 Sonnet给我的回答是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
要为 Hexo + NexT 主题的每篇博客添加 description meta 标签,你可以采取以下步骤:

在文章的 Front Matter 中添加描述:

首先,为每篇博客文章的 Front Matter 添加一个 description 字段。例如:
---
title: 你的文章标题
date: 2023-07-22 14:30:00
tags: [tag1, tag2]
description: 这是一段描述性的、包含关键词的文本,用来描述这篇文章的内容。
---

修改主题模板:

找到 NexT 主题的 head.swig 文件(通常位于 themes/next/layout/_partials/head.swig),在适当的位置添加以下代码:
{% if page.description %}
<meta name="description" content="{{ page.description }}">
{% elif page.excerpt %}
<meta name="description" content="{{ page.excerpt | strip_html | trim | truncate(150) }}">
{% elif config.description %}
<meta name="description" content="{{ config.description }}">
{% endif %}
这段代码会按以下优先级添加 description meta 标签:

使用文章 Front Matter 中的 description
如果没有,则使用文章摘要(excerpt)
如果都没有,则使用站点配置中的全局 description
配置站点全局描述:

在 Hexo 的 _config.yml 文件中添加一个全局描述:
description: 这是你的博客的全局描述,当文章没有特定描述时会使用这个。

生成摘要:

如果你想使用文章摘要作为描述,确保在 Hexo 的 _config.yml 中启用了自动摘要生成:
excerpt:
depth: 150
excerpt_excludes: []
more_excludes: []
hideWholePostExcerpts: false
这会自动生成 150 字符的摘要。

重新生成静态文件:

完成上述修改后,运行以下命令重新生成你的静态网站:
hexo clean
hexo generate
通过这些步骤,你的每篇博客文章都会包含一个 description meta 标签,内容会根据你的设置自动填充,这将有助于提升你的 SEO 表现。
记住,为每篇文章写一个独特、描述性强的 description 是最佳实践,因为它能最准确地描述你的文章内容,对 SEO 最有帮助。

我测试了一下这个方法,发现不行,不能按照预期生成description标签,后来找到原因是没有办法在head.njk中使用page.description这个参数,应该是模板变量作用域的问题。

我就尝试在 themes/next/layout/_layout.njk的 head部分添加上面给出的可以生成description标签的模板代码,毕竟layout是最顶层的模板,所有的参数在这里应该都是可用的,更新之后_layout.njk的head部分如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<head>
{{ partial('_partials/head/head.njk', {}, {cache: theme.cache.enable}) }}
{% if page.description %}
<meta name="description" content="{{ page.description }}">
{% else %}
<meta name="description" content="{{ theme.description }}">
{% endif %}
{%- include '_partials/head/head-unique.njk' -%}
<title>{% block title %}{% endblock %}</title>
{{ partial('_third-party/analytics/index.njk', {}, {cache: theme.cache.enable}) }}
{{- next_inject('head') }}
<noscript>
<link rel="stylesheet" href="{{ url_for(theme.css) }}/noscript.css">
</noscript>
</head>

测试表明上面这个方法是可行的。

现在Hexo + Next这一端已经有了解决方案了,但是这个方案的前提是博客文件的Front Matter中要包含description这个标签,并且内容要适合SEO。

我又想到了使用大模型帮我生成合适的description内容。于是我就手动从obsidian中一篇一篇的把博客内容复制到浏览器的大模型对话窗口中,然后再把大模型返回的description值写入到obsidian文件中。这么操作了七八篇博客之后我就放弃了,因为我有100多篇博客,这么做要很久,而且以后怎么办呢?难道要一直这么做吗?

前天晚上躺在床上睡不着觉,想到了这个问题,突然想到可以做一个obsidian插件来辅助这个过程。

上面提到的用大模型辅助生成description的过程中,比较麻烦是在obsidian和浏览器之间来回复制/粘贴文字,插件的逻辑只要自动化这一段操作就可以了,看起来还是比较简单的。

昨天花了两个多小时把这个插件做出来了,代码在这里:seo_friendly_description_geneater, 目前还没有通过obsidian官方的review,所以在plugin marketplace里面还搜不到。

插件的效果预览如图中红框标出来的部分。

seo-friendly-description-generater-demo

插件目前只支持openai和azure openai

参数名 说明 类型 默认值
apiKey 调用大模型需要的key string
useAzure 是否使用azure openai string false
apiUrl 大模型的调用接口,如果useAzure为True,这个参数应该填写azure openai的endpoint地址,格式为:https://xxxxx.openai.azure.com/ string https://api.openai.com/v1/chat/completions
model 大模型的名称,如果useAzure为True,这个参数不用填 string gpt-3.5-turbo
maxTokens 大模型生成的最大token数量 number 150
temperature 大模型生成的温度 number 0.8
azureApiVersion azure api版本, useAzure为False时,可以不填 string 2023-05-15
azureDeploymentName azure deployment name,useAzure为False时,可以不填 string

使用的时候,先打开需要生成description的markdown文件,然后在obsidian的命令行中搜索seo,出现如下命令,点击即可。

也可以绑定一个快捷键,方便使用,比如我这里绑定的是Ctrl + Alt + O

[command)