博客的迁移和重整

本文介绍的是之前本博客在 Notion 时所使用的 Nobelium 框架。现在本博客已经改为 Astro 框架。

寻找

今年的 2 月，我曾因为服务器的原因将博客从 Typecho 迁移到了 Notion，并通过 Super.so 驱动。老实讲，整体并不是非常满意，主要是以下三点：

Super.so 还没有为博客提供 RSS 订阅。无奈之下最开始使用的是用 rss.com 制作的订阅源，发现并不稳定而且不能输出全文；又换成了 fetchrss.com，只能在部分 RSS 阅读器中可以查看全文；最后，看到了 DIYgod 大佬的新项目链上开源博客 xLog，这才解决了 RSS 的问题。

Super.so 也没有集成评论功能。虽然我的博客评论并不多，但总还是有的。即便是我找到了 Tally，也还是因为读者使用门槛过高而受到过批评。

Super.so 更适合构建简单的网站，而不适合于博客。利用 Notion + Super.so 来做 CMS 很合适，可如果单纯做博客，尤其是内容一多起来，页面管理复杂、混乱的问题就暴露出来。

所以，我又开始寻找与 Notion 更匹配的博客驱动服务。

利用 Notion 建站的项目有很多，经过筛选之后我挑出来 4 个，分别是 Feather.so，Notablog，NotionNext 和 Nobelium。

Feather.so 非常好，可以说如果想要把 Notion 当作博客来使用，最好的驱动服务就是这个了。不仅有 RSS，也有评论功能，非常好的 SEO 优化，页面管理逻辑顺畅…… 不过，好服务往往对应着高价格，Super.so 每个月 $12 我都嫌贵，更何况这个是每个月 $39 呢。

Notablog 是我关注很久的一个项目，由一位美籍华人在 GitHub 上开源。整体观感十分简洁、优雅，操作与管理逻辑也很清晰，可以很方便地部署在 VPS。然而，这个项目近一年没有什么更新了。

NotionNext 是我曾经部署过的一个项目，不仅写过文章介绍，还推荐给了好几位朋友。到目前为止开发者的更新依然频繁，一直在尽心维护。只是对 Notion Block 的支持并不全面，更新起来也有些麻烦，不太适合我这种懒人。

Nobelium 和 Notablog 与 NotionNext 一样是在 GitHub 上开源的项目，只是与后两者区别很大。Notablog 更像是一个个人网站；NotionNext 由于支持很多种主题，显得花哨了很多；Nobelium 就是一个极简风格的博客，没有华丽的渲染，没有多变的主题，也没有复杂的功能。普普通通的 Nobelium 给了我返璞归真的感觉，个人博客不就应该是这样的吗？

部署

Nobelium 的部署并不复杂，开发者在 GitHub 的项目页面中写的很详细，我只简单说一下。

步骤一：复制 Notion template 到您自己的 Notion 账号中。

这个数据库里的每一个属性非常好理解。

Note

数据库属性释义

title： 文章的标题；

date： 文章发布的时间，如果留空默认是文章创建的时间；

slug： 文章 URL 尾部的字符，也就是 .com/xxx 中 xxx 的部分，建议使用英文，用 - 代替空格；如果使用中文或者空格、标点，会被 UrlEncode 变成一长串，链接会显得很长且不美观；

summary： 文章简介，会显示在主页标题的底部；

tags： 文章标签，可以对文章进行分类；

status： 文章状态，只有 Published 状态的文章会在博客公开显示；Draft 是草稿状态，Idea 是想法状态，Revise 是改写状态，这三种状态都不会在博客公开显示；

type： Post 会直接显示在主页，Page 只有直接访问 URL 会显示，不会出现在主页文章列表中。

步骤二：在 GitHub 中将项目 Fork 到自己的账号之后，需要修改 blog.config.js 中的内容。

