📅 ⏱️ 7 分钟阅读
🏷️ 折腾
Make Notion Great Again!

动机

之前的 blog 方案一直是使用 Gridea 生成静态页面搭配 Vercel 托管。Gridea 是一个很棒的工具,但作者已经很长时间没有更新了


另一方面,在写作的过程中还是感到 Markdown 的表达能力不足,很多时间都要靠插入 HTML 或使用外挂的插件才能实现预期排版or样式。

最简单的例子就是空行,Markdown 是会忽略多行空行的,而现代电子设备屏幕上的文字排版非常依赖空行来做分段(相对应纸质时代是采用首行缩进的方式),但在 Markdown 中却还要通过 <br/> 手动空行

有时还想有个单独的页面记录自己的旅行地图或摄影作品,显然这些要在基于 Markdown 的方案中实现都十分困难,就连图片管理都不方便

是时候摆脱 Markdown 的束缚了


还有一个原因是,我在个人的记录、信息整理中都重度使用了 Notion,保守估计在其中存放了上千个页面。与此同时,blog 却需要使用一个单独的工具来进行写作和管理,这也让我感到麻烦,很大程度上影响了写作的欲望(终于找到不更新的理由了


Notion-based blog

Notion 有很强的表达能力,block 和 database 的设计都是很大的创新,这些设计和功能被各种云文档和笔记软件抄了一遍又一遍,足以见其影响

现在又集成了 LLM,对写作更方便了。所以很早之前我就想,能否将 blog 也搬到让 Notion 上,让 all in one 更加彻底呢?


不过 Notion 并不是一个建站工具,虽然有提供公开页面的站点功能,但充其量也只是公开页面/文章,离站点还差了点味道,只能说勉强能用,绑定自定义域名还需要额外 10 刀一个月

而且要进行比较好的管理,就肯定得用 Notion 的 database,这时候如果直接使用站点功能,用户进来看到的就是一个表格,这很奇怪(虽然有其他view,但那些玩意没好到哪去,说到底是 database 目的是管理数据而不是展示数据)

如果将 Notion & Database 的组合在这里看作一个 Backend/Database as a Service,提供的是数据,那么还缺的就是面向最终用户的前端页面,这就是 Notion-based 建站方案需要解决的问题


好在有这个想法的人并不少,有很多优秀的第三方 Notion-based 建站工具,例如 noto, potion, super 等,但这些大都是 SaaS 产品,免费计划对功能和页面量有严格限制

后来也考虑过基于 NotionX/react-notion-x 这个 Notion block 的渲染库自己实现,不过这只是个渲染库,离搭出一个能用的产品还差了很多上层功能,加上我实在不想写太多前端代码,只能作罢

直到最近偶然刷到了 tangly1024/NotionNext ,在功能上基本满足了我的想象,可以自托管,也能直接生成静态页面,是开箱即用的。并且 MIT license 开源意味着可以自由定制修改甚至商业化(或许未来可以整个自己的 Notion 建站 SaaS 产品),不需要额外成本(除了折腾的时间),于是决定这次将 blog 迁移过来


实施

虽然 NotionNext 在功能性上满足我的要求,但还要进行一些小调整(例如去掉一些审美堪忧才会喜欢的花里胡哨鼠标特效,和有了 tag 却还要存在的意义不明的 category,以及乱加的与 Notion 相悖的样式),同时移植原先 blog 的主题 xxxuuu/gridea-theme-autumn 到 NotionNext 上

fork 了 NotionNext,花了一个周末来完成这些修改和移植(还是写了不少前端代码 真痛苦


NotionNext 改造完成后,还得把原先的文章搬到 Notion 中,Notion 能直接导入 Markdown,但有些样式(特别是代码块)会有奇怪的换行问题。所以最后还是手动 copy 并调整的,好在文章数量不多。在这个过程中看到自己以前写的东西,稍微有些感叹,原来当时那么弱智青涩,不过这就是记录的意义吧


NotionNext 可以直接作为服务端运行,但我不想维护一个额外的服务器。Vercel 之类的服务对这种有动态 API 和网络请求的 project 也有严格的资源限制

所以计划和之前一样生成静态页面推送到仓库,仓库更新就会触发 Vercel 部署。这样还能复用原来的仓库 xxxuuu/xxxuuu.github.io 和 Vercel project


不过这样还需要解决的一个问题是,站点无法动态更新。每次编辑完后要重新生成一下静态页面。在之前 Gridea 中点击一下发布就会自动完成这些操作,在 NotionNext 中就得执行 yarn exportgit push,显然有些麻烦。于是我将这个操作丢到了 Github Action 中,定时或手动 run 一下就行

Image

其实也可以直接为 NotionNext 仓库创建一个新的 Vercel project,设置 build command 为 yarn export。每次更新在 Vercel 中 redeploy 就可以了,但我绕一圈的目的主要是想将 NotionNext 的仓库和最终成品的静态页面仓库分离开来


最终效果:

Image

现在 blog 所有的编辑和管理都可以在 Notion 中完成



样式测试

💡
测试 Notion 各种元素能否正常显示,源自 react-notion-x test suite,与正文无关


Text

All kinds of text styling options are supported. Basic text blocks are akin to HTML <p> tags. Text blocks also support a variety of rich text formatting options.


gray brown orange yellow green blue purple pink red


gray bg

brown bg

orange bg

yellow bg

green bg

blue bg

purple bg

pink bg

red bg


Image

Image


Quote

This is an example quote.


Callout

💻
This is a basic callout.
It can contain blocks and rich text. 💪


Divider



Linked Block

The following block is linked to the content of a global footer block.

©️

Copyright 2025 Travis FischerCC0 License

HomeGitHubTwitter


Lists

  • Bulleted lists are supported
  • Second Items
    • Nested 1
      • Nested 2
  • Back at top level
    • Child 1
    • Child 2


  1. First Item
  2. Second
  3. Third
    1. First Nest
    2. Second Nest
      1. Deeply nested
    3. Third Nest
  4. Last


  • Pretty URLs
  • Custom domains
  • Google Fonts
  • Page title/description for SEO
  • Custom scripts
  • A setup wizard to customize the script (instead of having to change the raw code)
  • Stop random pages from showing up under custom domain
  • Hide the What's New banner


Normal Toggle

Content inside here.


Code Blocks

basic code

Typescript
/**
 * Base properties shared by all block types.
 */
export interface BaseBlock {
  id: ID
  version: number
  created_time: number
  last_edited_time: number
  parent_id: ID
  parent_table: string
  alive: boolean
  created_by_table: string
  created_by_id: ID
  last_edited_by_table: string
  last_edited_by_id: ID
  space_id?: ID
  properties?: any
  content?: ID[]
  type: BlockType
}


mermaid

flowchart LR
    subgraph subgraph1
        direction TB
        top1[top] --> bottom1[bottom]
    end
    subgraph subgraph2
        direction TB
        top2[top] --> bottom2[bottom]
    end
    %% ^ These subgraphs are identical, except for the links to them:

    %% Link *to* subgraph1: subgraph1 direction is maintained
    outside --> subgraph1
    %% Link *within* subgraph2:
    %% subgraph2 inherits the direction of the top-level graph (LR)
    outside ---> top2
Flowchart
quadrantChart
    title Reach and engagement of campaigns
    x-axis Low Reach --> High Reach
    y-axis Low Engagement --> High Engagement
    quadrant-1 We should expand
    quadrant-2 Need to promote
    quadrant-3 Re-evaluate
    quadrant-4 May be improved
    Campaign A: [0.3, 0.6]
    Campaign B: [0.45, 0.23]
    Campaign C: [0.57, 0.69]
    Campaign D: [0.78, 0.34]
    Campaign E: [0.40, 0.34]
    Campaign F: [0.35, 0.78]
Quadrant Chart
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'MetroLine1'}} }%%
      gitGraph
        commit id:"NewYork"
        commit id:"Dallas"
        branch MetroLine2
        commit id:"LosAngeles"
        commit id:"Chicago"
        commit id:"Houston"
        branch MetroLine3
        commit id:"Phoenix"
        commit type: HIGHLIGHT id:"Denver"
        commit id:"Boston"
        checkout MetroLine1
        commit id:"Atlanta"
        merge MetroLine3
        commit id:"Miami"
        commit id:"Washington"
        merge MetroLine2 tag:"MY JUNCTION"
        commit id:"Boston"
        commit id:"Detroit"
        commit type:REVERSE id:"SanFrancisco"
