开源这个博客的源码 — Notionic

slug
notionic
date
Apr 26, 2022
summary
在 Nobelium 的基础上修改而来, 增加了侧边栏大纲, 主题切换, 语言切换, 原生评论, 联系表单等等功能, 还支持子页面渲染, 且集成了 Craft.do 分享页面到站点中.
tags
Website
Craft.do
Notion
Next.js
status
Published
type
Post
Notionic 是一个实时更新的静态博客, 无需重新构建部署便可以同步 Notion 页面的变更.
Notionic 是 Nobelium 的一个衍生版本, 通过 Next.js 的增量静态渲染 (Incremental Static Regeneration) 功能实现即时渲染静态页面, 支持部署到 Vercel, Netlify, Fly.io 等服务上, 但不支持 Cloudflare Pages 和 Github Pages 等服务.

已实现的功能有:
实时增量更新渲染
文章大纲
主题切换
多语言切换
页面加载和过渡动画
支持子页面 (block page)
支持数据库外部页面 (指定 space 下任意公开页面都可以渲染)
SEO 和 Open Graph 优化
周刊页面
贴合网站风格的评论区
联系表单
Telegram 通知集成
支持 Craft.do 页面

你可以在下面 Github 仓库找到本站的全部代码:

快速部署

  1. 复制下面的 Notionic 模板到你的空间下, 并分享给所有人.
  1. 点击 Fork 分叉这个项目到你的 Github 账号下.
      • 替换 /public 目录下的资源, 使用你自己的图标 Logo 等等.
  1. 在 Vercel 中部署项目, 并设置以下环境变量:
      • NOTION_PAGE_ID (必填), 你公开分享的 Notion 页面 ID (如图所示).
      • NOTION_SPACES_ID (可选), 你的 Notion 空间 ID, 详情请看下面 子页面解析 部分内容.
      • TELEGRAM_TOKEN (可选), 新增评论和联系表单通知会发到 Telegram 上.
  1. 稍等一会就部署完成了.
💡
如果有问题, 点此 可以快速联系我.

文章大纲

在 Notionic 编辑器里插入一个 /toc 就可以显示文章大纲了.

多语言

多语言这个功能没有使用其他依赖库, 只在 Next.js 原生 i18n 支持下配合 next/router 实现了这个功能. 如果你要新增或者修改网站的语言或者文案, 只需要打开 lib/lang.js 修改其中的内容即可.
💡
目前全站的文本内容都已经"提炼"到这个 lib/lang.js 文件, 也就是说你可以在这个文件中修改全站每一处的文本内容.
如果需要新增语言, 首先在 lang.js 后面按格式添加你的语言和相对应的翻译, 然后在 next.config.js 中修改 i18n 的配置.
如下所示, 请确保两个文件中语言的缩写一致, 举个例子:
  • 如果你在 lang.js 中新增了新语言, 名为 zh-HK
// lib/lang.js export const lang = { zh: { ... }, zh-HK: { ... }, en: { ... }, ja: { ... }, es: { ... } }
  • 那么在 next.config.js 中也需要配置一样的语言缩写 zh-HK 才会生效
// next.config.js i18n: { locales: ['en', 'zh', 'zh-HK', 'ja', 'es'], // 如果想修改默认语言, 可以改动 defaultLocale 这个配置. defaultLocale: 'zh', localeDetection: false },
目前的语言切换按钮只支持在两种语言之间切换. 需要修改切换的语言, 可以编辑 components/LangSwitcher.js 里的表达式, 当前是中英两个语言之间切换.
<Link locale={locale === 'en' ? 'zh' : 'en'} passHref href={asPath}>

子页面和外部页面解析

子页面解析默认开启, 为了安全起见, 你应该设置 NOTION_SPACES_ID 这个环境变量, 否则任何人都可以通过你的域名解析其他人的 Notion 页面.
💡
你可以通过下面步骤找到你的 NOTION_SPACES_ID:
  • 在 Vercel 或其他地方成功部署后, 打开你的站点, 点击打开任意一篇文章
  • 鼠标右键, 选择”显示网页源代码”, 在源代码页面搜索 space_id 这个关键字, 第一个找到的就是你要的 NOTION_SPACES_ID 啦.
  • 在 Vercel 项目设置的环境变量里填上 NOTION_SPACES_ID 和对应值即可.