Copy
const BLOG = {
title: "CRAIGARY", // 您的博客名称（标题）
author: "Craig Hart", // 您的昵称
email: "i@craigary.net", // 您的邮箱
link: "https://nobelium.vercel.app", // 您的博客网址
description: "This gonna be an awesome website.", // 您的博客描述（副标题）
lang: "en-US", // 语言，'en-US'为英文, 'zh-CN'为简体中文, 'zh-HK'为香港繁体中文, 'zh-TW'为台湾繁体中文, 'ja-JP'为日文, 'es-ES'为西班牙文]
timezone: "Asia/Shanghai", // 时区，可以在 https://en.wikipedia.org/wiki/List_of_tz_database_time_zones 查看有关时区的更多详情
font: "sans-serif", // 字体，'sans-serif'为无衬线字体, 'serif'为衬线字体
lightBackground: "#ffffff", // 浅色背景，使用十六进制的颜色，比如 #fffefc，注意不要忘记 #
darkBackground: "#18181B", // 深色背景，使用十六进制的颜色，注意不要忘记 #
path: "", // 除非您想要在一个文件夹中部署，否则请将此文件保留为空
since: 2021, // 博客起始日期，如果留空则使用现在的年份
sortByDate: false, // 按日期排序，false 表示否，ture 表示是
showAbout: true, // 显示关于本站
showArchive: true, // 显示归档
autoCollapsedNavBar: false, // 自动折叠导航栏
ogImageGenerateURL: "https://og-image-craigary.vercel.app", // 生成 OG 图像链接
socialLink: "https://twitter.com/craigaryhart", // 社交平台链接，填写后在文章页面点击您的昵称会跳转到对应的平台
seo: {
keywords: ["Blog", "Website", "Notion"], // 关键词
googleSiteVerification: "", // 删除该值或替换为您自己的谷歌网站验证代码
},
notionPageId: process.env.NOTION_PAGE_ID, // 不要更改这个！！！
notionAccessToken: process.env.NOTION_ACCESS_TOKEN, // 如果不希望将数据库公开，则使用
analytics: {
provider: "", // 目前提供 Google Analytics 和 Ackee 两种访客统计,如果要使用 Google Analytics 则填写'ga'，如果要使用 Ackee 则填写 'ackee'，如果不使用则留空
ackeeConfig: {
tracker: "", // 如果使用 Ackee，则填写，如'https://ackee.craigary.net/tracker.js'
dataAckeeServer: "", // 如果使用 Ackee，则填写，如'https://ackee.craigary.net'
domainId: "", // 如果使用 Ackee，则填写，如'0e2257a8-54d4-4847-91a1-0311ea48cc7b'
},
gaConfig: {
measurementId: "", // 如果使用 Google Analytics，则填写，如'G-XXXXXXXXXX'
},
},
comment: {
// 目前集成的评论插件包括 gitalk, utterances 和 cusdis
provider: "", // 填写您使用的评论插件，留空则表示不使用
gitalkConfig: {
repo: "", // 此处请填写您从 gitalk 获取的信息
owner: "", // 此处请填写您从 gitalk 获取的信息
admin: [], // 此处请填写您从 gitalk 获取的信息
clientID: "", // 此处请填写您从 gitalk 获取的信息
clientSecret: "", // 此处请填写您从 gitalk 获取的信息
distractionFreeMode: false,
},
utterancesConfig: {
repo: "", // 此处请填写您从 utterances 获取的信息
},
cusdisConfig: {
appId: "", // // 此处请填写您从 cusdis 获取的信息
host: "https://cusdis.com", //如果您自己部署了 cusdis 服务，则更换为您自己的服务地址
scriptSrc: "https://cusdis.com/js/cusdis.es.js", // 如果您自己部署了 cusdis 服务，则更换为您自己的服务地址
},
},
isProd: process.env.VERCEL_ENV === "production", // 区分开发环境和生成环境，详情见 https://vercel.com/docs/environment-variables#system-environment-variables
};
// export default BLOG
module.exports = BLOG;

步骤三：修改完成后，到 Vercel 中部署就可以了，记得在 1️⃣ 填写 NOTION_PAGE_ID，在 2️⃣ 填写 Page ID，然后点击 Add 添加。

什么是 Notion Page ID

在 Notion 中点击 Share，然后打开 Share to web，会生成一段可公开访问的网址，比如 https://xxx.notion.site/80c301f9f7264a4aa5dfc1f8b9841222?v=37fe9de07b164c27a9cc3a7c5614a7c4，在https://xxx.notion.site/ 之后，?v= 之前的那一段编码就是 Page ID，即80c301f9f7264a4aa5dfc1f8b9841222 。

Cusdis

我很认同秉儒在《为何我想停用 Cusdis 但却又反悔？》中提到的理想中留言系统的样子：

有匿名留言的功能；要用 Twitter, Github, Telegram, FB, Google 等不同登录方式也可以；也可以用 email 登录；支持 markdown；可以连接 Tg 或 Slack 等通讯软件实时提醒；可以用 email 通知评论者他们的评论已回复（如果有留下 email）；轻量、注重隐私。