Gitgraph Diagram


bookmark

Google
Search the world’s information, including webpages, images, videos and more. Google has many special features to help you find exactly what you’re looking for.
google.com.hk


没有特殊处理的普通站点的 mention 会显示异常,比如 https://google.com

mention:

Inline styled text NotionX/react-notion-x and more after


block

GitHub - NotionX/react-notion-x: Fast and accurate React renderer for Notion. TS batteries included. ⚡️
Fast and accurate React renderer for Notion. TS batteries included. ⚡️ - NotionX/react-notion-x
github.com


Tables

123
456
789


Column Layouts

one

two

three

four

five

Image
This is a caption
This is a caption
Image

Nesting works just fine.

It is also responsive.



Equations

Block

$$[ x^n + y^n = z^n ]$$
$$\displaystyle \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\cdots} } } }(ϕ5−ϕ)e52π1=1+1+1+1+1+⋯e−8πe−6πe−4πe−2π$$
$$\displaystyle \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)(k=1∑nakbk)2≤(k=1∑nak2)(k=1∑nbk2)$$
$$\displaystyle {1 + \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots }= \prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})}, \quad\quad \text{for }\lvert q\rvert<1.1+(1−q)q2+(1−q)(1−q2)q6+⋯=j=0∏∞(1−q5j+2)(1−q5j+3)1,for ∣q∣<1.$$


Inline

This is an example of an inline equation: y = mx + b

500ms + 80ms + 500ms = 1080ms = 1.08 seconds

You can also add formatting:

x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}


Databases

名称标签数字单选多选复选框日期
AAA123123AA📅 2024/8/21
BBB321231.1321-BC📅 2024/8/26 - 2024/8/28
CCCabc-C-📅 2024/8/7


Embed

PDF


YouTube

This is a caption


twitter


Spotify Playlist


Google Maps


加载评论中...