如此一来, 站点只能解析你指定的 Notion 空间下的页面, 别人无法通过你的站点解析任意 Notion 页面了.
🎉
这是一个子页面示例

周刊 Newsletter

Nobelium 本身支持了两种类型的文章, 分别是 Post 和 Page, 对应了博客文章和博客页面, 我新增了一个类型 Newsletter, 它和 Post 类似, 但不会出现在首页的博客文章列表中.
当你在自己的 Notion 数据库里新建一个页面时, Type 选择 Newsletter (没有就在数据库里新建一个) 时, 该页面就不会显示在博客文章列表中, 而是显示在周刊 Newsletter 那一页.

评论区

因为 Nobelium 已经支持的评论系统似乎都不太好用, 或者和网站主题风格不搭. 所以就自己动手搞了一个, 这样评论区看起来和网站风格比较一致.
评论内容存储在 Supabase, 免费版已经完全够用. 要配置这个评论区, 你需要注册一个 Supabase 的账号, 然后新建一个数据库, 再新建一张名为 comments 的表, 表结构如下:
id - int8 name - text email - text postURL - text comment - text created_at - timestamp show - boolean
表结构参考表结构参考
表结构参考
然后在数据库的 settings —> api 页面复制 anon keyURL, 把它粘贴到 blog.config.js 文件里的 supaCommentsConfig 那两行中, 并修改 providersupacomments.
是 anon key, 不是 secret, 不要复制错了.是 anon key, 不是 secret, 不要复制错了.
是 anon key, 不是 secret, 不要复制错了.
provider: 'supacomments', // leave it empty if you don't need any comment plugin supaCommentsConfig: { supabaseUrl: '', // The url of your Supabase instance supabaseAnonKey: '', // The anonymous key of your Supabase instance },
这样评论区就配置完了. 值得一提的是, 如果你配置了 TELEGRAM_TOKEN (参考下面联系表单), 那么当有人发表评论时, 你的 Telegram 同样也会收到通知.
目前评论区的代码还没开源, 因为有一些细节还没搞定, 但是并不影响使用. 打包后的代码我放在了 public/comment 目录, 目前已经适配了中英两个语言.

💡
更新于 2022 11-22
我发现 Supabase 数据库现在要强制开启 RLS(行级安全) 了, 可以参考下图:
行级安全配置示意, 添加两个策略: 只允许查看和插入数据行级安全配置示意, 添加两个策略: 只允许查看和插入数据
行级安全配置示意, 添加两个策略: 只允许查看和插入数据
📌
行级安全配置详细说明

💡
如果出现 “data-url 配置错误” 的信息, 请检查你的 blog.config.js 文件里的 link 那一项. 浏览器访问的域名和 link 中的域名一致时, 评论区才会显示.

联系表单

联系表单会把提交的内容发送到 Telegram 里, 即便访客在国内也可以把内容发送到 Telegram. 因为它是通过 Vercel 的边缘函数给 Telegram 发送信息的, 所以不存在 Telegram 被墙发不出去的情况.
要配置这个表单, 你需要先创建一个 Telegram 机器人. 然后和 @BotFather 机器人交互, 获取你的 bot 的 API token.
类似 Nobelium 部署时添加的 NOTION_PAGE_ID 环境变量一样, 你需要在 Vercel 后台添加一个变量, 名为 TELEGRAM_TOKEN, 值就是你申请到的 API token.
最后修改 blog.config.js 里的 telegramChatId 那一项为你的 chat id (可以询问 Telegram 机器人 @chatIDrobot), 这样你的联系表单就配置好了.
💡
记得要和你创建的机器人互动一下, 给它发个 /start, 不然机器人无法给你发消息.