从 blog.config.js 可以看到，Nobelium 的评论插件支持 gitalk，utterances 和 cusdis。

Utterances 我没有用过，所以不考虑。Gitalk 在写评论的时候要使用 GitHub 账号登录，并不是匿名的，而且在国内的访问也不好，所以不考虑。Cusdis 是 Randy 大佬开发的评论插件，不仅小巧便捷，还不需要在评论的时候登录任何账号进行匿名评论，自然也就成为了唯一的选择，并且我之前还使用过，印象中很接近理想中留言系统的样子。

我没有选择自部署，而是直接用的 cusdis 的官方服务，添加了 Webhook，有新的评论就可以在 Tg 上实时提醒。之前就搭建了 MTPROTO，也不需要担心 Tg 收不到提醒。

由于 cusdis 是免登录的评论服务，所以每一条匿名评论都需要管理员批准，看起来似乎有些繁琐。不过测试的时候我发现可以直接在 Tg 中免登录批准评论，跳转也很方便。

修改

部署完之后，我将 Notion 中原本在 Super.so 数据库的文章都移动到了 Nobelium 的数据库。然后刷新了一下博客页面，发现对默认的导航栏、页脚、代码块和字体都不是很满意。于是，不懂代码的我就在 ChatGPT 的帮助下开始了自定义。

导航栏

首先修改的就是导航栏。在 components/Header.js 中，有这样一段代码：