Craft.do 分享页面

最后还加入了对 Craft.do 的支持, 可以实时生成一个 Craft.do 的页面列表, 并反代了 Craft.do 的分享页面. 具体可以点击导航栏的 笔记 查看效果.
Craft.do 同样是我很喜欢用的一个软件, 而且 Craft.do 的分享页面做得很出色, 早在去年我便写过一个 Cloudflare Worker 的脚本用来自定义 Craft.do 分享页面的域名. 后来我发现 Next.js 也支持一定程度的 rewrite, 可以做到类似 Cloudflare Worker 的功能, 于是我便把 Craft.do 也整合到这个博客中了.
这里有一个配置页面的示例, 你可以复制到你的空间, 然后修改 (如何修改可以参考我的这篇文章), 再把你的配置页面分享链接粘贴到 blog.config.js 里的 craftConfigShareUrl 就可以了, 网站会自动生成笔记页面.
如果你的 Craft.do 配置页面格式不正确, 在生成的笔记页面底部会有一行字提示你. 自己核对一下 craftConfigShareUrl 页面内容的格式.
💡
如果你不喜欢这个功能, 你只需要删掉 pages/notes.js 这个文件, 就看不见这个页面了.

最后, 这里还有一个去掉了 Notion 相关代码的版本, 只保留了 Craft.do 的相关功能. 我把它也开源出来, 供有需要的人参考使用.

扩展 1: 自定义 Logo

我的站点 Logo 用的是 svg 格式的图片, 很多都直接写进代码里了. 所以修改可能会麻烦一些, 按照步骤修改, 如果有问题可以私信联系我.
💡
网站标签页的图标
public 文件夹里的 favicon 图标文件都换成你自己的.
💡
左上角的 Logo
Logo.js 中修改. 你可以把你的 svg 图片贴到代码里, 替换我的 svg 标签. 也可以把 svg 标签都删掉, 用图片作为 Logo.
💡
首页右侧和 Loading 页面的 Logo
components/Hero/ 这个文件夹里面, 我放了两种类型的 Avatar 示例, 其中一个叫做 NotionAvatar.js, 另一个叫做 Avatar.js. 你可以在这两个网站中看到他们的区别:
如果你想修改 NotionAvatar 中的手绘风格人物形象, 可以在这个网站上生成你的形象, 然后参考下面的说明:
👤
Avatar 修改方法

最后, Loading 的图标修改方法参考下面的子页面:
🔃
Loading 图标修改

扩展 2: Open Graph 生成器

因为找不到对中文字体友好, 并且体积小巧+性能出色的 og 生成器, 所以自己动手做的一个小工具, 用来给我的网站生成 og 图片, 源代码在这里:
Notionic 默认配置的 og 地址便是这个, 如果不需要自定义更多细节, 使用默认的服务地址就行.

扩展 3: 图片链接失效

因为 Notion 的外链图片有 48 小时失效这个限制, 所以构建站点 48 小时之后, 来自 Notion 的图片就会加载不成功. 这时候重新触发一次构建即可刷新图片链接.
下面以在 Vercel 部署为例, 在 Vercel 管理后台, 对应项目内的 Settings > Git 设置页面中, 创建一个 deploy hook:
notion imagenotion image
在代码仓库里新建一个目录结构 .github/workflows 并在里面新建一个文件叫 cron.yaml, 最终结构如下图:
notion imagenotion image
name: auto-update-cron on: schedule: - cron: '0 0 * * *' jobs: build: name: Trigger Site Rebuild runs-on: ubuntu-latest steps: - name: Call Vercel Hook run: curl -X POST "https://api.vercel.com/v1/integrations/deploy/prj_xxxxxxxxx/ooooooooo?buildCache=false"
文件的代码如上, 配置里的 url 改成你新建的那个 deploy hook 地址. 设置好后 Github 会每天 0 点通知 Vercel 重新构建站点, 这样你的照片就不会失效了.
 
对于本文内容有任何疑问, 可与我联系.