Copy
const NavBar = () => {
const BLOG = useConfig()
const locale = useLocale()
const links = [
{ id: 0, name: locale.NAV.INDEX, to: BLOG.path || '/', show: true },
{ id: 1, name: locale.NAV.ABOUT, to: '/about', show: BLOG.showAbout },
{ id: 2, name: locale.NAV.RSS, to: '/feed', show: true, external: true },
{ id: 3, name: locale.NAV.SEARCH, to: '/search', show: true }
]

其中 id: 0, name: locale.NAV.INDEX, to: BLOG.path || '/', show: true 可以翻译为 id: 显示顺序, name: local.NAV. 变量, to: '路径', show: true。

简单理解，变量就是在导航栏中需要显示的名称变量，路径就是这个变量指向的 URL 是哪里。比如 id: 0 这个链接的变量是 INDEX，路径是博客地址。

既然存在变量，就需要先到申明变量为何物的文件中设置好变量的名称。在 assets/i18n/basic 中可以看到 en-US.json 等 6 个文件，所对应的就是 blog.config.js 中设定好的语言。于是，我就在 zh-CN.json 中修改和增加了导航栏变量和显示名称。

Copy
// 修改之前
"NAV": {
"INDEX": "博客",
"RSS": "订阅",
"SEARCH": "搜索",
"ABOUT": "关于"
},

// 修改之后
"NAV": {
"INDEX": "Blog",
"RSS": "RSS",
"SEARCH": "Search",
"ABOUT": "About",
"Page": "Page",
"Newsletter":"Newsletter"
},

考虑到我增加了 Newsletter，会跳转我在小报童的付费专栏订阅，那么 RSS 再显示为订阅会产生语义分歧。所以干脆把所有的变量显示名称全都改成了英文。

修改完 zh-CN.json 后，我就在 Header.js 中修改了导航栏中各条链接的显示顺序，并删除了 About（内容移动到 Page 页）。

以上的代码内容修改完后，我回到了 Notion，在 Nobelium 的数据库中增加了两个 type 为 Page 的页面，其中一个的 title 为 Newsletter，slug 留空（因为已经在代码中添加）；另一个的 title 为 Page，slug 为 page。

页脚

Nobelium 的默认页脚左边为 © 昵称 博客起始年份 - 现在的年份，右边为 ▲ Powered by Vercel。

我觉得这样不美观，就想着把左边的 © 昵称 博客起始年份 - 现在的年份 移动到右边，把 ▲ Powered by Vercel 移动到 Page 页，左边则显示带有 Copyright 页面链接的 Creative Commons 图标。

在 components/Footer.js 中看了半天，也不知道该怎么修改。于是问了 ChatGPT，他直接帮我生成了代码，复制粘贴进去之后，重新部署后美观了许多。

代码块

我发现在深色主题中，代码块的颜色依然是浅色，晚上看着十分扎眼。搜索了一番后，找到了 Leon 在《记录新博客：nobelium, Vercel, Tailwind CSS 和域名》中也提到了这一点，他用了 Prism.js 提供的深色背景 prism-tomorrow.css，还修改了 notion.css 的代码。我没有那么麻烦，直接到 pages/_app.js 中把原本引用的 prism.css 做了替换。

Copy
// 替换前
import "prismjs/themes/prism.css";

// 替换后
import "prismjs/themes/prism-tomorrow.css";

字体

一直都很喜欢在 GitHub 上开源的霞婺字体，在之前还在用 Typecho 的时候就想着把字体换成霞婺文楷，但没有成功。这一回怎么着都得尝试一下。

我看到 public/fonts 中有四个 woff2 的字体文件，于是找到了霞鹜文楷的 LXGW Bright GB 版本，下载并上传了 LXGWBrightGB-Regular.woff2。

之后先是在 styles/globals.css 中声明了字体。

Copy
@font-face {
font-family: 'LXGWBrightGB-Regular';
src: url('/fonts/LXGWBrightGB-Regular.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}

然后在 tailwind.config.js 中添加了字体。

Copy
// 修改前
fontFamily: {
sans: FONTS_SANS,
serif: FONTS_SERIF,
noEmoji: [
'"IBM Plex Sans"',
'ui-sans-serif',
'system-ui',
'-apple-system',
'BlinkMacSystemFont',
'sans-serif'
]
}

// 修改后
fontFamily: {
lxgw: ['LXGWBrightGB-Regular', 'sans-serif'],
sans: FONTS_SANS,
serif: FONTS_SERIF,
noEmoji: [
'"IBM Plex Sans"',
'ui-sans-serif',
'system-ui',
'-apple-system',
'BlinkMacSystemFont',
'sans-serif'
]
}

再到 components 文件夹中修改了 ****Container.js 和 NotionRenderer.js 两个文件。

终于，我在博客上配置好了霞婺字体，实现了一个心愿。

完善

代码部分的修改完成，接下来就是回到 Notion 中，在 Nobelium 数据库中完善博客的内容了。

我首先完善的是 Page 页面中的内容。我将 Page 页面定义为博客的独立页面入口，它本应该只是一个不带链接的菜单按钮，其架构在理想状态下是这样的：

Copy
Page
├──── [Memos](https://memo.hhzz.plus/explore)
├──── [File Gallery](https://file.hhzz.love)
├──── [Monitor](https://monitor.hhzz.plus/status/public)
├──── [About](https://justgoidea.com/about)
├──── [Copyright](https://justgoidea.com/copyright)
└──── [Friend Link](https://justgoidea.com/links)

因为 Nobelium 目前还不支持二级菜单（submenu），为了保持导航栏的简洁，只能将我的 Memos，File Gallery，Monitor 这三个独立页面，和原本应该在 About 和 Friend Link 中呈现的内容都放到 Page 页面中。

Memos 是我利用 GitHub 上的仿 flomo 的开源项目 memos 自部署的一个快速备忘录。这里存放着一些目前不成熟的想法，也可以把它看作是我的私人「Twitter」。目前的分类包括 #闪念，#思考，#碎碎念，#吐槽，#推荐等。

File Gallery 是一个资源分享站，收集到好玩的、实用的资源会存放在里面。

Monitor 是一个监控站点，用来监控我在网络中部署的网站、服务和 VPS 的运行情况。

About 则分为了 About This Site 和 About Me 两部分书写。

在 About This Site 中列举了博客的名称（标题），网址，Logo，描述（副标题），版权声明，技术建构，DNS 和 CDN 服务，以及使用的字体。因为将页脚的 ▲ Powered by Vercel 移除了，所以在技术声明中，进行了说明，同时也表达对 Vercel 的感谢。同样的，我使用了 Cloudflare 做 DNS 和 CDN 服务，使用了霞婺字体，这两者和 Vercel 一样都提供了非常好用的免费的服务，也理应说明并表示感谢。另外，还写了一小段我一直坚持写博客的初衷。

在 About Me 中，简单描述了我的 MBTI 人格、身份和职业，写了我的座右铭，留了我的 Email 和 Twitter。

完善 Page 页面的内容后，我又制作了 Copyright 页面并修改了 Footer.js ，使左侧的 Creative Commons 图标指向了这个页面。

总结

博客原本就应该纯粹，用于记录与分享。Notion 非常好用，Nobelium 非常简洁，满足了我对博客的全部需求。在这个过程中，我也学习到了许多知识，比如关于 Tailwind CSS 和 Next.js，我依然不入门，但至少能看懂了，也知道该怎么样向 ChatGPT 提问以输出我想要的代码。接下来，就是认真梳理与思考该怎么样继续提高文字的水准了。