Technical Documentation: tangly1024/NotionNext
ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference
Overview (README.md)
NotionNext 是什么?
NotionNext 是一个基于 Next.js + Notion API 的开源站点系统。你继续用 Notion 管理文章、分类、标签、菜单和页面,NotionNext 负责把这些内容发布成可访问、可搜索、可运营的独立网站。
它适合想长期沉淀内容的人:内容创作者、独立开发者、设计师、摄影师、课程作者、开源项目维护者,以及需要快速搭建产品官网或知识库的小团队。
你可以用它做什么?
| 目标 | 推荐入口 | 适合人群 |
|---|---|---|
| 搭个人博客 | 从这里开始 | 内容创作者、独立开发者、学生 |
| 做作品集或个人品牌站 | 按场景选主题 | 设计师、摄影师、自由职业者 |
| 做产品官网或 SaaS 落地页 | Starter / Landing / Proxio | 创业者、独立产品、小团队 |
| 做知识库或文档站 | GitBook / Claude | 开源项目、课程作者、团队文档 |
| 做导航站或资源聚合 | Nav 主题 | 资源整理者、社群运营者 |
为什么选择 NotionNext?
- 不换写作工具:文章、分类、标签、封面、菜单仍在 Notion 中维护。
- 上线路径短:复制 Notion 模板、Fork 仓库、连接 Vercel,即可部署。
- 主题选择多:内置 26 个主题,覆盖博客、文档、作品集、官网、相册、导航站等场景。
- 适合长期运营:支持独立域名、SEO、Sitemap、RSS、评论、统计、搜索、广告和邮件订阅。
- 开源可控:源码、配置和主题都在自己的仓库里,后续可以继续二次开发。
- 数据链路清晰:Notion 负责内容沉淀,站点负责展示和分发,后续可迁移到 Markdown 或其他系统。
20 分钟部署路线
- 打开 主题预览站 看最终效果。
- 复制 NotionNext 官方 Notion 模板。
- Fork 本仓库到自己的 GitHub 账号。
- 使用 Vercel 部署 NotionNext。
- 在环境变量中填写 Notion 页面 ID 等配置。
- 部署成功后,按场景选择主题并补齐域名、评论、统计、搜索等功能。
新手建议直接从文档站的 从这里开始 阅读。
主题与预览
- 在线切换主题:preview.tangly1024.com
- 26 个内置主题:主题全览
- 仓库内主题文档:docs/user-guide/themes/
| 场景 | 优先看 |
|---|---|
| 个人博客 | simple、hexo、nobelium、typography |
| 文档 / 知识库 | gitbook、claude、thoughtlite |
| 作品集 / 个人品牌 | opc、proxio、starter、landing |
| 产品官网 | starter、landing、commerce |
| 图片 / 摄影 | photo、plog、magzine |
| 导航站 | nav |
本地开发
推荐使用 Node 22 和 Yarn 1。Node 20 已无法安装当前依赖(@ai-sdk/google 要求 Node >=22),部署平台也需要同步设置为 Node 22。
# 1. 使用 Node 22
nvm use || nvm install
# 2. 安装 Yarn
npm i yarn
# 3. 安装依赖
yarn
# 4. 启动开发
yarn dev常用命令:
| 命令 | 用途 |
|---|---|
yarn dev |
启动本地开发 |
yarn build |
构建生产版本 |
yarn export |
静态导出 |
yarn docs:site:dev |
本地预览文档站 |
yarn docs:site:build |
构建文档站 |
文档入口
自 2026 年起,NotionNext 使用仓库内 Markdown 文档作为主要教程来源,并发布为独立文档站。
| 内容 | 链接 |
|---|---|
| 在线文档站 | notionnext.tangly1024.com |
| 新手入口 | 从这里开始 |
| 场景模板 | 按目标选择模板 |
| 配置索引 | 全站功能与配置索引 |
| 主题说明 | 26 个主题说明 |
| 用户作品 | Showcase:已上线站点欢迎提交作品 |
| 文档源码 | docs/ |
| 旧版手册 | docs.tangly1024.com |
参与社区
NotionNext 主仓库由 GitHub 组织 notionnext-org 维护。欢迎提交问题、补充文档、贡献主题、修复代码或参与讨论。
| 内容 | 链接 |
|---|---|
| 参与社区 | community-participate.md |
| 5.0 愿景与路线图 | VISION_ROADMAP.md |
| 贡献指南 | CONTRIBUTING.zh-CN.md |
| 项目治理 | GOVERNANCE.zh-CN.md |
| 维护者 | MAINTAINERS.md |
| 行为准则 | CODE_OF_CONDUCT.md |
| 讨论区 | GitHub Discussions |
如果你在仓库转让前已克隆旧地址,建议更新远程仓库:
git remote set-url origin https://github.com/notionnext-org/NotionNext.git
git remote -v技术栈
- 框架:Next.js
- 样式:Tailwind CSS
- 渲染:react-notion-x
- 评论:Twikoo、Giscus、Gitalk、Cusdis、Utterances
- 部署:Vercel
相关项目
- Elog:Markdown 批量导出工具,支持组合 Notion、语雀、FlowUs、飞书等写作平台与 Hexo、VitePress、Halo、WordPress 等博客平台。
致谢
感谢 Craig Hart 发起的 Nobelium 项目。
| Craig Hart |
|---|
感谢每一位参与代码、主题、文档、Issue、Review 与发布维护的贡献者。
使用声明
本项目为免费、公开资源,仅限个人学习和合法站点建设使用。禁止利用本项目发布非法内容或进行违法活动。
License
The MIT License.
Project Stars
Live star-history charts are temporarily unavailable because GitHub now restricts historical stargazer data to repository owners and collaborators.
README (`docs/README.md`)
NotionNext 文档(`docs/`)
| 在线阅读 | https://notionnext.tangly1024.com |
| 参与社区 | user-guide/community-participate.md · GOVERNANCE.zh-CN.md |
| 参与维护 | 在线页底「在 GitHub 上维护此页」· user-guide/maintain-docs.md |
| 致谢贡献者 | user-guide/acknowledgements.md · Contributors |
| 旧版手册 | user-guide/help/legacy-docs.md · 源站 docs.tangly1024.com |
本目录结构
docs/
├── index.md # 在线站首页
├── DOCUMENTATION_POLICY.md # 在线:文档维护策略
├── user-guide/ # 在线:部署、配置、主题、运营与维护教程
├── developer/ # 在线:架构、贡献、主题迁移与维护文档
└── community/ # 在线/仓库共用:社区活动与讨论材料在线站包含什么
user-guide/、developer/、community/,以及根目录 index.md、DOCUMENTATION_POLICY.md。
构建命令:yarn docs:site:build → 发布到 notionnext.tangly1024.com。
文档方向
文档站不再把使用者和开发者分开。新用户可以从 user-guide/ 完成部署和配置,随后继续阅读 developer/ 理解运行原理、修改主题、用 AI 辅助开发并提交贡献。
如何改教程并上线
- 编辑
user-guide/或developer/下对应.md - 本地预览:
yarn docs:site:dev - 合并
main→ GitHub Actions 自动部署
详见 user-guide/maintain-docs.md · user-guide/MAINTENANCE_WORKFLOW.md
社区与治理(仓库根目录)
- 参与社区(在线站可见)
- GOVERNANCE.zh-CN.md · MAINTAINERS.md · CODE_OF_CONDUCT.md
- Discussions · CONTRIBUTING.zh-CN.md
Org 管理员还需在 GitHub 启用 Discussions、Giscus App、分支保护等,见治理文档末尾清单。
开发文档
Index (`docs/index.md`)
layout: home
hero:
name: NotionNext
text: 把 Notion 变成可长期运营的独立站
tagline: 继续在 Notion 写作和维护内容,用开源、自托管、可定制的方式发布为博客、作品集、知识库、导航站或产品官网。
image:
src: /brand/notionnext-logo.svg
alt: NotionNext Logo
actions:
- theme: brand
text: 开始搭建
link: /user-guide/start-here
- theme: alt
text: 浏览主题
link: /user-guide/themes/THEMES_CATALOG
- theme: alt
text: 用户作品
link: /user-guide/showcase
- theme: alt
text: 部署到 Vercel
link: /user-guide/deploy-vercel
features:
- title: 不换写作工具
details: 文章、分类、标签、菜单和页面仍在 Notion 中维护,网站自动读取并渲染。 - title: 从模板到上线
details: 复制 Notion 模板、Fork 仓库、连接 Vercel,新手也能按步骤完成上线。 - title: 26 个内置主题
details: 覆盖博客、文档、作品集、官网、相册、导航站和视觉展示等场景。 - title: 面向长期运营
details: 支持独立域名、SEO、Sitemap、RSS、评论、统计、搜索、广告和邮件订阅。 - title: 开源可控
details: 源码、配置和主题都在你的仓库中,可按业务需要持续扩展。 - title: 可迁移的数据链路
details: Notion 负责沉淀内容,网站负责展示分发,后续可迁移到 Markdown 或其他静态站系统。
从内容库到网站
<h2>不是再造一个后台,而是把已有 Notion 内容发布出去</h2>
Notion 适合写作、整理和协作;独立站适合搜索、传播和长期沉淀。NotionNext 连接这两件事:你继续维护 Notion,网站负责把内容变成可访问、可检索、可运营的公开入口。
Notion 中维护
**文章、分类、标签、菜单、页面**
把内容结构留在熟悉的 Notion 数据库里,减少迁移和重复录入。
NotionNext 发布
**博客、作品集、文档站、官网**
选择主题、绑定域名、配置 SEO 和评论,把内容沉淀为自己的站点资产。先跑起来,再逐步精调
<a class="nn-step-card" href="/user-guide/start-here">
01
**确认路线**
先看 20 分钟部署路线,理解 NotionNext 适合哪些站点和需要准备什么。
</a>
<a class="nn-step-card" href="/user-guide/deploy-vercel">
02
**复制模板并部署**
复制官方 Notion 模板,Fork 仓库,连接 Vercel 完成第一次上线。
</a>
<a class="nn-step-card" href="/user-guide/themes/THEMES_CATALOG">
03
**选择主题和配置**
按博客、作品集、文档、官网等目标选主题,再补齐域名、搜索、评论和统计。
</a>主题预览
<h2>同一份 Notion 内容,可以长成不同类型的网站</h2>
[查看全部主题](/user-guide/themes/THEMES_CATALOG)
<a class="nn-theme-card" href="/user-guide/themes/landing">
**Landing**
产品官网和转化页
</a>
<a class="nn-theme-card" href="/user-guide/themes/proxio">
**Proxio**
SaaS、创业项目、服务介绍
</a>
<a class="nn-theme-card" href="/user-guide/themes/gitbook">
**GitBook**
知识库和项目文档
</a>
<a class="nn-theme-card" href="/user-guide/themes/photo">
**Photo**
摄影、作品集、视觉展示
</a>
<a class="nn-theme-card" href="/user-guide/themes/nav">
**Nav**
导航站和资源聚合
</a>
<a class="nn-theme-card" href="/user-guide/themes/next">
**Next**
个人博客和内容主页
</a>不同用户需要的不是同一张首页
<a href="/user-guide/start-here">
**内容创作者**
用 Notion 写文章,用独立域名沉淀搜索、订阅、评论和长期内容资产。
</a>
<a href="/user-guide/themes/THEMES_CATALOG#按场景选主题">
**独立开发者**
把产品介绍、更新日志、帮助文档和博客放在同一个可维护的站点里。
</a>
<a href="/user-guide/themes/THEMES_CATALOG#按场景选主题">
**设计师与自由职业者**
用作品集主题展示项目案例,保留 Notion 的低维护成本。
</a>
<a href="/user-guide/themes/gitbook">
**团队与课程作者**
把教程、知识库、FAQ 和项目文档发布成结构清晰的站点。
</a>为什么选择开源方案
<h2>托管服务追求省心,NotionNext 更强调可控</h2>
如果你只需要最短路径发布 Notion 页面,托管式服务很合适。NotionNext 更适合希望拥有源码、部署平台、主题样式和长期迁移能力的用户。
**源码在你的仓库**
可审计、可修改、可长期维护。
**部署在你的平台**
支持 Vercel、Netlify、Cloudflare Pages、VPS 等路径。
**主题可以继续演进**
从简单博客到产品官网,不必更换内容后台。
**数据链路可迁移**
Notion 是内容源,未来仍可迁移到 Markdown 或其他系统。已经上线?欢迎把你的站点提交到作品墙
Showcase 收集真实的 NotionNext 站点,帮助新用户按场景选择主题,也让社区成员的博客、作品集、知识库和产品官网被更多人看到。
[提交或查看用户作品](/user-guide/showcase)上线前最常被问到的几件事
NotionNext 和 Notion 官方公开页面有什么区别?
Notion 官方页面适合快速分享,NotionNext 更适合独立域名、主题定制、SEO、RSS、评论、统计、搜索和长期运营。
不会写代码可以使用吗?
可以按文档完成基础部署和配置。深度改主题、接入特殊服务或自定义交互时,具备前端基础会更从容。
内容数据会不会离开 Notion?
默认仍以 Notion 作为内容源,NotionNext 读取并渲染这些内容。你也可以逐步把内容迁移到其他系统。
应该先看哪些文档?
从 [零基础开始](/user-guide/start-here)、[Vercel 部署](/user-guide/deploy-vercel) 和 [主题全览](/user-guide/themes/THEMES_CATALOG) 三篇开始就够了。Developer README (`docs/developer/README.md`)
NotionNext 开发者文档
本目录 不 进入 notionnext.tangly1024.com。
站长向教程见../user-guide/· 在线站说明见../README.md。
中文 | English
入门与协作
| 主题 | 中文 | English |
|---|---|---|
| 快速上手 | GETTING_STARTED.md | GETTING_STARTED.en.md |
| 愿景与路线图 | VISION_ROADMAP.md | — |
| 可持续增长路线图 | GROWTH_ROADMAP.zh-CN.md | — |
| 开放生态长期计划 | LONG_TERM_PLAN.md | — |
| 主题色变量计划 | THEME_COLOR_TOKEN_ROADMAP.zh-CN.md | — |
| 主题控制台设计 | THEME_CONSOLE_DESIGN.zh-CN.md | — |
| 架构总览 | ARCHITECTURE.md | ARCHITECTURE.en.md |
| 目录与模块 | PROJECT_STRUCTURE.md | PROJECT_STRUCTURE.en.md |
| 配置体系 | CONFIGURATION.md | CONFIGURATION.en.md |
| 提交与 PR | CONTRIBUTION_WORKFLOW.md | CONTRIBUTION_WORKFLOW.en.md |
| 维护哲学 | MAINTENANCE_PHILOSOPHY.zh-CN.md | MAINTENANCE_PHILOSOPHY.en.md |
| 大改动 RFC | rfc/README.md | — |
| 维护者手册 | MAINTAINER_RUNBOOK.zh-CN.md | MAINTAINER_RUNBOOK.en.md |
| 项目治理 | GOVERNANCE.zh-CN.md | GOVERNANCE.md |
| 主题迁移 | THEME_MIGRATION_GUIDE.zh-CN.md | THEME_MIGRATION_GUIDE.md |
| 版本更新说明 | UPDATE.md | — |
| 社区路线图 | COMMUNITY_SITE_ROADMAP.md | — |
| 5.0 愿景与参与方向 | VISION_ROADMAP.md | — |
仓库贡献总则:CONTRIBUTING.zh-CN.md · 用户向 参与社区 · MAINTAINERS.md
主题开发者文档
站长向 26 篇说明在 ../user-guide/themes/。
| 目录 | 说明 |
|---|---|
| themes/README.md | 主题长文、存根、英文副本 |
| themes/CLAUDE.md 等 | 含全局 _app.js 等实现细节 |
其它
| 路径 | 说明 |
|---|---|
| performance/ | 主题性能审计记录 |
| ../DOCUMENTATION_POLICY.md | 文档维护策略(同时在线发布) |
Developer Index (`docs/developer/index.md`)
NotionNext 开发文档
NotionNext 文档不再把“站长教程”和“开发者文档”做成两个隔离区域。每个使用者都可以先完成部署和配置,再逐步理解运行原理、修改主题、提交 PR。
如果你刚开始搭建网站,先读 从这里开始。当你想改样式、改主题、排查问题或参与维护时,继续阅读本页下面的开发文档。
入门与协作
主题与生态
| 主题 | 文档 |
|---|---|
| 主题迁移 | THEME_MIGRATION_GUIDE.zh-CN.md · THEME_MIGRATION_GUIDE.md |
| 主题实现长文 | themes/ |
| 大改动 RFC | rfc/ |
维护资料
| 主题 | 文档 |
|---|---|
| 版本更新说明 | UPDATE.md |
| 社区路线图 | COMMUNITY_SITE_ROADMAP.md |
| 会员、权限与评论可选集成 | MEMBERSHIP_COMMENTS_ROADMAP.md |
| 5.0 愿景与参与方向 | VISION_ROADMAP.md |
| 项目治理 | GOVERNANCE.zh-CN.md · GOVERNANCE.md |
| 仓库贡献总则 | CONTRIBUTING.zh-CN.md |
User Guide ARTICLE INDEX (`docs/user-guide/ARTICLE_INDEX.md`)
官方文档迁移索引
源站:https://docs.tangly1024.com
本表由 node scripts/import-legacy-docs.mjs 从旧站导航和文章数据生成。正文已迁移到 docs/user-guide/,每篇文末保留旧站原文链接。
| 原栏目 | 原文 slug | 本地文档 |
|---|---|---|
| 入门 | about |
intro.md |
| ✨ 更新日志 | how-to-update-notionnext |
update.md |
| ✨ 更新日志 | latest |
changelog/latest.md |
| ✨ 更新日志 | v4.0 |
changelog/v4-history.md |
| ✨ 更新日志 | v3.0 |
changelog/v3-history.md |
| ✨ 更新日志 | V2.0 |
changelog/v2-history.md |
| ✨ 更新日志 | v1.0 |
changelog/v1-history.md |
| 🚀 安装部署 | vercel-deploy-notion-next |
deploy-vercel.md |
| 🚀 安装部署 | vercel-domain |
deploy/vercel-domain.md |
| 🚀 安装部署 | vercel-accelerate |
deploy/vercel-accelerate.md |
| 🚀 安装部署 | vercel-notionnext-notion |
development/architecture.md |
| 🚀 安装部署 | vercel-multi-sites |
deploy/vercel-multi-sites.md |
| 🚀 安装部署 | vercel-deploy-notion-next-static |
deploy/vercel-static.md |
| 🚀 安装部署 | vercel-redploy |
deploy/vercel-redeploy.md |
| 🚀 安装部署 | notion-next-cloud-flare |
deploy/cloudflare-pages.md |
| 🚀 安装部署 | notion-image-proxy |
deploy/notion-image-proxy.md |
| 🚀 安装部署 | deploy-notion-next-with-netlify |
deploy/netlify.md |
| 🚀 安装部署 | deploy-notion-next-with-edge-one |
deploy/edgeone-pages.md |
| 🚀 安装部署 | deploy-notion-next-on-vps |
deploy/vps.md |
| 🚀 安装部署 | notionnext-deploy-web3.0-4everland |
deploy/4everland.md |
| 🚀 安装部署 | deploy-notion-next-with-zeabur |
deploy/zeabur.md |
| ✒ Notion教程 | example-1 |
notion/example-article.md |
| ✒ Notion教程 | notion-backup |
notion/notion-backup.md |
| ✒ Notion教程 | start-to-write |
notion-database.md |
| ✒ Notion教程 | notion-template |
notion/notion-template.md |
| ✒ Notion教程 | notionnext-video |
notion/notionnext-video.md |
| ✒ Notion教程 | notion-short-key |
notion/short-keys.md |
| ✒ Notion教程 | notion-faster |
notion/faster.md |
| ✒ Notion教程 | how-to-add-link-for-text-in-notion |
notion/how-to-add-link-for-text-in-notion.md |
| ✒ Notion教程 | notionnext-hidden-page |
notion/notionnext-hidden-page.md |
| ✒ Notion教程 | notionnext-scheduled-article-release |
notion/notionnext-scheduled-article-release.md |
| ✒ Notion教程 | notion-tutorial |
notion/notion-tutorial.md |
| 🛠 站点配置 | cache-of-notion-next |
config/cache-of-notion-next.md |
| 🛠 站点配置 | how-to-config-notion-next |
config-site.md |
| 🛠 站点配置 | notion-next-inline-config |
config/notion-next-inline-config.md |
| 🛠 站点配置 | notion-next-guide |
config/site-basics.md |
| 🛠 站点配置 | notion-next-image-cover |
config/notion-next-image-cover.md |
| 🛠 站点配置 | use-github-as-image-hosting-service |
config/use-github-as-image-hosting-service.md |
| 🛠 站点配置 | notion-next-url-customize |
config/url-customize.md |
| 🛠 站点配置 | notionnext-notice |
config/notionnext-notice.md |
| 🛠 站点配置 | notion-next-secondary-menu |
menu-secondary.md |
| 🛠 站点配置 | notion-next-web-font |
config/notion-next-web-font.md |
| 🛠 站点配置 | notion-next-font-awesome |
config/notion-next-font-awesome.md |
| 🛠 站点配置 | notion-next-iconfont |
config/notion-next-iconfont.md |
| 🛠 站点配置 | notion-next-code-style |
config/notion-next-code-style.md |
| 🛠 站点配置 | notion-next-custom-properties |
config/notion-next-custom-properties.md |
| 🛠 站点配置 | notion-next-copy-permission |
config/copy-permission.md |
| 🛠 站点配置 | notion-next-article-copyright |
config/article-copyright.md |
| 🛠 站点配置 | notion-next-originality-proof |
config/originality-proof.md |
| 🛠 站点配置 | notion-next-mulity-languages |
config/notion-next-mulity-languages.md |
| 🛠 站点配置 | notion-next-site-combine |
config/notion-next-site-combine.md |
| 🛠 站点配置 | notion-next-api_base_url |
config/notion-next-api_base_url.md |
| 🛠 站点配置 | notion-workspace-id |
config/notion-workspace-id.md |
| ⭐ 主题参数 | notion-next-themes |
themes/overview.md |
| ⭐ 主题参数 | notion-next-theme-console |
themes/theme-console.md |
| ⭐ 主题参数 | notion-next-typography |
themes/typography.md |
| ⭐ 主题参数 | notion-next-magzine |
themes/magzine.md |
| ⭐ 主题参数 | notion-next-proxio |
themes/proxio.md |
| ⭐ 主题参数 | notionnext-simple |
themes/simple.md |
| ⭐ 主题参数 | notion-next-greetings |
themes/hexo-matery.md |
| ⭐ 主题参数 | notionnext-gitbook |
themes/gitbook.md |
| ⭐ 主题参数 | notionnext-heo |
themes/heo.md |
| ⭐ 主题参数 | notionnext-starter |
themes/starter.md |
| ⭐ 主题参数 | notionnext-movie |
themes/movie.md |
| ⭐ 主题参数 | notionnext-game |
themes/game.md |
| ⭐ 主题参数 | notionnext-commerce |
themes/commerce.md |
| 📊 网站统计 | notion-next-analytics |
analytics/overview.md |
| 📊 网站统计 | notion-next-umami |
analytics/umami.md |
| 📊 网站统计 | notion-next-search-engine-index |
operations/search-engine-index.md |
| 📊 网站统计 | notion-next-clarity |
analytics/clarity.md |
| 📊 网站统计 | notion-next-51-la |
analytics/51la.md |
| 📊 网站统计 | notion-next-ackee |
analytics/ackee.md |
| 📩 评论插件 | notion-next-comment-plugin |
comments/overview.md |
| 📩 评论插件 | notion-next-cusdis |
comments/cusdis.md |
| 📩 评论插件 | notion-next-utterance |
comments/utterances.md |
| 📩 评论插件 | notion-next-giscus |
comments/giscus.md |
| 📩 评论插件 | notionnext-twikoo |
comments/twikoo.md |
| 📩 评论插件 | notion-next-artalk |
comments/artalk.md |
| 📩 评论插件 | notion-next-gitalk |
comments/gitalk.md |
| 📩 评论插件 | notionnext-valine |
comments/valine.md |
| 📩 评论插件 | notion-comments |
comments/notion-comments.md |
| 📩 评论插件 | notion-next-waline |
comments/waline.md |
| 🧷 外部扩展 | notion-next-plugins |
plugins/overview.md |
| 🧷 外部扩展 | notion-next-plugin-music-player |
plugins/music-player.md |
| 🧷 外部扩展 | notion-next-plugin-live2d |
plugins/notion-next-plugin-live2d.md |
| 🧷 外部扩展 | notion-next-algolia |
config/algolia.md |
| 🧷 外部扩展 | notion-next-ai-chat |
plugins/notion-next-ai-chat.md |
| 🧷 外部扩展 | notion-next-coze |
plugins/notion-next-coze.md |
| 🧷 外部扩展 | notion-next-chat-base |
plugins/notion-next-chat-base.md |
| 🧷 外部扩展 | notion-next-facebook-chat-plugn |
plugins/notion-next-facebook-chat-plugn.md |
| 🧷 外部扩展 | notion-next-salesmatly-pulgin |
plugins/notion-next-salesmatly-pulgin.md |
| 🧷 外部扩展 | notion-next-tidio |
plugins/notion-next-tidio.md |
| 🧷 外部扩展 | notion-next-google-adsense |
plugins/notion-next-google-adsense.md |
| ⌨ 开发教程 | frontend-development-tutorial |
development/frontend-development-tutorial.md |
| ⌨ 开发教程 | how-to-develop-with-notion-next |
development/getting-started.md |
| ⌨ 开发教程 | custom-your-style |
development/custom-style.md |
| ⌨ 开发教程 | your-own-theme |
development/own-theme.md |
| ⌨ 开发教程 | notion-next-click-effect |
development/notion-next-click-effect.md |
| ⌨ 开发教程 | notion-next-develop-with-ai |
development/notion-next-develop-with-ai.md |
| ⌨ 开发教程 | react-jsx |
development/react-jsx.md |
| ⌨ 开发教程 | next-js |
development/nextjs.md |
| ⌨ 开发教程 | about-tailwindcss |
development/about-tailwindcss.md |
| ⌨ 开发教程 | notionnext-how-to-pr |
development/notionnext-how-to-pr.md |
| 🔊 运营教程 | seo-course |
operations/seo.md |
| 🔊 运营教程 | wechat-offical-account |
operations/wechat-offical-account.md |
| 🔊 运营教程 | notion-next-mailchimp |
plugins/mailchimp.md |
| 👨👦👦 获取帮助 | how-to-question |
help/community-rules.md |
| 👨👦👦 获取帮助 | about-author |
help/feedback.md |
| 👨👦👦 获取帮助 | chat-community |
help/community.md |
| 👨👦👦 获取帮助 | my-service |
help/support.md |
| 💪 支持我们 | support-notion-next |
help/support-notion-next.md |
| 💪 支持我们 | crowdfunding |
help/crowdfunding.md |
User Guide Intro (`docs/user-guide/intro.md`)
NotionNext 快速免费建站
迁移自:NotionNext-快速免费建站
发布日期:2021-12-4
最后编辑:2026-5-10
标签:Notion、NotionNext、建站
NotionNext 是一个基于 Notion 和 Next.js 的开源建站系统。你可以继续在 Notion 中写文章、整理知识库和维护页面结构,NotionNext 负责把这些内容渲染成独立网站,并提供主题、SEO、评论、统计、搜索、广告、插件、静态导出和多平台部署等能力。
它适合个人博客、知识库、文档站、作品集、导航站、产品官网、相册和轻量商业展示等场景。对非技术用户来说,它降低了从 Notion 到独立站的门槛;对开发者来说,它保留了完整源码、配置文件和主题扩展空间。
旧版升级提醒
2026 年起 Notion 侧数据结构多次升级,过旧的 NotionNext 源码可能无法完整拉取页面。建议把站点代码同步到主线最新版本。当前仓库版本为 4.10.2,升级步骤见 版本升级指引。
为什么选择 NotionNext
写作系统最重要的不是后台有多复杂,而是能不能降低持续输出的阻力。许多博客系统需要维护数据库、后台、插件、主题和服务器;NotionNext 的思路更轻:把 Notion 作为内容源,把网站作为展示层。
这样做有几个直接好处:
- 写作仍然在 Notion 中完成,电脑和手机都可以随时编辑。
- 内容、图片、分类、标签、菜单等数据集中沉淀在 Notion 中,便于备份和迁移。
- 网站源码、域名、部署平台都由你自己掌控,不被第三方内容平台锁定。
- 基于 Next.js 渲染,支持良好的访问性能、SEO、RSS、Sitemap 和静态化能力。
- 主题与插件可自由扩展,既能快速上线,也能按业务需要长期演进。
核心能力
1. Notion 写作与内容管理
NotionNext 直接读取 Notion 数据库和页面内容。你可以在 Notion 中维护文章、分类、标签、发布日期、摘要、封面图、菜单、隐藏页、定时发布和多语言内容。
Notion 本身支持富文本、图片、视频、引用、表格、代码块、折叠块、数据库视图等内容形态。通过 NotionNext,这些内容可以转化为可访问、可搜索、可分享的独立网站页面。
Notion 也集成了 AI 写作能力,可以辅助起草、润色、总结和翻译内容。对内容型站点来说,这意味着选题、写作、编辑和发布都可以在同一个知识库中完成。
2. 26 个内置主题
当前版本内置 26 个主题,覆盖不同站点形态:
- 个人博客:
simple、hexo、nobelium、typography - 文档和知识库:
gitbook、claude - 作品集和品牌站:
opc、proxio、starter、landing - 图片和相册:
plog、photo - 导航聚合:
nav - 杂志与视觉展示:
magzine、heo - 阅读体验:
medium、fuwari、thoughtlite
完整主题列表见 内置主题全览。你可以通过环境变量、Notion Config 或主题切换挂件选择主题。
3. 部署与静态化
NotionNext 支持多种部署方式,包括 Vercel、Cloudflare Pages、EdgeOne Pages、Netlify、Zeabur、4EVERLAND 和 VPS。新手建议先从 Vercel 部署 开始。
站点可以使用 ISR 缓存、静态导出、伪静态路径、构建预热和 Notion 请求限速等能力,在访问速度、构建稳定性和平台资源消耗之间取得平衡。相关说明见 部署索引 与 构建性能调优。
4. SEO、订阅与站点运营
NotionNext 内置面向独立站运营的基础能力:
- 自定义标题、描述、关键词、作者信息和站点图标
- Sitemap 与 RSS
- Google / 百度站长验证
- 自定义文章 URL、伪静态
.html路径和 UUID 重定向 - 分享按钮、文章推荐、文章过期提示和置顶文章
- Google、百度、Umami、Clarity、51LA、Ackee、Matomo、Vercel Analytics 等统计接入
如果你希望长期运营个人品牌、产品站或内容站,独立域名和可持续的 SEO 积累会比依赖第三方内容平台更稳定。
5. 评论、搜索、广告与插件
NotionNext 支持多种评论系统,可按需同时启用并在评论区 Tab 切换:
- Twikoo、Waline、Valine
- Giscus、Utterances、Cusdis
- Gitalk、Artalk、Webmention
扩展能力还包括 Algolia 全文搜索、Google AdSense、万维广告、AI 文章摘要、Mailchimp 邮件订阅、音乐播放器、Live2D 挂件、Chatbase、Dify、WebWhiz、Facebook / SaleSmartly / Tidio 等聊天组件,以及点击烟花、樱花、星空、鼠标跟随等动效。
插件教程见 外部插件说明,评论教程见 评论插件说明,统计教程见 站点统计相关。
6. 开源可控与高度自定义
NotionNext 的源码、配置和主题都在你的仓库中。你可以通过 blog.config.js 和 conf/*.config.js 配置站点基础信息、文章列表、评论、统计、图片、字体、代码块、动画、广告、插件、缓存和主题专属选项。
如果现有主题不满足需求,也可以继续开发自己的主题,或在现有主题中定制布局、样式和交互。开发入口见 开发入门 和 开发自己的主题。
平滑迁移与数据安全
这套新版 VitePress 文档本身就是一个迁移案例:它从旧版 Notion 文档站迁移而来,保留了原文章内容、图片、链接与分类结构。借助 AI、脚本和结构化解析工具,Notion 中的数据可以被快速转换为 Markdown、静态站点或其他网站平台需要的格式。
这说明 NotionNext 不会把内容锁死在某一个框架或托管平台中。Notion 负责沉淀原始内容,网站系统负责展示与分发;当你需要升级主题、更换框架、切换部署平台,甚至迁移到全新的文档系统时,都可以沿着清晰的数据链路完成迁移。
这种架构为站点搭建提供了更平滑的迁移弹性,也为长期运营提供了更可靠的数据安全保障。
独立站价值
在互联网和自媒体环境中,独立站不只是一个展示页面,更是长期积累的数字资产。
- 建立可信的个人或品牌入口:独立域名、稳定页面和持续内容能让读者更容易记住你。
- 沉淀搜索权重和内容资产:优质文章会持续为域名积累搜索曝光,而不是只服务于某个第三方平台。
- 连接更多业务场景:作品集、产品介绍、知识库、邮件订阅、评论互动、广告和在线客服都可以在同一个站点中组合。
对个人而言,它可以是博客和作品集;对团队而言,它可以是文档站、产品官网和内容运营阵地。
快速开始
建议按下面顺序阅读:
部署完成后,你可以继续绑定自定义域名、配置评论系统、接入统计、开启搜索、选择主题,并根据自己的站点定位逐步补齐内容和功能。
原文链接
https://docs.tangly1024.com/about
Developer Rfc README (`docs/developer/rfc/README.md`)
RFC(Request for Comments)
较大或跨模块的改动,建议先在本目录提交 RFC(Markdown),在 Discussions 或 Issue 中链接并收集反馈,再开实现 PR。
适用场景(参见 GOVERNANCE.zh-CN.md):
- 新公共 API、全局配置默认值变更
- 跨多个内置主题的共享层改动
- 破坏性变更、Next.js / 依赖大版本升级
- 安全或数据模型相关设计
如何提交
- 复制 TEMPLATE.md 为
docs/developer/rfc/NNNN-short-title.md(NNNN为四位序号或日期)。 - 填写后提 PR,标题形如
RFC: 简短标题。 - 在 PR 描述中 @ 相关维护者(见 MAINTAINERS.md)。
- 共识达成后,再开实现 PR,并在 RFC 文末记录 状态:已接受 / 已拒绝 / 已 superseded。
已有 RFC
| RFC | 状态 | 说明 |
|---|---|---|
| 2026-originality-proof-auto-manifest.md | 已实现,本地验收通过 | 原创存证自动生成 GitHub 公开清单 |
| 2026-originality-proof-ux.md | 已落地,本地验收通过 | 原创存证从大块信息卡优化为徽章、展开详情和复制证据 |
Developer Rfc Index (`docs/developer/rfc/index.md`)
RFC
大型改动先写 RFC,再进入实现和 PR 讨论。RFC 不是只给维护者看的内部文档;它帮助使用者理解项目为什么这样演进,也帮助新贡献者参与设计讨论。
流程
- 复制 TEMPLATE.md 为
docs/developer/rfc/NNNN-short-title.md。 - 在 RFC 中说明背景、目标、非目标、方案、迁移影响和风险。
- 在 GitHub Discussion 或 PR 中引用 RFC,收敛后再开始大规模实现。
模板
已有 RFC
Developer Themes README (`docs/developer/themes/README.md`)
Themes Documentation
中文 | English
本目录用于开发者向主题说明(架构、全局改动、迁移计划)及英文文档。
站长向统一入口:user-guide/themes/README.md(26 个主题各一篇 .md)。
文档分工
| 类型 | 位置 | 说明 |
|---|---|---|
| 站长教程 | docs/user-guide/themes/.md |
启用、场景、配置表;Proxio / Heo 全文在此 |
| 开发者深度 | 本目录 CLAUDE.md 等 |
实现细节、Supabase、_app.js 等 |
| 已合并存根 | PROXIO.md、HEO.md |
仅重定向,勿再编辑 |
主题索引
| Theme | 站长文档 | 开发者 / 英文 |
|---|---|---|
| Proxio | proxio.md | 已合并至站长文档 |
| HEO | heo.md | 已合并至站长文档 |
| Claude | claude.md | CLAUDE.md · CLAUDE.en.md |
| Endspace | endspace.md | ENDSPACE.md · ENDSPACE.en.md |
| Fuwari | fuwari.md | FUWARI.md |
| ThoughtLite | thoughtlite.md | THOUGHTLITE.md · THOUGHTLITE.en.md |
全部主题列表:THEMES_CATALOG.md
维护约定
- 新增主题时,在
docs/user-guide/themes/.md写站长说明;仅当需要记录全局改动时再在本目录补开发者文档。 - 修改
themes//config.js后运行node scripts/generate-theme-user-docs.mjs刷新配置表(proxio/heo仅更新 `` 段)。 - 合并主仓库时:除
themes//外,需在public/images/themes-preview/提交.png/.webp,并更新conf/themeSwitch.manifest.js;详见 主题迁移指南 §8。
Developer Themes Index (`docs/developer/themes/index.md`)
主题开发文档
这里放主题实现、迁移计划、架构取舍、上游来源和许可证说明。它们会和使用教程一起发布到在线文档站,方便使用者从“会配置主题”逐步走到“能修改和贡献主题”。
如果你只想启用或配置主题,先看 主题目录 与 主题全览。如果你准备改主题、迁移主题或提交 PR,再继续读本目录。
主题文档
| 主题 | 使用文档 | 实现文档 |
|---|---|---|
| Claude | claude.md | CLAUDE.md · CLAUDE.en.md |
| Endspace | endspace.md | ENDSPACE.md · ENDSPACE.en.md |
| Fuwari | fuwari.md | FUWARI.md |
| HEO | heo.md | HEO.md |
| Proxio | proxio.md | PROXIO.md |
| ThoughtLite | thoughtlite.md | THOUGHTLITE.md · THOUGHTLITE.en.md · 迁移计划 |
全部主题列表见 THEMES_CATALOG.md。
User Guide Analytics Overview (`docs/user-guide/analytics/overview.md`)
站点统计相关
迁移自:站点统计相关
发布日期:2023-8-4
最后编辑:2024-4-28
原栏目:📊 网站统计
标签:NotionNext、站点统计
::: tip 提示
作为站长,站点统计功能对于管理和优化你的网站非常重要。它可以提供有关访问者行为、流量来源和网站性能的关键信息,帮助你做出数据驱动的决策和改进网站体验。
:::
站点统计功能的一些主要作用:
访问者分析:站点统计可以提供关于你的访问者的详细信息,包括他们的地理位置、使用的设备和操作系统、浏览器类型等。这些数据可以帮助你了解你的目标受众,优化网站内容和布局以提供更好的用户体验。
流量来源追踪:统计功能可以告诉你访问者是通过搜索引擎、外部链接还是直接输入网址来到你的网站的。这有助于你了解哪些渠道为你带来了最多的流量,以便你可以聚焦于这些渠道,提高网站的可见性和曝光度。
页面分析:你可以了解每个页面的访问量、跳失率、停留时间等指标。通过分析这些数据,你可以确定哪些页面受欢迎,哪些页面需要改进,以及你的访问者在你的网站上的行为模式。
目标跟踪和转化率分析:如果你有特定的目标,比如注册、购买或订阅,站点统计功能可以帮助你追踪这些目标的完成情况。你可以了解转化率、关键转化路径和转化漏斗,以便你可以优化你的网站和营销策略。
常用的站点统计方案包括:
Google Analytics:这是最受欢迎的免费网站统计工具之一,提供了广泛的功能和详细的数据分析报告。
百度统计:这是百度提供的一款免费统计工具,特别适用于中文网站。
CNZZ统计:这是国内另一款常用的免费统计工具,提供了实时数据监控和细致的访问者分析。
Ackee:这是一款自托管的开源统计工具,可以在你自己的服务器上搭建,提供了强大的个性化定制和隐私保护功能。
Clarity统计:最近我才发现的、微软推出的统计工具,很好用,而且在国内访问体验很好。
不蒜子 / Busuanzi:轻量的 PV/UV 计数,默认开启;2024 年起官方服务不稳定,已切换到社区维护的 Vercount,详见专页。
这些统计方案在功能和报告类型上略有不同,你可以根据自己的需求选择最适合你的方案。无论你选择哪种方案,站点统计功能都将帮助你更好地了解和优化你的网站。
配置相关
// ----> 站点统计
ANALYTICS_BUSUANZI_ENABLE: true, // 展示网站阅读量、访问数;2024 年起官方服务不稳定,默认改走社区兼容实现 Vercount,详见 /user-guide/analytics/busuanzi
ANALYTICS_BAIDU_ID: process.env.NEXT_PUBLIC_ANALYTICS_BAIDU_ID || '', // e.g 只需要填写百度统计的id,[baidu_id] -> https://hm.baidu.com/hm.js?[baidu_id]
ANALYTICS_CNZZ_ID: process.env.NEXT_PUBLIC_ANALYTICS_CNZZ_ID || '', // 只需要填写站长统计的id, [cnzz_id] -> https://s9.cnzz.com/z_stat.php?id=[cnzz_id]&web_id=[cnzz_id]
ANALYTICS_GOOGLE_ID: process.env.NEXT_PUBLIC_ANALYTICS_GOOGLE_ID || '', // 谷歌Analytics的id e.g: G-XXXXXXXXXX::: tip 不蒜子站点的处理建议
如果你之前一直用不蒜子、现在发现 PV/UV 数字为空,请直接阅读 不蒜子统计专页:
- 默认走 Vercount,升级后会自动从
busuanzi.ibruce.info同步历史 PV/UV,无需手动操作 - 自托管 Vercount / 切回原版不蒜子 / 关闭开关都有明确步骤
- 新增
NEXT_PUBLIC_BUSUANZI_SCRIPT_URL用于自定义脚本地址
:::
开启 谷歌统计(GA)
只需在vercel后台添加一个环境变量,值为你的GA-ID即可,无需其他配置
GA-ID从哪里来?
在GoogleAnalytics后台 创建你的网站资源,并添加一个数据流(类型为网站)
在数据流的详情中,可以看到我们所需要的 衡量ID (Analytics-ID)
FAQ
统计多久生效?
- 理论上实时生效,只要在站点安装好后,google后台就能立刻查询到安装结果
怎么知道我的统计安装是否生效?
- 打开网页 → 按F12打开控制台 → 点击元素(Elements)面板 → 在面板中搜索你的衡量ID,如果能搜索相关代码
googletagmanager.com/gtag/js?id=xxxxx到就是成功的。
- 打开网页 → 按F12打开控制台 → 点击元素(Elements)面板 → 在面板中搜索你的衡量ID,如果能搜索相关代码
配置失效怎么办?
- 参考站点配置的文档,进行redeploy
原文链接
https://docs.tangly1024.com/article/notion-next-analytics
User Guide Changelog Index (`docs/user-guide/changelog/index.md`)
更新日志
| 文档 | 说明 |
|---|---|
| 最新版本 | v4.11.0 发布要点、升级须知与近期主线改动 |
| V4 历史 | v4.10.0 起的发布历史与 V4.9 及更早版本归档 |
另见:升级 · 仓库 GitHub Releases
User Guide Comments Overview (`docs/user-guide/comments/overview.md`)
评论插件说明
迁移自:评论插件说明
发布日期:2024-7-11
最后编辑:2024-7-11
原栏目:📩 评论插件
NotionNext评论插件
NotionNext支持多种评论插件,通常只需要准备好对应的评论功能,在NotionNext的环境变量中添加评论插件的信息即可启用。
目前支持7种评论插件,其中部署最快速的是 Cusdis 和 Utterance这两个插件,他们几乎不需要另外的设置,直接配置到NotionNext即可。
其中体验比较好的是Twikoo。它支持直接在页面上管理评论,而且能友好地根据用户评论时的邮箱展示头像,同时支持方便的邮箱通知配置。
另外Valine/Waline也很不错,它们是很相似的一对评论插件,借助LeanCloud存储数据。
评论、登录和会员能力的边界
如果只是给博客、文档站或个人网站增加评论,优先选择现有评论插件。Twikoo、Waline、Artalk、Giscus、Cusdis 等方案已经覆盖了评论存储、审核、通知、反垃圾和迁移等常见需求,不需要把评论系统重新写进 NotionNext。
如果站点需要登录、会员权限或“只有登录用户才能评论”,建议把登录身份、会员权限和评论存储拆开看:
- 登录身份可以交给 Clerk 等认证服务。
- Notion Integration 更适合作为站长可维护的低频权限后台,例如维护会员状态、角色、过期时间和可访问内容。
- 评论数据可以继续使用现有评论插件;只有在确实需要与站点账号深度绑定时,再考虑启用一个轻量的 Notion 评论适配。
不建议一开始把支付、订单、积分、复杂 RBAC 全塞进 NotionNext。Notion 适合当“站长可视化后台”和低频权限源,不适合当高并发交易数据库。评论如果流量较大,仍建议使用 Waline、Artalk、Twikoo 或自建数据库,并保留登录身份绑定。
这类能力会尽量作为可选插件、适配器或示例存在,不影响博客站点的最简单使用路径。相关规划见 会员、权限与评论可选集成路线图。
同时部署多个评论插件
您可以选择同时部署多个。多个评论插件会在评论区用切换面板的形式展现
关闭特定文章的评论
在4.5.4以后的版本中,支持在Notion数据库中配置comment属性,如果属性值为Hide,就可以隐藏该页面的评论区域。
具体方法,找到页面的字段列表,在最后找到+Add a property 按钮 ,然后添加一个新的字段, 类型是 Select(下拉框)名称是 comment , 然后添加Hide和Show 两个下拉框的值即可。
点击添加新属性
设置属性名和类型
- 添加选项
使用
参考实现结果:
目录1
原文链接
https://docs.tangly1024.com/article/notion-next-comment-plugin
NotionComments
如果希望评论数据也保存在 Notion 中,可以使用 NotionComments。它通过 Notion API 写入独立的评论数据库,访客不需要登录 Notion;支持昵称、回复、加载更多、Notion 手动审核和基础频率限制,但没有独立管理后台、邮件通知和完整垃圾评论过滤,更适合轻量站点。
User Guide Config Index (`docs/user-guide/config/index.md`)
站点配置
| 文档 | 说明 |
|---|---|
| 基础功能 | 站点开关与常用项 |
| URL 自定义 | 路径、重定向 |
| PWA 安装入口 | Android Chrome 安装到桌面 |
| 字体字号 | 系统字体、Web Font 与字号 |
| Algolia | 站内搜索 |
| 按文章控制是否允许复制 | 单篇覆盖全站复制开关 |
User Guide Deploy Index (`docs/user-guide/deploy/index.md`)
部署指南索引
仓库根目录 DEPLOYMENT.md 含更完整的平台说明与排错。
推荐流程
- Vercel 部署(入门)
- 绑定域名
- 流量增大时:静态导出 · Netlify · Cloudflare Pages
全部部署文档
| 文档 | 场景 |
|---|---|
| deploy-vercel.md | Vercel 默认 SSR/ISR |
| vercel-domain.md | 自定义域名 + Cloudflare |
| vercel-accelerate.md | 国内访问加速 |
| vercel-static.md | yarn export 降额度 |
| vercel-redeploy.md | 重新部署 |
| netlify.md | Netlify(4.0.9+) |
| cloudflare-pages.md | Cloudflare 静态 |
| notion-image-proxy.md | Cloudflare Worker 图片反代、浏览器长期缓存与 304 验证 |
| edgeone-pages.md | 腾讯云 EdgeOne(Node 版本、ENOSPC、Next SSG 预设) |
| build-tuning.md | 构建超时 / Notion 预热与限流(环境变量) |
| vps.md | VPS / Docker(Node 22+) |
构建超时排错
若在 Cloudflare、Netlify 等平台出现 timeout of 300 seconds 或 prefetch 极慢,请参阅 构建性能调优(BUILD_PREFETCH_ENABLED、STATIC_PAGE_GENERATION_TIMEOUT 等)。
环境要求(2026)
- Node.js 22(见
.nvmrc/.node-version)。Node 20 已无法安装当前依赖,Cloudflare、Netlify、VPS、Docker 等构建环境都应同步使用 Node 22。 - Yarn:
yarn→yarn build/yarn export - 必配:
NOTION_PAGE_ID
Docker 镜像发布说明
4.10.9 起,主仓库的 GHCR Docker 镜像发布流程会随镜像生成 provenance 与 SBOM attestation。自托管用户如果从 ghcr.io/notionnext-org/notionnext 拉取镜像,可以在 GitHub Packages / Actions 记录中查看镜像来源和依赖清单。
这不会改变本地 Dockerfile 构建方式;如果你仍按 VPS / Docker 教程在服务器上自行 docker build,原流程保持不变。
EdgeOne
Node 版本、磁盘 ENOSPC、框架预设 Next SSG 等见 edgeone-pages.md。构建时若 .next/cache 不可写,项目会回退系统临时目录,见 lib/cache/build_session.js。
User Guide Development Getting Started (`docs/user-guide/development/getting-started.md`)
NotionNext开发先导
迁移自:NotionNext开发先导
发布日期:2022-11-13
最后编辑:2026-5-2
原栏目:⌨ 开发教程
标签:NotionNext
摘要:小白入门如何开发notionnext,下载NotionNext、启动NotionNext、提交合并到NotionNext等。
::: warning 注意
此处文档较旧。如需更全面的开发指导,请阅读项目仓库中的 README.md,以及 /docs 目录下的相关文档。
:::
前言
在进行二次开发之前,您需要了解到:NotionNext本身支持大量的自定义配置,开发之前,请先访问《配置手册》获取帮助、配置您的站点,例如:
blog.config.js文件中可以修改站点的基础信息、主题、语言、评论插件等核心配置每个主题下都有一个配置文件
config_[theme].js,以便用户配置自己的页面个性化。
自定义脚本
NotionNext操作手册中,有关于自定义脚本和样式的引入方式;即:
在
/public/js/custom.js/public/css/custom.css中引入您的脚本,就可以实现任意的页面功能。在
blog.config.js的CUSTOM_EXTERNAL_JS、CUSTOM_EXTERNAL_CSS中也可以引入第三方的脚本。
::: tip 提示
用这两种方式引入脚本,即使本机上没有安装nodejs等开发环境,也可以直接在浏览器控制台中编写调试。
:::
Notion中自定义JS和CSS
在4.2.0之后的版本中,您可以直接在Notion中指定网页上的样式,以及执行的脚本,只需在NotionConfig中配置GLOBAL_CSS属性以及GLOBAL_JS属性即可,如下图示例:
自行开发
如果上述的配置方式,不能满足您的需要,例如新增组件、深度定制等等。您可以选择在github上发起issue,提出改进页面的建议,或者遵循此教程,进行您的开发之旅。
::: tip 提示
可选Codespaces云开发,以及本地开发两种方案。
:::
一、云开发(Codespaces)
::: tip 提示
这是一个可选方案,相比本地开发,您不需要在电脑上安装环境;直接将Github仓库导入到云开发环境,在线编辑即可。
Codespaces是Github官方提供的云开发环境。
:::
导入启动项目
点击Codespaces
点击新建代码空间
导入项目,并选择代码分支、以及云环境的服务器配置,然后点击Create codespacee
等待几分钟,您的云开发环境即可搭建
- 在终端中输入yarn即可安装依赖的环境
- 等上一步安装全部完成(约3分钟)后,在终端输入 `yarn dev` 即可开始实时调试终端会提示以下内容,说明服务启动成功:
@tangly1024 ➜ /workspaces/NotionNext (main) $ yarn dev
yarn run v1.22.19
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info - Loaded env from /workspaces/NotionNext/.env.local
Attention: Next.js now collects completely anonymous telemetry regarding usage.
This information is used to shape Next.js' roadmap and prioritize features.
You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
https://nextjs.org/telemetry点击右下角的在浏览器中打开,即可开启调试页面。
- 调试效果github 会临时分配给您一个临时的域名,用于开发调试
二、 本地开发
1.准备开发环境
::: tip 提示
您的电脑上需要有一个开发环境NodeJs、以及代码编辑器VSCode,
- NodeJS 运行环境
:::
安装步骤
- windows操作系统下,在官网下载安装最新版的NodeJs即可Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
::: tip 提示
建议使用 Node 22(与仓库 README、.nvmrc 一致)。安装后执行 node -v 自检。
个别小版本若遇构建问题,请以 GitHub 仓库 README 与 Issues 的最新说明为准。
- 安装成功检验
安装成功,测试安装是否成功,运行CMD,分别输入node -v 和 npm -v 分别查看node和npm的版本号,如下图所示:
💡
node是基础运行环境,npm是依赖包的管理组件
💡
如果执行 npm -v 出现异常 **npm : 无法加载文件 D:\nodejs\npm.ps1 ,可以参考此文: **
npm : 无法加载文件 D:\nodejs\npm.ps1-CSDN博客
文章浏览阅读1.1k次,点赞11次,收藏5次。npm : 无法加载文件 D:\ nodejs\ npm.ps1
:::
- VsCode 编辑器
安装下载
Download Visual Studio Code - Mac, Linux, Windows
Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows. Download Visual Studio Code to experience a redefined code editor, optimized for building and debugging modern web and cloud applications.
设置中文
Visual Studio Code是一款支持多种语言和格式的编辑器,那么,怎么把界面设置成中文的呢?今天就和大家一起把Visual Studio Code界面设置成中文 打开Visual Studio Code 点击"应用"按钮 输入"Chinese (Simplified) Language Pack for Visual Studio Code"并敲回车键 点击第一个选项 点击Install 点击Restart Now 这样就设置完成了 点击下方链接 点击Install 点击Continue 如果浏览器有拦截,请点击打开(各浏览器的界面不同) 点击Install 最后点击Restart Now即可 END 喜欢请点赞+关注
::: tip 提示
相关阅读
- NodeJS是什么
- NPM使用介绍
- 什么是React
:::
2.导入启动项目
- 下载您的代码
安装Github Desktop
Checkout branches with pull requests and view CI statuses See all open pull requests for your repositories and check them out as if they were a local branch, even if they're from upstream branches or forks. See which pull requests pass commit status checks, too!
点击Sign in to Github登录,或者skip this step 稍后登录都可以
下载代码
找到您的仓库地址进行Clone
点击Clone即可下载代码
- 用vscode打开项目
打开项目文件
安装项目依赖的组件
点击 菜单栏的终端,并选择 新建终端,然后在新建的终端窗口中输入安装启动脚本:
任选一种安装
# 使用npm安装
npm install yarn --registry=https://registry.npm.taobao.org
# 使用yarn安装(推荐 更快)
yarn config set registry https://registry.npm.taobao.org/
yarn install::: tip 提示
静候片刻,首次安装依赖需要花一点时间
:::
启动项目 只需一个命令
yarn dev# 执行后vscode中会显示
yarn run v1.22.19
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info - Loaded env from D:\Workspace\NotionNext\.env.local其他脚本说明
yarn # 安装依赖
yarn dev # 开发,支持热加载
yarn build # 为生产编译打包
yarn start # 运行打包后的项目构建服务- 访问页面
浏览器打开 http://localhost:3000/ 即可访问你的本地博客
::: tip 提示
调试模式下:代码的每次修改会实时影响到你的页面,不需要刷新或重启服务
:::
3.本地开发环境配置
VSCode中可以使用launch面板,进行设置环境变量以及断点调试
创建一个launch文件
可参考官方推荐配置
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: Debug Server",
"type": "node",
"request": "launch",
"runtimeExecutable": "yarn",
"runtimeArgs": ["dev"],
"console": "integratedTerminal",
"skipFiles": ["<node_internals>/**"],
"env": {
"NODE_OPTIONS": "--inspect",
"ENABLE_CACHE": "true"
}
},
{
"name": "Next.js: Debug Client (Chrome)",
"type": "pwa-chrome",
"request": "launch",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}",
"sourceMaps": true
}
],
"compounds": [
{
"name": "Next.js: Debug Full Stack",
"configurations": [
"Next.js: Debug Server",
"Next.js: Debug Client (Chrome)"
]
}
]
}VSCode 里会出现三个启动项:
① Debug Server
只调试 Node 端
适合调试:
- getServerSideProps
- app/api/*
- middleware.ts
- server components
② Debug Client (Chrome)
只启动浏览器调试
适合调试:
- React组件
- hooks
- 前端逻辑
- 页面跳转
③ Debug Full Stack(推荐)
一次同时启动:
- Next dev server
- Chrome调试
这是 Next.js最常用调试方式。
代码结构简介
NextJS
项目用NextJS框架构建,以下是代码所有主要目录,修改样式主要在themes 目录下完成。
::: tip 提示
关于NextJs框架请阅读官方文档获取帮助
快速入门 | Next.js
欢迎阅读 Next.js 文档! 如果你是初学 Next.js,我们建议你从 互动课程 开始。 通过这些带小测验的互动课程你将学到使用 Next.js 所需的全部知识。 如果你有任何与 Next.js 相关的问题,欢迎随时在 GitHub Discussions 上向我们的社区寻求帮助。 我们建议使用 create-next-app 创建新的 Next.js 应用程序,它会自动为你设置所有内容。创建项目,请运行: npx create-next-app@latest yarn create next-app 如果你希望使用 TypeScript 开发项目,可以通过 --typescript 参数创建 TypeScript 项目: npx create-next-app@latest --typescript yarn create next-app --typescript 安装完成后: 运行 npm run dev 或 yarn dev 来启动开发服务器,访问地址为 http://localhost:3000。
:::
TailWindCSS
项目开发使用TailwindCss,这是一个极简、灵活的CSS工具库,上手后开发效率极高。
TailwindCSS官方称一个可以让你脱离css文件,在html直接通过class修改样式的框架。 但是TailwindCSS一直受到CSS 方案备受争议。第一个问题就是这和写style css有什么区别? 首先在我们的进行修改css样式的风法中,多多少少会用到一些4中方式 越往下走,颗粒度越来越大,约束性变高,自由性不足。而 TailwindCSS 位于第二层。 第一层的话,就很难复用了,所以 TailwindCSS 选择了第二层的原因。 在不久之前Facebook经过重构后的css体积已经重原来的413kb 压缩到74kb。 可是很多开发者,很疑惑。我的css文件下去了,但是我的html和组件的文件变得无比的大,并不知道这里的好处在哪里? 首先第一,现在的开发模式已经是组件开发了,就算你在搞一个css来维护。其实很多的样式属性这个组件有,那个组件也存在复用。这个没有必要,这里的自己的组件样式交给组件自己维护就好了。 第二点就是想到这个疑惑的,估计是没有去了解过nginx的gzip。只是知道有这么一回事。 gzip 的核心Deflate使用的是LZ77 算法和 Huffman 编码来压缩文件,重复度越高的文件可压缩的空间就越大。 即使 HTML 因为类名过多造成体积增大,由于 class 高度相似,gzip 也将会得到一个很大的压缩比例。 这才是 TailwindCSS 想要的结果 第一次我使用 tailwind ui 框架的时候,很多情况看多以下的这种写法。 你想要多少的数值,直接写多少就好了。 还有对应响应式 对应你使用的@media,你感觉谁更加舒服呢? 第三 就是后期维护的时候,就算有人跑路了,这么多个css,后面的人只需要去看html就能维护。这么多的css file你慢慢找吧,反正我是不想找的。 第四 Jit css编译,使用TailwindCSS在编译的过程中,比css-loader less-loader 都要快 说了这么这些好处,TailwindCSS有什么不足呢?我说说我的看法吧。 第一遇到复杂一点的css操作你不能直接使用 TailwindCSS 操作 比如以上的情况,你需要写css来操作子元素的显示,除非你无聊非要用js来写,也不是不行。 第二是增加了记忆负担,它的命名和你认知中的使用不一样,前期需要一直查阅文档,或者下载TailwindCSS的提示插件。要不你无从下手。 但是一旦你有习惯了,形成条件反射,那就是另一种情况,你会直喊香。 如果你正在做代码加速优化的话,你可以试试TailwindCSS.因为gzip后是真的小。 如果你是一个爱折腾的人,可是试试TailwindCSS。 如果你感觉你的组件已经可以完全独立使用一个css的时候,可以使用TailwindCSS来制作这个组件。后面要改代码时候,只需要去这个组件修改,并且不用担心自己的class会影响到他人的组件。
安装 - TailwindCSS中文文档 | TailwindCSS中文网
The simplest and fastest way to get up and running with Tailwind CSS from scratch is with the Tailwind CLI tool.
代码格式规范
使用Eslint + Prettier,关于格式化代码,可以阅读这篇文档:
ESLint插件:
Prettier插件
有两个插件任选一种,按照插件内的配置说明配置您的工作空间即可。
示例:Prettier - Code formatter
使用说明
- https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
安装后,在项目配置中启用自动格式化,在settings.json中添加如下配置:
{
// 保存时 prettier 自动格式化
"editor.formatOnSave": true,
// 默认格式化工具使用prettier
"editor.defaultFormatter": "esbenp.prettier-vscode",
// 开启eslint检查
"eslint.enable": true,
// 保存代码时自动用ESLint进行检查代码,并纠正格式化
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
}
}安装后,在项目配置中启用自动格式化,在用户,或者项目的settings.json中添加如下配置:
示例二:Prettier - Eslint
- 使用说明: [Prettier ESLint - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=rvest.vs-code-prettier-eslint)
- 安装后,在项目配置中启用自动格式化,在settings.json中添加如下配置:{
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint",
"editor.formatOnType": false, // required
"editor.formatOnPaste": true, // optional
"editor.formatOnSave": true, // optional
"editor.formatOnSaveMode": "file", // required to format on save
"files.autoSave": "onFocusChange", // optional but recommended
"vs-code-prettier-eslint.prettierLast": false // set as "true" to run 'prettier' last not first
}- 项目中的相关配置文件参考。
.eslintrc.js
.prettierrc.json原文链接
https://docs.tangly1024.com/article/how-to-develop-with-notion-next
User Guide Development Index (`docs/user-guide/development/index.md`)
开发入门
| 文档 | 说明 |
|---|---|
| 开发入门 | 本地运行与环境 |
| 运行原理 | 架构概览 |
| 自定义样式 | 样式与主题 config |
| 开发自己的主题 | 新建主题目录 |
| Next.js 相关 | 与 Next 的衔接 |
深度文档在 GitHub 仓库 docs/developer/(不进在线文档站)。
User Guide Help Index (`docs/user-guide/help/index.md`)
获取帮助
| 文档 | 说明 |
|---|---|
| 反馈与提问 | Issue、Discussions、社群 |
| 交流社群 | 非官方交流渠道 |
| 旧版手册入口 | docs.tangly1024.com 对照 |
| 获取帮助 | 免费社区支持、付费协助与赞助入口 |
另见:参与社区
User Guide Notion Index (`docs/user-guide/notion/index.md`)
Notion 写作与排版
| 文档 | 说明 |
|---|---|
| Notion 数据库 | 数据库字段与发布 |
| 社区站数据库模板 | Member / Event / 作者关系字段约定 |
| 双语库翻译 CLI | 可选 — 中英两库 LLM 同步(维护者工具,含风险说明) |
| 排版示例 | 标题、代码、评论等示例 |
| 快捷键 | 常用快捷键 |
| 加速访问 | 访问与同步优化 |
User Guide Operations Search Engine Index (`docs/user-guide/operations/search-engine-index.md`)
搜索引擎收录
迁移自:搜索引擎收录
发布日期:2024-3-18
最后编辑:2024-5-9
原栏目:📊 网站统计
标签:NotionNext、站点统计
摘要:notionnext的网站百度收录,html验证,的meta放在哪里
网站创建好后,搜索引擎会自动爬取您的站点信息,便于他人搜索到您的站点内容。
而我们可以通过主动提交的方式,加快这一进程。以下以Baidu和GoogleSearch为例
主要分为三步骤。绑定站点,提交站点地图,提交想要被收录的url。
Baidu站点验证
如果需要让百度快速收录你的网站,可以在百度站长工具中,完成对网站的验证。百度网站的验证方法有三种,这里介绍最简单的一种方法,HTML 标签验证。进入站长工具,输入需要验证的网站(如是自定义域名,请使用 https 链接,如 https://www.domain.com),并选择 HTML 标签验证:
复制该标签代码中的秘钥,即红色加粗部分,如下示例:
<script>
<meta name="baidu-site-verification" content="**NQ53KRpuNy**" />
</script>配置到NotionNext
方法一:使用NotionConfig (简单、推荐)
打开Notion模板配置中心,添加一条配置 SEO_BAIDU_SITE_VERIFICATION , 值为上一步获取的秘钥即可
方法一:使用环境变量
添加环境变量: **NEXT_PUBLIC_SEO_BAIDU_SITE_VERIFICATION** 值为上述的秘钥即可。
Google绑定站点
在google后台提交您的站点,并且验证您是站长。
点击左上角添加资源
添加域名
根据要求在您的域名服务商添加一条TXT的解析
我用CF解析域名,示例如下:
- 解析后回到Google控制台并点击右下角 验证按钮。
提交站点地图
NotionNext搭建的网站自带一个站点地图 地址是您的 域名后加 /sitemap.xml
例如域名是 https://blog.tangly1024.com, 则站点地图的地址 https://blog.tangly1024.com/sitemap.xml
提交网页url
提交可以加速被收录,在顶部搜索框直接输入完整的网址页面并按下回车键,例如about页面 /user-guide/intro ,
Google 会提示 未收录Google,此时我们点击请求编入索引即可
后续按照Google的提示操作即可。
最后
只要搜索词包含您站点的内容,即可搜索到您的网站,但如果站点权重低,您的站点排名会很靠后,可能在搜索结果的后面几页才能看到。
::: tip 提示
如何让自己的站点在同样竞争力的关键词下获得更优先的排名呢?
:::
这里涉及到SEO的知识,您可以参阅以下文章了解更多:
SEO怎么做,谷歌SEO优化教程,快速增加你的站点访问量 | Tangly的学习笔记
在这个以流量为王的时代,无数的流量媒体平台如谷歌、YouTube、Facebook、Bing、抖音、小红书和知乎等,为每个人提供了实现网络事业、走向财富自由的机会。
扩展阅读
NotionNext如何在<head>标签中注入元素呢?由于很多第三方的脚本插件都需要在网页的<head>中插入内容,所以如何快速在NotionNext中修改<head>成了一个问题。
在/components/GlobalHead.js 中包含了整个页面所有<head>中的内容,您可以在这里直接插入一些脚本代码。例如百度和google的网站验证代码已经预先设置了,所以只要简单地配置环境变量就可实现:相关代码:
{siteConfig('SEO_GOOGLE_SITE_VERIFICATION') && (
<meta
name='google-site-verification'
content={siteConfig('SEO_GOOGLE_SITE_VERIFICATION')}
/>
)}
{siteConfig('SEO_BAIDU_SITE_VERIFICATION') && (
<meta
name='baidu-site-verification'
content={siteConfig('SEO_BAIDU_SITE_VERIFICATION')}
/>
)}原文链接
https://docs.tangly1024.com/article/notion-next-search-engine-index
User Guide Plugins Overview (`docs/user-guide/plugins/overview.md`)
外部插件说明
迁移自:外部插件说明
发布日期:2023-6-27
最后编辑:2024-9-7
原栏目:🧷 外部扩展
NotionNext 预支持了一些第三方功能脚本插件。除了评论插件,还支持搜索、广告、背景动效、宠物挂件、音乐播放器、邮件订阅和在线客服等扩展。
开启插件的方法通常是在 blog.config.js 或 conf/*.config.js 中找到对应配置,或者在部署平台环境变量中添加同名配置项。不同插件需要的密钥、脚本地址或服务端地址不同,请进入对应教程查看。
插件教程
| 插件 | 用途 | 教程 |
|---|---|---|
| 音乐播放器 | APlayer / Meting 音乐播放组件 | 音乐播放器 |
| Live2D 宠物 | 页面 Live2D 挂件模型 | Live2D 宠物插件 |
| Algolia | 全文搜索索引 | Algolia 搜索 |
| OpenAI 兼容 AI 助手 | DeepSeek / OpenAI 兼容模型聊天代理 | OpenAI 兼容 AI 助手 |
| Google AdSense | 广告收益与文章内广告位 | Google 广告营收插件 |
| Gemini AI 助手 | 使用自己的 Gemini Key 接入博客 AI 助手 | Gemini AI 助手 |
| Coze | AI 聊天机器人 | Coze AI 聊天机器人 |
| Chatbase | AI 聊天机器人 | Chatbase AI 聊天机器人 |
| Facebook Chat | Facebook Messenger 聊天插件,旧教程已失效但保留迁移记录 | Facebook 聊天插件 |
| SaleSmartly | 在线客服与聚合聊天 | SaleSmartly 聊天插件 |
| Tidio | 在线客服聊天 | TIDIO 聊天插件 |
| Mailchimp | 邮件订阅 | Mailchimp 邮件订阅 |
相关教程
原文链接
https://docs.tangly1024.com/article/notion-next-plugins
User Guide Reference Index (`docs/user-guide/reference/index.md`)
参考手册(4.10.2)
本目录与 conf/*.config.js、blog.config.js 同步维护,描述 当前主线(package.json 版本,现为 4.10.2)能力,替代多年前源站教程中的过时表述。
| 文档 | 内容 |
|---|---|
| 全站功能与配置索引 | 评论、统计、挂件、文章、Notion、性能、广告等 全部配置项 |
| Notion 数据与 4.x 能力 | 数据库视图、字段、Menu、置顶、嵌入媒体等 |
| 部署与环境 | 各平台部署(见 deploy 目录) |
配置优先级(与 config-site.md 一致):Notion Config 表 > 环境变量 > conf/*.js > 主题 config.js。
维护者更新代码中的配置时,请同步修改本目录,流程见 MAINTENANCE_WORKFLOW.md。
User Guide Themes Index (`docs/user-guide/themes/index.md`)
内置主题说明文档(26 个)
每个主题一篇独立说明:主题特性、启用方式与 themes//config.js 配置表 与代码同步。维护者可运行:
node scripts/generate-theme-user-docs.mjs从各主题 config.js 重新生成配置表(改键名后请执行)。proxio / heo 含手写章节,脚本只更新 `` 段。
全部主题(27 个)
| ID | 名称 | 特性摘要 | 说明 |
|---|---|---|---|
claude |
Claude | 类 Claude Docs 的文档与终端氛围。 | claude.md · 实现文档 |
commerce |
Commerce | 电商与商品展示向页面结构。 | commerce.md |
endspace |
Endspace | 轻工业终末风,侧栏导航、悬浮控件与加载动画。 | endspace.md · 实现文档 |
example |
Example | 示例与演示向默认骨架。 | example.md |
fukasawa |
Fukasawa | 深川式多栏与侧边信息密度较高。 | fukasawa.md |
fuwari |
Fuwari | 日系轻量双栏与主题色板。 | fuwari.md · 实现文档 |
game |
Game | 偏游戏与像素元素装饰。 | game.md |
gitbook |
GitBook | 文档与手册式侧栏目录结构。 | gitbook.md |
heo |
Heo | 致敬张洪Heo,丰富的 模块化组件。 | heo.md |
hexo |
Hexo | 类 Hexo 经典博客结构与侧边栏。 | hexo.md |
landing |
Landing | 单页着陆与分区滚动叙述。 | landing.md |
magzine |
Magazine | 杂志封面与大图列表风格。 | magzine.md |
matery |
Matery | 卡片式列表与 Material 质感组件。 | matery.md |
medium |
Medium | Medium 风格阅读体验与排版。 | medium.md |
movie |
Movie | 影视与海报墙式呈现。 | movie.md |
nav |
Nav | 顶部导航主导航的现代布局。 | nav.md |
next |
Next | 经典双栏布局,右侧栏与移动端悬浮目录。 | next.md |
nobelium |
Nobelium | 致敬Nobelium,极简排版风格。 | nobelium.md |
opc |
Opc | 个人主页与一人公司入口,聚焦 AI 工作流。 | opc.md |
photo |
Photo | 摄影作品与相册网格。 | photo.md |
plog |
Plog | 偏图片与轻量图文化展示。 | plog.md |
proxio |
Proxio | 作品集与个人品牌展示增强。 | proxio.md |
simple |
Simple | 极简清爽,适合文字为主的博客。 | simple.md |
starter |
Starter | 落地页与区块化营销向模板。 | starter.md |
thoughtlite |
ThoughtLite | 轻阅读向时间线与 Latest 卡片,单列列表与文章卡片排版。 | thoughtlite.md · 实现文档 |
typography |
Typography | 排版优先,强调正文阅读与层级。 | typography.md |
xuhome |
XuHome | 新粗野主义博客主题,粗边框、偏移阴影、Hero 打字机与响应式导航。 | xuhome.md |
User Guide Themes Overview (`docs/user-guide/themes/overview.md`)
主题功能说明
迁移自:主题功能说明
发布日期:2023-6-27
最后编辑:2026-5-2
原栏目:⭐ 主题参数
标签:NotionNext、主题
摘要:主题与 main 分支 themes 目录对齐:默认 simple、挂件内切换见 conf/widget.config.js;修改 THEME 与在线预览说明。
主题功能介绍
NotionNext会扫描/themes目录下的文件夹,并根据文件夹的名字生成一个主题,只要在配置中将您的当前主题设置为对应文件夹名字即可,注意都是小写。
主题预览
内置主题以 GitHub 仓库 [themes/](https://github.com/notionnext-org/NotionNext/tree/main/themes) 目录为准(会随版本迭代增减)。当前主线常见主题包括:simple(新建仓库默认,见 blog.config.js 的 THEME)、next、medium、hexo、fukasawa、gitbook、matery、heo、nobelium、plog、landing、nav、starter、commerce、magzine、photo、movie、game、fuwari、claude、proxio、typography、example 等。
可按用途粗选:GitBook 偏文档;Nav 偏导航聚合;Landing / Starter 偏落地页;Plog、Photo 偏图集;更多说明见各主题子文档或源码中对应 config.js。
点击 预览站 左下角挂件可在线切换主题。
主题目录构成
每个主题下都有四个部分组成,以example主题为例,目录下有四个元素:
components 组件文件夹,下面存放着主题用到的所有组件,项目采用react架构,所有的按钮模块都是单独的组件。
config.js 针对当前主题的配置
index.js 存放主题的基础布局和对应的路由关系
style.js 自定义的css样式
如何修改默认主题?
新手常见问题:固定 simple 主题并隐藏切换按钮
如果你只是想固定使用 simple 主题,并且不想让页面显示“切换主题”按钮,不需要改代码。
优先在 Notion Config 表里添加这三项:
THEME=simple
THEME_SWITCH=false
WIDGET_PET_SWITCH_THEME=false含义如下:
THEME=simple:固定使用 simple 主题。THEME_SWITCH=false:隐藏页面上的主题切换按钮。WIDGET_PET_SWITCH_THEME=false:防止点击宠物挂件时切换主题。
如果你没有使用 Notion Config,而是在 Vercel 后台配置环境变量,则填写:
NEXT_PUBLIC_THEME=simple
NEXT_PUBLIC_THEME_SWITCH=false
NEXT_PUBLIC_WIDGET_PET_SWITCH_THEME=false改完后重新部署一次。如果重新部署后仍然不是 simple,请先检查 Notion Config 表里是否已经写了其它 THEME,因为 Notion Config 的优先级高于 Vercel 环境变量,也高于 GitHub 代码里的默认值。
可以改变blog.config.js配置中THEME这一项的值;示例如下:
- 方法1:改动github中的源代码:
THEME: process.env.NEXT_PUBLIC_THEME || 'simple', // 与当前主仓库默认值一致;可按需改为 hexo、next 等文件夹名(小写)方法2 , 在vercel后台添加环境变量:
NEXT_PUBLIC_THEME方法3: 使用Notion_config,在您的notion笔记中配置默认主题
在线切换主题
您可以像我的博客站一样,在页面上开启一个实时切换主题的按钮,以供预览;开启方式:在主仓库 [conf/widget.config.js](https://github.com/notionnext-org/NotionNext/blob/main/conf/widget.config.js) 中调整(或在部署后台配置环境变量 NEXT_PUBLIC_THEME_SWITCH):
THEME_SWITCH: process.env.NEXT_PUBLIC_THEME_SWITCH || false, // 是否显示切换主题按钮;预览站常开便于体验说明:此项已自 blog.config.js 拆至挂件配置;亦可在 Notion Config 表格中写同名键覆盖,优先级仍为 Notion Config 高于环境变量、高于代码默认值。
开启后效果如下:网页上会始终悬挂一个可以拖拽的面板,用于切换主题。
主题控制台与调色板
新版主题切换工具同时提供“主题切换”和“主题控制台”两个入口。主题控制台可以实时调整当前主题的信息配置与配色,确认效果后复制到 notion_config。详细使用方式见 主题控制台与调色板。
如何个性化您的主题
主题的微调
可以参考本文档丶关于各个主题可支持的配置进行修改:
另外您可以参考开发指引中的教程来自定义您的主题。
NotionNext开发先导 | NotionNext帮助手册
小白入门如何开发notionnext,下载NotionNext、启动NotionNext、提交合并到NotionNext等。
NotionNext用配置调整样式 | NotionNext帮助手册
不会react、不会 nextjs、不会webpack、不会TailWindCSS如何调整样式
创建您的主题
您可以复制一个现有的主题,并在此基础进行二次开发。更多关于创建主题与开发的功能,请阅读开发教程:
NotionNext自建主题 | NotionNext帮助手册
简单几步骤即可创建属于自己的主题
也欢迎您将自己开发设计的主题,通过PR的方式提交到NotionNext中央仓库中,提供给更多站友们使用。
最后
接下来在这个主题配置栏目下我将逐一介绍各个主题的配置,但在看主题个性配置前,请确保您已经完整阅读站点的基础配置部分:‣ 。
原文链接
https://docs.tangly1024.com/article/notion-next-themes
DOCUMENTATION POLICY (`docs/DOCUMENTATION_POLICY.md`)
NotionNext 使用说明文档维护策略
维护位置(权威来源)
自 2026 年起,NotionNext 文档以本仓库 docs/ 目录为主维护面,并逐步替代仅依赖 Notion 托管的在线手册(docs.tangly1024.com)。
文档站不再把“站长教程”和“开发者文档”做成访问边界。user-guide/ 负责从部署、配置、主题使用开始,developer/ 继续承接架构、贡献、主题迁移和维护决策。借助 AI 开发后,修改主题、排查问题、补文档和提交 PR 的门槛已经降低,文档应鼓励每个使用者逐步成为贡献者。
| 目录 | 用途 |
|---|---|
docs/user-guide/ |
部署、配置、Notion 数据库、菜单、升级等用户教程(从官方站点迁移并持续更新) |
docs/user-guide/reference/ |
4.9.x 参考手册:全站配置索引、Notion 新能力(与 conf/ 同步维护) |
docs/user-guide/themes/THEMES_CATALOG.md |
26 个内置主题全表与选型 |
docs/developer/ |
架构、贡献流程、维护手册、主题迁移、RFC 等进阶文档(在线站可见) |
docs/developer/themes/ |
主题实现长文、迁移计划、上游来源与许可证说明 |
为何迁到 GitHub
- 版本与代码同步:文档与
main分支、发行版号(如 4.9.5.x)同仓管理,避免「站点文档滞后于代码」。 - PR 可审阅:教程修正与功能改动可同一 PR 讨论。
- 可构建静态站:Markdown 可经 VitePress / Nextra 等生成可浏览网站(规划见
user-guide/WEBSITE.md)。 - 离线可读:克隆仓库即可阅读,不依赖 Notion API 拉取文档库。
与线上一致性
- 已迁移文章文末保留 「原文链接」,指向 docs.tangly1024.com 对应页面,便于对照与补图。
- 官方 Notion 文档库在过渡期仍可能更新;以本仓库
docs/user-guide/最新提交为准 作为 notionnext-org 主线推荐说明(fork 可自行同步)。
贡献者如何改文档
操作步骤、目录秩序、检查清单见 用户文档维护工作流(维护者必读)。
简要规则:
- 使用教程 → 编辑
docs/user-guide/**/*.md,并同步user-guide目录索引、ARTICLE_INDEX.md。 - 主题使用说明 →
docs/user-guide/themes/.md;主题实现、迁移和维护细节 →docs/developer/themes/,两边互相链接。 - 勿将个人
.env、私有 ID 写入示例。 - PR 描述中注明:是否替代/补充线上某篇文档(附 slug 或 URL)。
迁移进度
官方帮助手册核心栏目已迁入 user-guide/,对照表见 user-guide/ARTICLE_INDEX.md。状态见 user-guide/MIGRATION_STATUS.md。
English summary
Documentation is maintained in this repo under docs/, as the long-term source of truth replacing Notion-only hosting at docs.tangly1024.com. User guides and developer docs are both published to the VitePress site so users can gradually become contributors. Migrated pages link back to the legacy site during transition.
Community PINNED DISCUSSION POSTS.Zh CN (`docs/community/PINNED_DISCUSSION_POSTS.zh-CN.md`)
Discussions 置顶帖草稿
在仓库 Settings → Discussions → Pin discussion 使用下列内容。建议发在 「公告」 分类(若无该分类,先用 General 并设为公告)。
帖一:欢迎参与 NotionNext 社区(建议置顶)
标题: 【公告】欢迎参与 NotionNext 社区维护
正文(复制以下内容):
大家好,
NotionNext 已由个人仓库移交至组织 notionnext-org,正在向社区协作维护过渡。无论你是站长还是开发者,都欢迎参与。
你可以这样参与
| 我想… | 去哪里 |
|---|---|
| 学部署、改配置 | 使用说明文档站 |
| 提问、交流经验 | 本区 「使用问答」 发 Discussion(比 Issue 更合适) |
| 改教程、纠错 | 文档页底 「在 GitHub 上维护此页」 → 提 PR |
| 修 Bug、做功能 | Contributing → Fork → PR |
| 长期维护、加入组织 | 先合并 1~2 个 PR,再发 「组织成员申请」 讨论(见模板) |
完整路径见:参与社区指南
当前最需要帮助
- 带
good first issue标签的任务(文档、小修复为主) - 带
help wanted的任务
请注意
旧版 Notion 托管教程仍在 docs.tangly1024.com;新版以仓库 docs/user-guide/ 为准。
感谢每一位 Contributor ❤️
帖二:维护者分工与合并约定(建议置顶或链在帖一)
标题: 【公告】维护者分工与 PR 合并约定
正文:
本文说明谁负责什么、如何减少重复劳动,详细规则见 维护者运行手册 与 项目治理。
负责域(招募中,欢迎认领)
| 域 | 范围 | 当前 |
|---|---|---|
| 文档站 | docs/user-guide/、VitePress |
招募中 |
| 内置主题 | themes/<name>/ |
招募中(可在主题文档注明 @维护者) |
| CI / 构建 | .github/workflows/ |
招募中 |
| 数据层 / Notion API | lib/db/ 等 |
@tangly1024 守门 |
| 发版 / 组织 | tag、Secrets、成员邀请 | Org Admin |
认领方式:合并若干 PR 后,用 「组织成员申请」 模板发帖,或在本帖回复负责域。
合并约定(摘要)
- 所有改动走 PR,CI 须通过(lint、类型检查、测试、lockfile;文档另过 VitePress 构建)
- 仅文档(
documentation标签 /docs/**):具备 Write 的维护者 Review 后即可合并,无需 Founder 必审 - 高影响路径(
lib/db、next.config.js、package.json等):需 CODEOWNERS 过目(通常为 Founder) - Dependabot PR:维护者每周批量 Review 合并(默认跳过 major 升级)
分流(请维护者转发,勿长篇私信 Founder)
- 使用类问题 → 使用问答 Discussion
- 重复 Issue → 关为 duplicate 并链到已有帖
- 缺环境信息 → 标
needs-info,请用户补版本/主题/部署方式 - 长期无活动 → 由 Stale 工作流自动处理
已符合组织加入条件但未收到邀请?
请勿重复私信。请使用 Discussion 模板 「组织成员申请」 发帖,附上 GitHub 用户名与已合并 PR 链接。
帖三:用户作品墙征集(建议置顶或定期顶帖)
标题: 【征集】提交你的 NotionNext 站点到用户作品墙
正文:
如果你已经用 NotionNext 搭好了公开站点,欢迎把它提交到用户作品墙。
提交内容只需要一行:
| [站点名](https://example.com) | 用途 | 主题 | @yourname |建议字段:
| 字段 | 示例 |
|---|---|
| 站点名 | Tangly Blog |
| 站点链接 | https://blog.tangly1024.com |
| 用途 | 个人博客、知识库、作品集、产品官网、导航站 |
| 主题 | simple、heo、starter、gitbook |
| 提交人 | @yourname |
收录到 Showcase 后,可以帮助新用户参考真实案例,也让维护者知道哪些主题和场景需要优先补文档、截图和模板。
作品墙页面: https://notionnext.tangly1024.com/user-guide/showcase
已发布(2026-05-17)
分类:Announcements。请在 Discussions 列表对以上三帖各点一次 Pin discussion 置顶(API 暂不支持自动 Pin)。
发帖步骤(若需重发)
- 打开 https://github.com/notionnext-org/NotionNext/discussions/new/choose
- 选择分类 Announcements
- 粘贴上面对应标题与正文
- 发布后 Pin discussion
- (可选)将帖一链接写入组织 Profile README
修改正文后请同步编辑上述 Discussion 页面。
Community SHOWCASE DISCUSSION POST.Zh CN (`docs/community/SHOWCASE_DISCUSSION_POST.zh-CN.md`)
用户作品墙征集帖草稿
在 GitHub Discussions 发布,用于征集已经上线的 NotionNext 站点。
建议分类:Show and tell、使用问答 或 General。如果 Discussions 没有单独的展示分类,先发到 General 并置顶一段时间。
标题
【征集】提交你的 NotionNext 站点到用户作品墙正文
大家好,
NotionNext 文档站新增了「用户作品墙」:
https://notionnext.tangly1024.com/user-guide/showcase
如果你已经用 NotionNext 搭好了公开网站,欢迎在本帖回复你的站点。我们会把合适的站点整理到 Showcase 页面,让更多人看到社区成员的作品,也帮助新用户按真实案例选择主题。
### 可以提交哪些站点?
- 个人博客
- 作品集 / 个人品牌站
- 知识库 / 文档站
- 产品官网 / SaaS 落地页
- 导航站 / 资源聚合站
- 其他使用 NotionNext 搭建的公开站点
### 回复格式
请按这个格式回复:
| 字段 | 内容 |
| --- | --- |
| 站点名 | 你的站点名称 |
| 站点链接 | https://example.com |
| 用途 | 博客 / 作品集 / 知识库 / 产品官网 / 导航站等 |
| 主题 | 使用的 NotionNext 主题 ID,例如 `simple`、`gitbook`、`starter` |
| 提交人 | GitHub 用户名或站点作者名 |
也可以直接用一行格式:
```md
| [站点名](https://example.com) | 个人博客 | simple | @yourname |收录规则
- 站点需要公开可访问。
- 内容需要合法,并与 NotionNext 使用场景相关。
- 失效链接、违法内容、明显无关内容会被移除。
- 如果你后续换主题、换域名或不想继续展示,可以在本帖回复更新。
感谢每一位愿意展示站点的朋友。真实案例会让后来者少走很多弯路。
## 发布后维护
发布后建议把链接补到 `docs/user-guide/showcase.md` 的提交说明里,方便新用户直接跳转到征集帖。
---
### Developer ALGOLIA SEARCH RUNTIME.Zh CN (`docs/developer/ALGOLIA_SEARCH_RUNTIME.zh-CN.md`)
# Algolia 弹窗搜索
弹窗要求同时配置 `ALGOLIA_APP_ID`、`ALGOLIA_SEARCH_ONLY_APP_KEY`、`ALGOLIA_INDEX`。已配置 `ALGOLIA_APP_ID` 但缺少搜索密钥或索引时,搜索入口回退到本站 `/search` 页面。未配置 `ALGOLIA_APP_ID` 时不启用 Algolia 快捷键、不触发导航,保留主题自身的 Ctrl+K 行为。浏览器只应使用搜索专用密钥。
GitBook 的本地搜索框只有在三项 Algolia 配置齐全时才打开弹窗。配置不完整时,聚焦和输入不会触发跳转,Enter 继续筛选本地目录,Esc 清空本地搜索。全局 Algolia Ctrl+K 的显式回退条件保持不变。
输入后等待约 600 毫秒发起请求。继续输入、清空输入、关闭弹窗或切换页面后,旧请求的响应不会覆盖当前结果。加载时显示状态;请求失败时显示可重试提示,点击“重试”重新请求当前关键词和页码。
弹窗打开后焦点进入搜索框;Tab / Shift+Tab 在弹窗内的关闭按钮、输入框、标签、结果链接、重试按钮和分页按钮之间移动。Esc 在整个弹窗内生效,关闭后焦点返回仍在页面上的打开入口;关闭的弹窗不会进入 Tab 顺序或暴露给读屏软件。输入框内仍可用 ↑ / ↓ 选择结果、Enter 跳转。
---
### Developer ARCHITECTURE.En (`docs/developer/ARCHITECTURE.en.md`)
# Architecture Overview
[中文](./ARCHITECTURE.md)
## Core flow
NotionNext main flow can be simplified as:
1. **Data access layer** (`lib/db/`)
Fetches Notion data, normalizes structure, maps fields, handles cache and dedup.
2. **Server data assembly** (`lib/db/SiteDataApi.js`)
Produces `allPages`, `tagOptions`, `categoryOptions`, `siteInfo`, etc.
3. **Routing layer** (`pages/`)
Handles route-level filtering, pagination, and render preparation.
4. **Theme layer** (`themes/`)
Themes consume the same props contract and render different UI.
## Config priority
Priority (high -> low):
1. Notion Config page key
2. Environment variable
3. Local config (`blog.config.js` + `conf/*.config.js`)
## Why “move rules to data layer”
If a sorting/filtering rule is global business logic, place it in data layer instead of duplicating it in route files.
Benefits:
- Smaller change surface
- Lower risk of missing routes
- Consistent behavior across themes
## Cache & build
- Cache modules: `lib/cache/`
- Build prefetch/concurrency: `lib/build/`
- Changes here can impact CI speed and deployment stability; include validation notes.
---
### Developer ARCHITECTURE (`docs/developer/ARCHITECTURE.md`)
# 架构总览
[English](./ARCHITECTURE.en.md)
## 核心链路
NotionNext 的主流程可以简化为:
1. **数据获取层**(`lib/db/`)
从 Notion 拉取数据、做结构归一化、字段映射、缓存与去重。
2. **服务端数据组装层**(`lib/db/SiteDataApi.js`)
统一产出 `allPages` / `tagOptions` / `categoryOptions` / `siteInfo` 等。
3. **路由层**(`pages/`)
在 `getStaticProps/getStaticPaths` 中做页面级过滤、分页、渲染准备。
4. **主题层**(`themes/`)
各主题通过统一的数据契约消费 `props`,渲染不同 UI。
## 数据优先级
配置读取优先级(高 -> 低):
1. Notion Config 表同名键
2. 环境变量(`.env.local` / 部署平台 env)
3. `blog.config.js` + `conf/*.config.js`
## 为什么强调“数据层下沉”
如果某个排序/过滤策略属于“全局业务规则”,优先放在数据层而非分散在多个页面路由中。
好处:
- 减少改动面和重复逻辑
- 降低漏改风险(分页/分类/搜索路由容易遗漏)
- 让所有主题行为一致
## 缓存与构建相关
- 缓存模块位于 `lib/cache/`
- 构建阶段并发与预热逻辑位于 `lib/build/`
- 这些模块会影响 CI/CD 和大站点构建速度,改动时需要附带验证说明
---
### Developer CACHE MAINTENANCE.Zh CN (`docs/developer/CACHE_MAINTENANCE.zh-CN.md`)
# 数据缓存与页面重建
维护接口只接受 POST,并返回 `Cache-Control: no-store`。未配置令牌时返回 503,错误令牌返回 401。
- `/api/cache` 使用 `Authorization: Bearer <CACHE_REVALIDATION_TOKEN>`,清理文件、内存和已配置的 Redis 数据缓存;不会自动重建 ISR 页面。
- `/api/revalidate` 使用 `Authorization: Bearer <REVALIDATION_TOKEN>`,按请求范围重建页面。兼容请求体中的 `token` 字段。
请求体支持 `{"path":"/article/example"}`、`{"paths":["/","/article/example"]}` 或 `{"all":true}`。批量输入限制为 1 至 500 个站内路径;不接受完整 URL、API 路径、查询参数或路径穿越片段。
单页和 `paths` 请求默认只重建明确指定的页面,不清空数据缓存,也不自动重建其他语言或列表入口。这保留了单页 webhook 的原有成本;页面仍受底层数据缓存有效期影响。如果必须立即读取新数据,可以显式传入 `{"path":"/article/example","invalidateData":true}`。该选项会清空全站数据缓存,但仍只重建指定路径,宜用于低频人工维护。需要联动的首页、分类或标签页应由调用方放入 `paths`。
`all: true` 会先收集旧路径、清空数据缓存,再收集新路径,覆盖新旧文章、首页、归档、搜索、分类、标签及列表分页,包含配置的语言前缀和构建清单中的历史路径。可用 `paths` 同时补充已知历史 URL。`all: true` 不能与 `invalidateData: false` 同时使用。
Vercel Hobby 旧版计算模式的函数上限为 60 秒,因此 `/api/cache` 和 `/api/revalidate` 均设置了 60 秒上限以兼容未启用 Fluid Compute 的项目。所有请求默认最多重建 25 个路径,可设置整数 `batchSize`(1 至 50)。每批最多并发 3 个页面,运行 45 秒后停止发起新的页面重建,为 Hobby 函数留出返回续传结果的时间。响应中的 `results` 仅包含本批已尝试的页面,`remainingPaths` 是尚未尝试的路径;`complete` 表示没有剩余路径,并不代表全部成功。HTTP 200 表示全部完成且成功,202 表示本批成功但仍有剩余路径,任一已尝试页面失败返回 500,缓存清理或路径发现失败返回 503。
大站点调用流程:
1. 首次发送 `{"all":true,"batchSize":25}`,保存响应中的 `remainingPaths`。
2. 将待处理路径按数量(最多 500 个)和请求体大小(最多 32 KB)拆分,发送 `{"paths":[...],"batchSize":25}`;合并本次响应的剩余路径与本地尚未发送的路径。
3. 重复步骤 2,直至待处理路径为空。将 `results` 中 `revalidated: false` 的路径单独记录并按需重试。
续传不要再传 `all: true` 或 `invalidateData: true`,以免重新清理数据与发现全站路径。这里采用调用方保存进度的同步批次,不在 Serverless 请求结束后运行后台任务。45 秒预算不能中断已经开始的路径发现、缓存清理或 `res.revalidate`;这些步骤本身若超过平台上限,仍可能被平台终止。遇到单页渲染较慢的情况,应减小 `batchSize`,部署平台超时后可安全重试该批路径。
每次数据清理(`/api/cache`、`all: true` 或 `invalidateData: true`)都会更换缓存版本,清理前启动的请求即使后来完成,也不会覆盖新版本的数据。版本号在进程内缓存 1 秒,合并并发读取,避免每次缓存访问都额外读取 Redis 或同步文件;轮换版本后等待 1 秒传播窗口,再完成清理并开始页面重建。
**AI 摘要与调用费用:** `ai_summary_*` 与 Notion 数据共用缓存版本和清理范围。以上任一数据清理操作都会使已缓存的 AI 摘要失效,即使 `AI_SUMMARY_CACHE_TIME` 尚未到期;配置 `AI_SUMMARY_API` 的站点在后续页面重建或访问时可能再次调用摘要服务并产生费用。高频 webhook 宜使用默认的 `path` / `paths` 请求,按需集中执行全量失效。当前维护接口没有保留 AI 摘要的选项;需要跨全量清理复用付费摘要时,应在摘要服务端另行缓存。
**HTTP 状态与重试:** 旧版部分页面重建失败仍返回 200,现在任一已尝试页面失败都会返回 500。即使收到 500,也应读取 JSON 中的 `results` 和 `remainingPaths`:失败页在 `results` 中,不会重复放入 `remainingPaths`;`complete: true` 仅表示所有路径都已尝试。将失败页与尚未尝试的路径合并去重后,以不带 `all` / `invalidateData` 的 `paths` 请求继续处理,避免重复刷新已经成功的页面。
不要为带 `all: true` 或 `invalidateData: true` 的请求配置自动重试;重放会再次清理数据,全站请求还会重新发现路径,并可能重复调用付费摘要 API。收到 503、连接中断或平台超时时,数据清理可能已经执行;先核对服务端日志和已保存的进度,仅对已知路径使用普通 `paths` 请求重试。没有拿到完整路径计划时,应由运维确认是否重新发起全量维护。
**多实例与 Serverless 部署要求:** 所有提供页面数据的实例必须使用同一 `REDIS_URL` 和 Notion 根页面配置,才能共享版本及清理结果。仅使用内存或本地文件时,清理无法使其他隔离实例失效,`res.revalidate` 可能命中其他实例旧数据,不能保证全站立即更新。同一主机的进程也必须共享文件缓存目录。Redis 和内存键按 Notion 根页面配置区分站点;生产共享 Redis 的可用性仍是同步失效的前提。
不在旧站点数据或构建清单中的历史运行时 URL 无法枚举,应通过 `paths` 明确刷新。
回归验证包含真实临时目录中的版本号读写、原子替换和独立模块实例测试。Redis 集成测试须显式配置独立测试实例 `NOTIONNEXT_TEST_REDIS_URL`,然后运行 `yarn jest __tests__/lib/cache/redis.integration.test.js --runInBand`;未配置时跳过,不会连接站点的 `REDIS_URL`。该测试使用随机命名空间,验证真实版本读写及多批 `SCAN` 清理,不执行 `FLUSHDB`。
---
### Developer COMMUNITY SITE ROADMAP (`docs/developer/COMMUNITY_SITE_ROADMAP.md`)
# 社区官网能力扩展路线
## 背景
NotionNext 现在非常适合做个人博客、作品集、知识库和轻内容站点,但如果要承接“社区官网”场景,会很快碰到几个结构性短板:
1. **单作者模型过强**
当前很多主题和 SEO 元数据默认围绕 `AUTHOR`、`AVATAR`、`BIO` 这一组单人字段展开。
2. **组织信息与内容信息没有分层**
社区成员、活动、报名表、招募信息、内容文章,都会被当作普通页面/文章处理,缺少清晰的数据角色区分。
3. **表单与活动闭环能力薄弱**
可以展示活动,但缺少发布活动、收集报名、展示成员、回显状态的统一方案。
4. **多人展示能力不足**
缺少成员列表、头像预览、成员 bio、角色标签、社交链接、成员详情页等常见社区模块。
这意味着:NotionNext 目前更像“博客模板集合”,而不是“内容驱动的社区官网框架”。
## 适用场景
这个方向适合:
- 开源社区官网
- 校园组织官网
- 创作者社区主页
- DAO / 社群主页
- 沙龙 / meetup 组织官网
- 有活动、成员、内容、招募四类信息的轻运营站点
## 当前能力与缺口
### 已有基础
- 有统一数据层:`lib/db/SiteDataApi.js`
- 有主题层可消费统一 `props`
- 有部分“团队区块”雏形,例如 `starter` 的 Team 组件
- 有配置驱动和 Notion Config 机制
- 有路由与静态生成能力,适合做目录页和详情页
### 主要缺口
#### 1. 成员管理
缺少:
- 成员集合的数据模型
- 成员头像列表 / 卡片墙
- 成员 bio / role / social links
- 成员详情页
- 成员与内容的关联关系
#### 2. 社区内容分层
建议把现有内容至少拆成四类:
- `Post`: 普通内容文章
- `Member`: 社区成员
- `Event`: 活动
- `Page`: 静态说明页
实现时,`Member` / `Event` 应与现有 Notion 页面 `type` 约定、`lib/db/SiteDataApi.js` 的数据契约,以及主题 `props` 与路由的既有模式对齐,避免与文章/页面流程硬分叉。
如果继续全部混在 `Post/Page` 里,后续主题、搜索、SEO、列表页、导航、侧边栏都会越来越难维护。
#### 3. 活动发布与展示
缺少:
- 活动列表页
- 活动详情页
- 时间 / 地点 / 报名截止时间 / 状态字段
- 已结束 / 进行中 / 即将开始 的状态管理
- 活动与表单链接的标准化展示
#### 4. 表单收集
缺少:
- 报名入口字段
- 外部表单嵌入 / 跳转规范
- 表单型页面的 UI 约定
- 收集结果的接入说明
这里不一定要求 NotionNext 自己做完整后端,更现实的做法是:
- 先支持 **外部表单链接 / 嵌入**
- 再考虑接入 Airtable / Notion Form / Tally / 飞书表单 / 自建 API
#### 5. 多人作者展示
当前 `AUTHOR / AVATAR / BIO` 基本是单人站点思路。社区官网更需要:
- 页面级作者卡片
- 多作者/多维护者
- 成员头像预览
- 成员简介与职责
- 内容作者与组织成员分离
## 建议的数据模型
### Member
建议最小字段:
- `slug`
- `name`
- `avatar`
- `bio`
- `role`
- `tags`
- `socialLinks`
- `joinedDate`
- `status`
- `featured`
### Event
建议最小字段:
- `slug`
- `title`
- `summary`
- `cover`
- `startDate`
- `endDate`
- `location`
- `eventStatus`
- `registrationUrl`
- `registrationEmbedUrl`
- `organizer`
- `speakers`
- `featured`
### Post
保留现有文章模型,但建议额外支持:
- `authors`(数组)
- `relatedMembers`
- `relatedEvents`
## 推荐的功能拆分顺序
### Phase 1: 社区展示基础能力
目标:先能“看起来像社区官网”。
建议 PR:
1. **成员集合支持**
- 在数据层识别 `Member`
- 提供 `allMembers`
- 支持成员详情页基础路由
2. **成员卡片列表组件**
- 头像
- 名称
- bio
- role
- 社交链接
3. **活动集合支持**
- 在数据层识别 `Event`
- 提供 `allEvents`
- 活动列表/详情页基础能力
### Phase 2: 社区运营能力
目标:先能“发活动、收报名、展示组织”。
建议 PR:
1. **活动状态字段规范**
- upcoming
- ongoing
- ended
- cancelled
2. **报名入口能力**
- `registrationUrl`
- `registrationEmbedUrl`
- `registrationNote`
3. **内容与组织信息分层**
- 导航、搜索、站点地图里区分 `Post / Member / Event / Page`
### Phase 3: 社区内容协作能力
目标:先能“多人协作发布内容”。
建议 PR:
1. **多作者支持**
- `authors` 数组
- 作者卡片
- 作者链接到成员页
2. **内容关联**
- 文章关联成员
- 文章关联活动
- 成员页回显内容贡献
## 建议优先发起的 Issue
最值得先提的不是“大而全社区系统”,而是以下 3 类高价值 issue:
1. **支持 Member / Event 内容类型**
- 这是所有社区场景的底座
- 技术上最适合先从数据层做
2. **支持多作者与成员资料卡**
- 对博客、团队站、社区站都有价值
- 复用面最大,最容易获得上游接受
3. **支持活动页与报名入口字段**
- 功能边界清晰
- 很适合拆成渐进式 PR
## 建议的 MVP Issue 文案方向
可以把问题描述成:
> NotionNext 目前对个人博客支持很好,但对社区官网/组织官网场景支持不足。建议在数据层与主题契约中增加 `Member` / `Event` 类型,以及成员资料卡、多作者、活动报名入口等基础能力,让项目不仅适合单作者博客,也适合多人社区站点。
这个表述的好处是:
- 不会显得需求过散
- 不是只替一个特定站点定制
- 更像“框架通用能力增强”
## 文档化建议
本文档可作为该方向的**总览路线图**。若后续落地实现,建议再补充更细的设计文档,例如:
- `docs/COMMUNITY_SITE_SCHEMA.md`(字段与数据契约)
- `docs/COMMUNITY_SITE_EXAMPLES.md`(主题与 Notion 配置示例)
---
### Developer CONFIGURATION.En (`docs/developer/CONFIGURATION.en.md`)
# Configuration System
[中文](./CONFIGURATION.md)
## Sources and priority
For keys with same name, priority is:
1. Notion Config page
2. Environment variables
3. Local files (`blog.config.js` / `conf/*.config.js`)
## Recommended practice
- Split large config sections into `conf/*.config.js`
- Keep `blog.config.js` mostly as aggregator
- For each new config key, document:
- default value
- env var name
- Notion Config same-name key
## High-risk open-source pitfalls
### 1) Do not commit personal configs
Usually should never be committed:
- `.env.local`
- private token/key content
- personal ad/analytics IDs as defaults
- personal-only menu/theme defaults
### 2) Avoid unrelated config edits
If task is a small bug fix, do not casually reformat/sort many config files.
### 3) Document new global configs
At minimum update:
- comment in config file
- docs or PR description usage notes
Theme-level configs follow the same rule. When adding a `themes//config.js` key, update `docs/user-guide/themes/.md` with the default value, enabled/disabled behavior, and whether Notion Config or environment variables can override it. Do not mark user-visible config changes as "docs not applicable".
---
### Developer CONFIGURATION (`docs/developer/CONFIGURATION.md`)
# 配置体系说明
[English](./CONFIGURATION.en.md)
## 配置来源与优先级
同名配置项的优先级:
1. Notion Config 表
2. 环境变量
3. 本地配置文件(`blog.config.js` / `conf/*.config.js`)
## 推荐实践
- 将大块配置拆分到 `conf/*.config.js`
- `blog.config.js` 仅做聚合,避免文件无限膨胀
- 新增配置项时,写清楚:
- 默认值
- 环境变量名
- Notion Config 同名键
## 开源协作高风险点(必须遵守)
### 1) 不要提交个性化配置
以下内容通常属于个人环境,不应提交:
- `.env.local`
- 带私人 key/token 的配置
- 带个人广告 ID、统计 ID、第三方埋点 ID 的默认值
- 仅个人站点使用的导航/菜单/主题私有配置
### 2) 避免修改与任务无关的配置文件
例如你只修复一个组件 bug,不应顺手改动大量 `conf/*.config.js` 排序或格式。
### 3) 新增全局配置时要文档化
至少更新:
- `conf/*.config.js` 注释
- 本目录文档或 PR 描述中的使用说明
主题级配置也遵守同一原则。新增 `themes//config.js` 配置项时,请同步更新 `docs/user-guide/themes/.md`,说明默认值、开启/关闭效果,以及是否支持 Notion Config 或环境变量覆盖。不要把用户可见配置标记为“文档不适用”。
---
### Developer CONTRIBUTION WORKFLOW.En (`docs/developer/CONTRIBUTION_WORKFLOW.en.md`)
# Contribution Workflow
[中文](./CONTRIBUTION_WORKFLOW.md)
## 1. Branch strategy
- Always branch from latest `main`
- One branch, one change type (feature/fix/docs)
- Naming examples:
- `fix/...`
- `feat/...`
- `chore/...`
- `docs/...`
## 2. Pre-commit checks
```bash
yarn lint
yarn type-check
yarn testIf build-chain changed:
yarn build3. Commit format
Prefer Conventional Commits:
feat(scope): ...fix(scope): ...docs(scope): ...chore(scope): ...
4. PR template suggestion
- Background / problem
- Approach (why this way)
- File-level scope
- Risk/compatibility notes
- Verification steps and results
5. Forbidden items
- Do not commit personal
.env.local - Do not include unrelated personal config changes
- Do not mix unrelated features in one PR
- Do not commit development changes directly to main
6. Reviewer-friendly habits
- Keep patch minimal
- Split large changes into smaller PRs
- Clearly mark breaking changes in PR description
Developer CONTRIBUTION WORKFLOW (`docs/developer/CONTRIBUTION_WORKFLOW.md`)
提交与 PR 协作规范
1. 分支策略
- 永远从最新
main拉新分支 - 一个分支只做一类改动(一个主题/一个功能/一个修复)
- 分支命名建议:
fix/...feat/...chore/...docs/...
2. 提交前检查
yarn lint
yarn type-check
yarn test如果改动涉及构建链路,建议额外执行:
yarn build3. 提交规范
推荐 Conventional Commits:
feat(scope): ...fix(scope): ...docs(scope): ...chore(scope): ...
4. 小 Bug 修复流程
小 Bug 最重要的是先把问题描述清楚,再进入修复:
- 实际现象:现在发生了什么。
- 期望现象:正常应该是什么。
- 复现步骤:从哪个页面或配置开始,按什么步骤能稳定复现。
如果复现步骤清楚,可以优先让 AI Agent 辅助处理,例如 Codex、Cursor、Claude Code、WorkBuddy 等支持自动读代码、改代码、提交 PR 的工具。NotionNext 已经内置开发文档、维护手册和文档站 AI 助手指令,适合先让 AI 阅读这些上下文,再执行最小修复。
推荐 AI Agent 工作流:
- 读取 Issue,确认实际现象、期望现象和复现步骤是否完整。
- 阅读相关项目文档,例如
docs/developer/README.md、docs/developer/PROJECT_STRUCTURE.md、docs/developer/CONTRIBUTION_WORKFLOW.md、docs/developer/MAINTAINER_RUNBOOK.zh-CN.md,以及对应主题文档。 - 从最新
main创建独立分支,保持工作区只包含本次修复。 - 先定位共享根因,再做最小代码改动,避免只修单一路径或顺手重构。
- 运行最小必要检查,例如目标文件语法检查、相关 lint/test、
git diff --check。 - 提交 PR,描述改动范围、风险、验证步骤,并回到原 Issue 附上 PR 链接。
建议给 AI Agent 的约束:
根据我的 Bug 描述,创建一个新分支修复这个问题,然后提交 PR 到云端仓库。
要求:
1. 只修复这个 Bug,不要混入我自己站点的个性化配置或无关改动。
2. 在能修复相同问题的前提下,尽量改动最少的代码,降低对其他用户的影响。
3. 修复前先阅读项目内置的开发文档、维护手册和相关主题文档。
4. 保留必要的本地检查结果,并在 PR 描述中说明改动范围、风险和验证步骤。5. PR 内容建议模板
- 背景/问题
- 方案说明(为什么这么做)
- 改动范围(文件列表)
- 风险与兼容性评估
- 验证步骤(本地命令 + 结果)
6. 明确禁止项(减少冲突)
- 不要把个人
.env.local提交到仓库 - 不要提交与你任务无关的个性化
config.js改动 - 不要把多个无关功能塞进同一个 PR
- 不要在主分支直接提交开发改动
7. 对评审者友好的做法
- 尽量做“最小补丁”
- 大改动拆分为多个小 PR
- 在 PR 描述中标注“是否包含破坏性变更”
8. 用户文档(user-guide)
修改或新增 docs/user-guide/ 时,请遵循 文档维护工作流:同步更新 README.md、ARTICLE_INDEX.md,并与 conf/*.config.js 中的配置键保持一致。
Developer GETTING STARTED.En (`docs/developer/GETTING_STARTED.en.md`)
Getting Started (New Contributors)
1. Requirements
- Node.js >= 20
- Yarn (default package manager in this repo)
- Git
2. Initialize the project
yarn
cp .env.example .env.localAt minimum, set this in .env.local:
NOTION_PAGE_ID
Then start dev server:
yarn dev3. Recommended local checks
yarn lint
yarn type-check
yarn test4. Read these first
5. First contribution advice
- Start with small scoped fixes (single file/module).
- Do not mix multiple change types in one PR.
- Ensure lint/test pass before opening PR.
Developer GETTING STARTED (`docs/developer/GETTING_STARTED.md`)
快速上手(新开发者)
1. 环境要求
- Node.js >= 20
- Yarn(项目默认使用 Yarn)
- Git
2. 初始化项目
yarn
cp .env.example .env.local在 .env.local 至少配置:
NOTION_PAGE_ID
然后启动:
yarn dev3. 推荐本地检查命令
yarn lint
yarn type-check
yarn test4. 你应该先读什么
5. 首次贡献建议
- 优先挑选小范围问题(单文件或单模块)
- 不要在一个 PR 混入多类改动(功能 + 依赖升级 + 个人配置)
- 提交前确保能通过本地 lint/test
Developer GROWTH ROADMAP.Zh CN (`docs/developer/GROWTH_ROADMAP.zh-CN.md`)
NotionNext 可持续增长路线图
这份路线图只解决一个问题:如何让更多人更快成功上线,并愿意把自己的经验、站点和改进反哺给社区。
NotionNext 的增长不应先依赖复杂平台能力。更短路径是把现有开源项目打磨成一个清晰飞轮:
新用户看懂价值 -> 20 分钟上线 -> 提交站点案例 -> 案例帮助下一批用户选型 -> 重复问题沉淀成文档和小 PR北极星指标
优先看这些信号,而不是先追求功能数量:
| 指标 | 说明 |
|---|---|
| 新用户首站成功率 | 用户能否按文档完成复制模板、Fork、部署和填写环境变量 |
| 从进入文档到上线时间 | 新手是否能在 20-30 分钟内看到可访问站点 |
| Showcase 提交数 | 有多少真实站点愿意公开展示 |
| 重复问题文档化率 | 高频 Issue / Discussion 是否被沉淀为 FAQ 或教程 |
| 首次贡献路径 | 新贡献者是否能从文档、截图、主题说明等低风险任务开始 |
90 天计划
Phase 1: 统一入口叙事(第 1-2 周)
目标:任何人打开仓库或文档站,都能马上知道 NotionNext 是什么、适合谁、下一步做什么。
最小任务:
- 重写英文 README,使它和中文 README 的定位一致。
- 清理 Vercel 部署页中的旧个人化措辞和旧仓库链接。
- 把“开始搭建 / 主题全览 / Showcase / 支持”做成稳定入口。
- 保留旧版手册链接,但降低它在新手路径中的权重。
验收:
- README 中英文都能回答:用它做什么、谁适合、怎么开始、哪里看案例。
- 部署页不再出现“复制我的代码”这类个人站长口吻。
- 新用户不需要在多个旧入口之间判断哪篇才是最新教程。
Phase 2: 建立 Showcase 飞轮(第 3-4 周)
目标:把真实用户站点变成最轻量的传播资产。
最小任务:
- 新增 Showcase 页面,公开征集用户提交已上线站点。
- 收集字段只保留:站点名、链接、用途、主题、提交人。
- 在 README、文档首页、主题目录和支持页加入 Showcase 入口。
- 在 GitHub Discussions 准备“提交你的站点”置顶帖。
验收:
- 用户能在 1 分钟内找到案例页面。
- 用户知道如何提交自己的站点。
- 每个案例能反向帮助新用户选择主题。
Phase 3: 模板驱动上手(第 5-8 周)
目标:让用户复制结果,而不是阅读大量配置。
最小任务:
- 梳理 5 个官方 Notion 模板入口:博客、知识库、作品集、产品官网、导航站。
- 每个模板只配一条推荐主题路径。
- 为每个模板写一页“适合谁 / 复制后改哪几处 / 推荐主题”。
- 把模板入口放进开始页和主题目录。
验收:
- 新用户可以按目标直接选模板。
- 模板文档不讲所有配置,只讲上线必须改的字段。
- 每个模板能对应到 Showcase 里的真实案例。
Phase 4: 社区维护转化(第 9-12 周)
目标:把重复支持成本变成社区资产。
最小任务:
- 每周从 Issue / Discussion 中整理 3-5 个重复问题。
- 能写文档就写文档,能标 good first issue 就标 issue。
- 支持页改成“免费支持 / 付费协助 / 赞助项目”三段。
- 新贡献者优先从文档、截图、主题说明、FAQ 小修开始。
验收:
- 支持页不再像私人付费页,而是清楚分流。
- 高频问题有固定链接可回复。
- 新贡献者能找到低风险入口。
协作边界
为了让公开路线图便于协作者执行,本页只记录已经适合公开讨论和拆分 PR 的方向。还没有验证的商业化设想、定价、内部优先级和私聊反馈,不放进公开仓库。
| 当前边界 | 原因 | 后续条件 |
|---|---|---|
| 不引入复杂后台 | Markdown 足够管理早期计划和案例 | Showcase 数量多到维护困难 |
| 不做大规模改版 | 当前最大问题是入口和路径 | 新手路径和案例飞轮跑通后 |
| 不扩大 PR 范围 | 小改动更容易审查和回滚 | 需要 RFC 的大功能另开讨论 |
当前推进顺序
先做最少文件的连续改动:
- 新增本路线图,并挂到文档站。
- 重写
README_EN.md。 - 清理
docs/user-guide/deploy-vercel.md的旧链接和个人化措辞。 - 新增
docs/user-guide/showcase.md。 - 把 Showcase 加到 README、文档首页和 VitePress 导航。
每一步都可以单独提交和回滚,不依赖大改版。
下一轮执行清单
当前进入 Phase 3/4 的小步推进,不新增后台,也不一次性补齐所有模板。
| 优先级 | 任务 | 验收 |
|---|---|---|
| P0 | 明确模板页的内容源边界 | 新用户能知道 NotionNext 用 Notion 写内容,GitHub 只负责代码和部署 |
| P1 | 先补博客和知识库两条模板路线 | 每条路线说明适合谁、先改哪几处、推荐主题 |
| P1 | 从最近 Issue / Discussion 抽 3 个重复新手问题 | 每个问题能指向已有文档,或生成一个可拆的小文档任务 |
| P2 | 继续收集 Showcase 站点 | 累计 3-5 个真实站点后,再反向完善模板示例 |
Developer HEO CONTROLS AND COMMENTS.Zh CN (`docs/developer/HEO_CONTROLS_AND_COMMENTS.zh-CN.md`)
Heo 评论与目录控制
Heo 使用与共享评论组件一致的启用判断。只配置 COMMENT_ARTALK_SERVER 或开启 COMMENT_NOTION_ENABLE 时,也会显示评论区域。Notion 评论开关接受布尔 true 或字符串 "true";未启用任何服务时不渲染空评论容器。
移动端悬浮目录使用原生按钮,可通过键盘操作,提供可访问名称和展开状态。关闭时目录内容处于隐藏状态,不进入键盘焦点顺序;目录外观与显示断点保持主题原有配置。
Heo 的评论区域由 themes/heo/index.js 的 LayoutSlug 渲染,测试应覆盖此实际入口。文章设置 comment: Hide、处于锁定状态或全屏阅读模式时,评论区域不渲染。Heo 和 Commerce 中未被引用的 JumpToCommentButton 已移除。
Endspace 的评论快捷按钮同样检查服务配置、comment: Hide 和文章锁定状态。没有目录的文章仍可跳到已启用的评论区;首页和未启用评论的文章不显示无效入口。
Endspace 的文章工具栏由 LayoutSlug 接收实时解锁状态与目录数据;首页和无法解锁时由 LayoutBase 保留通用工具栏。密码输入期间不启动缺失正文的 404 倒计时,避免尚未解锁的正常文章被误判为不存在。
Fuwari 的文章评论区域和浮动评论入口还受 FUWARI_ARTICLE_COMMENT 控制。关闭此开关、设置 comment: Hide 或文章尚未解锁时,两者均不显示,避免按钮滚动到不存在的评论区或留下空标题和边框。
Proxio 切换到另一篇文章时会收起目录抽屉,新的文章不会继承上一篇的展开状态。
目录关闭时保留过渡动画,并设置 aria-hidden 和 inert;支持 Esc、蒙层关闭后焦点返回触发按钮,以及切换文章后复位。目前 React 18 使用 inert='' 表示启用;升级至 React 19 时需改为布尔属性并重新验证键盘行为。
Heo 页面顶部回弹区域使用配置的浅色或深色背景。调色板实时预览背景时,会同时更新主题容器和文档根的背景变量;关闭调色板后保持预览,离开 Heo 主题时恢复文档根原有变量,避免预览残留。
Developer LONG TERM PLAN (`docs/developer/LONG_TERM_PLAN.md`)
NotionNext 开放生态长期计划
本文用于说明 NotionNext 的长期演进方向,帮助使用者、开发者、维护者和贡献者理解项目接下来为什么做、优先做什么、哪些能力适合进入开源主线,哪些能力更适合作为外部适配、社区模板或独立服务存在。
这不是商业化计划,也不是某个大版本的承诺清单。它的核心目标是让 NotionNext 在保持开源、自托管、可迁移、可定制的前提下,逐步覆盖更多真实站点场景。
长期定位
NotionNext 的长期定位是:
用 Notion 维护内容,用独立站完成发布、检索、展示和长期运营。
NotionNext 仍然会重视个人博客,这是项目最重要、最稳定的使用场景之一。同时,很多站长已经在用 NotionNext 搭建知识库、产品官网、导航站、课程站、社区官网和项目文档站。长期计划要承认这些真实用法,并把可复用的能力沉淀下来。
项目不应把所有复杂能力都塞进核心代码。更健康的方式是:核心保持稳定,接口保持开放,场景通过模板和文档逐步扩展,外部系统通过适配器接入。
读者视角
这份计划同时面向两类读者:
- 使用者和站长:可以用它判断 NotionNext 是否适合自己的站点,以及未来哪些场景会得到更好支持。
- 开发者和贡献者:可以用它判断哪些改动更容易被主线接受,以及如何把功能拆成文档、模板、接口和实现。
无论是哪类读者,都不需要依赖任何特定服务才能使用 NotionNext。自托管、Fork、二次开发和迁移能力应始终保留。
核心原则
开放优先
部署、主题、SEO、搜索、评论、统计、配置、文档、数据读取、升级体验等共性能力,应尽量保持开源、可自托管、可审计。场景先行
新方向先通过文档、Notion 模板、主题配置和示例站验证。只有被多个场景反复使用的能力,才适合抽象进核心。接口清晰
登录、表单、订阅、会员、线索、支付、CRM、通知等能力差异很大,不应一次性内置成一个重系统。更适合先定义字段约定、配置约定和适配器接口。可替换
外部服务只能作为选项。项目应避免把站点绑定到某个托管平台、评论系统、统计系统、表单系统、支付系统或邮件系统。不增加普通用户负担
新能力不能让普通博客用户的部署、配置和升级变复杂。复杂场景可以通过模板、插件和文档逐步启用。社区贡献友好
文档、模板、主题、测试、案例、问题复现和使用反馈都应被视为有效贡献,不应只重视核心代码贡献。
四条开放方向
1. 站点运营能力
目标:让 NotionNext 不只展示内容,也能帮助站长完成订阅、反馈、互动、线索收集和内容分层等轻量运营任务。
适合进入开源主线的部分:
- 表单、订阅、登录状态、内容可见性等扩展接口。
- Notion 数据库字段约定和示例模板。
- 基础表单提交示例。
- 登录可见内容的最小演示。
- 评论、统计、搜索、广告、邮件订阅等现有能力的文档索引。
适合作为外部适配或可选扩展的部分:
- 写入队列。
- 邮件通知。
- 用户资料页。
- 支付回调。
- 用户标签和分组。
- 运营看板。
- 多站点管理。
这个方向不等于要把 NotionNext 做成完整会员平台。短期目标是先补齐站点运营的基础接口和文档,让不同站长可以按自己的需求接入外部系统。
2. 部署与维护支持
目标:降低部署、升级、配置和排查问题的门槛,让更多非专业开发者也能长期维护自己的站点。
开源主线应加强:
- 部署前配置检查。
- 构建和缓存诊断。
- 常见平台部署文档。
- 升级指南。
- 主题兼容性检查。
- 更可读的失败信息。
- 常见问题排查手册。
可选支持可以承接:
- 部署协助。
- 域名和 HTTPS 配置协助。
- 升级协助。
- 主题安装协助。
- SEO 基础配置协助。
- 备份和恢复建议。
这些支持不应成为使用 NotionNext 的前提。它们只是为不想花时间排查基础问题的用户提供额外选择。
3. 主题与模板生态
目标:把 NotionNext 的主题优势扩展为可复用的场景方案,让用户可以从“我想做什么站”出发,而不是先理解所有技术细节。
一个完整模板不只包含页面样式,还可以包含:
- Notion 数据库结构。
- 推荐字段。
- 主题配置。
- 示例内容。
- 部署说明。
- 可选插件组合。
- 常见修改位置。
优先场景:
- 个人博客。
- 知识库。
- 开源项目官网。
- 产品官网。
- 课程站。
- AI 工具导航站。
- 社区官网。
推进方式:
- 先建立模板提交规范。
- 再维护精选模板目录。
- 鼓励社区模板、官方示例模板和第三方模板共存。
- 对模板质量、可维护性和兼容性建立基本检查。
模板生态的重点是开放复用,而不是制造封闭入口。用户应能清楚知道模板改了哪些字段、依赖哪些配置、如何迁移和二次修改。
主题配色也需要从“快速开发优先”进入“长期定制优先”的阶段。早期大量使用 Tailwind CSS 工具类,是为了让主题和组件能快速成型;随着主题数量增加、站点风格差异扩大,颜色继续散落在组件 className 中会让用户改色困难,也会让维护者难以判断某个 blue、indigo 或 yellow 到底代表主色、强调色、背景还是状态色。
后续主题应逐步过渡到语义色变量方案:每个主题在 themes//config.js 中声明可配置色号,例如 HEO_COLOR_PRIMARY、HEO_COLOR_ACCENT、HEO_COLOR_BG、HEO_COLOR_CARD、HEO_COLOR_BORDER、HEO_COLOR_TEXT;在 themes//style.js 中映射为主题作用域 CSS 变量,例如 --heo-color-primary。组件应使用语义变量,而不是继续把视觉语义写成 Tailwind 固定色名。
主题切换工具也应演进为主题定制入口:切换到某个主题时,面板可以显示当前主题的调色板。像 Fuwari 这类只有一个主色的主题,只展示一个主色调色项;像 Heo 这类视觉层次更丰富的主题,则展示主色、强调色、背景、卡片、边框、正文等多个色号。调色板需要显示配置键、当前色值和可复制内容,帮助用户把调好的颜色回填到 Notion Config、环境变量或主题配置文件中。
4. 场景模板:AI 工具导航站
目标:把 AI 工具导航站作为一个具体场景模板来验证 NotionNext 的内容组织能力,而不是一开始做成独立平台。
选择这个场景的原因:
- 与 Notion 数据库天然匹配。
- 适合展示筛选、标签、榜单、分类、详情页和 SEO 页面。
- 可以验证模板规范、主题组件、提交入口和站点运营能力。
- 复杂度适中,便于拆成多个小 PR。
第一阶段只做模板和文档:
Tool数据库字段规范。- 工具列表页。
- 分类页。
- 标签页。
- 工具详情页。
- 推荐榜单。
- 提交入口。
- SEO 元数据规范。
如果该模板产生真实使用案例,再把可复用能力抽象为通用模块。
阶段计划
0-3 个月:统一叙事和基础入口
目标:让社区理解 NotionNext 是 Notion 驱动的独立站框架,既适合博客,也适合更多内容站场景。
重点任务:
- 完善愿景、路线图和场景文档。
- 梳理博客、知识库、导航站、产品官网、社区官网的推荐路径。
- 建立模板文档结构。
- 为 AI 工具导航站写第一版模板说明。
- 梳理现有邮件订阅、评论、统计、搜索、广告等运营能力。
- 补充部署检查和升级排查文档。
验收标准:
- 新用户能判断自己适合哪类站点。
- 贡献者能看到可拆分的小任务。
- 站长能按场景找到模板和配置说明。
3-6 个月:做出第一个完整场景模板
目标:让一个具体场景跑通内容、模板、部署和基础互动。
优先建议选择 AI 工具导航站或课程知识库。
重点任务:
- 定义场景数据库字段。
- 提供示例 Notion 模板。
- 提供主题配置示例。
- 支持提交入口或外部表单链接。
- 支持分类、标签、筛选和详情页的稳定展示。
- 形成一篇完整的从复制模板到上线的教程。
验收标准:
- 一个普通站长可以按教程搭建完整站点。
- 模板能沉淀真实案例和反馈。
- 不需要改核心代码也能完成大部分配置。
6-12 个月:抽象扩展接口
目标:把前期场景中反复出现的能力抽象成稳定接口。
重点任务:
- 表单提交适配器。
- Notion 数据写入规范。
- 登录状态接口。
- 内容可见性规则。
- 邮件订阅适配器。
- 用户资料字段。
- 站点事件记录规范。
验收标准:
- 扩展能力不与某个主题硬绑定。
- 普通站点可以不用这些能力。
- 复杂站点可以通过配置或插件接入。
- 外部系统可以被替换。
12 个月以上:形成开放生态
目标:让开源项目、模板生态、外部适配和可选支持互相增强。
重点任务:
- 模板目录和推荐标准。
- 主题质量检查。
- 外部适配器清单。
- 可选支持边界说明。
- 多站点管理和升级策略调研。
- 更多真实站点案例。
验收标准:
- 开源仓库仍然可自托管、可迁移、可二次开发。
- 外部服务不会阻塞开源使用。
- 模板和真实案例能持续反哺主线能力。
不做什么
短期内不建议做:
- 完整会员 SaaS 平台。
- 与 Ghost、Substack、Patreon 正面竞争的订阅平台。
- 强绑定某个托管服务的闭源内核。
- 把支付、权限、CRM、邮件全部塞进主仓库。
- 一次性重写主题系统。
- 为单个站点加入不可复用的定制逻辑。
- 让基础使用路径依赖某个付费服务。
维护者判断清单
当一个新功能被提出时,先问:
- 它是多数 NotionNext 站长的共性问题吗?
- 它能否先用文档、模板或配置解决?
- 它是否需要进入核心,还是适合作为适配器?
- 它是否会增加普通博客用户的维护负担?
- 它是否能沉淀为可复用的主题、组件或数据契约?
- 它是否会破坏自托管、可迁移和开源透明性?
- 它是否允许用户替换外部服务?
只有当这些问题有清晰答案时,才适合进入实现阶段。
推荐的下一批小任务
| 方向 | 最小任务 |
|---|---|
| 场景文档 | 新增“如何选择站点类型”文档,覆盖博客、知识库、导航站、课程站、产品官网 |
| 模板生态 | 定义模板包结构:Notion 模板、主题配置、示例内容、部署说明 |
| 主题配色 | 为主题定义语义色变量规范,并先在一个代表主题中落地调色板配置 |
| AI 导航站 | 设计 Tool 数据库字段,并提供第一版模板说明 |
| 运营能力 | 梳理现有评论、统计、搜索、邮件订阅、广告能力,形成运营能力索引 |
| 部署维护 | 新增部署检查清单和常见升级问题排查页 |
| 社区路线 | 把 Member / Event 与社区官网路线图拆成可执行 Issue |
这份计划的关键不是同时启动所有方向,而是让每个方向都能从开源主线自然长出来:先文档和模板,再接口和示例,最后才是更复杂的外部适配和可选支持。
Developer MAILCHIMP SUBSCRIBE.Zh CN (`docs/developer/MAILCHIMP_SUBSCRIBE.zh-CN.md`)
Mailchimp 邮件订阅
设置 MAILCHIMP_API_KEY 和 MAILCHIMP_LIST_ID 后可使用订阅接口。数据中心从 API Key 的 -usN 后缀读取,不再固定为 us18。
POST /api/subscribe 请求体为 {"email":"[email protected]","firstName":"Reader","lastName":"Example"};姓名可省略。浏览器 helper subscribeToNewsletter(email, firstName, lastName) 使用同样的字段。
Mailchimp 接受新请求和返回 Member Exists 时,接口均返回相同的 200 和中性提示“Subscription request received…”,使这两类请求无法通过响应状态或文案区分。这个结果只表示请求已处理,不承诺该地址已完成订阅。
新建成员使用 pending 状态,要求邮箱持有人通过 Mailchimp 确认邮件完成订阅;这也避免归档成员被直接恢复为已订阅。重复地址不会触发 PUT/upsert、再次确认邮件或状态更新,已退订成员不会被自动恢复。需要重新订阅但未收到确认邮件时,应使用站点所有者提供的 Mailchimp 订阅表单或联系站点所有者,按 Mailchimp 的确认流程处理。此接口不查询或公开现有成员状态;第三方对归档、清理或永久删除成员的限制仍可能导致请求被拒绝。
无效参数返回 400;除 Member Exists 外的 Mailchimp 400 也返回 400,例如永久删除地址等受上游限制的请求。响应只含固定错误文案,但 HTTP 状态仍可能区分少数地址状态,因此统一提示不代表完全消除了名单探测的可能。其他 Mailchimp 服务错误返回 502;未配置或网络故障返回 503。浏览器 helper 会对非成功响应抛错,Fukasawa 表单及 Landing 的正文、页脚表单展示服务端安全错误文案并允许重试;请求完成前禁用重复提交。成功处理后展示同一中性提示。
服务端记录 Mailchimp HTTP 状态、错误标题和异常信息,并移除 API Key、邮箱和 Authorization 内容;不会记录请求头、完整响应或上游 detail。客户端只收到固定错误文案。接口不缓存响应,请求超时为 15 秒。
Developer MAINTAINER RUNBOOK.En (`docs/developer/MAINTAINER_RUNBOOK.en.md`)
Maintainer runbook (low overhead)
Canonical guide: MAINTAINER_RUNBOOK.zh-CN.md.
Summary: Route usage questions to Discussions; let CI / Labeler / Dependabot / Stale handle routine work; Founders focus on CODEOWNERS paths and releases; doc-only PRs can be merged by any Write maintainer when CI is green.
Developer MAINTAINER RUNBOOK.Zh CN (`docs/developer/MAINTAINER_RUNBOOK.zh-CN.md`)
维护者运行手册(低负担)
面向 Maintainer / Triager / Founder:用规则与自动化减少重复劳动,把 Founder 精力集中在高影响变更与发版。
1. 设计原则
| 原则 | 做法 |
|---|---|
| 公开优先 | 使用类问题 → Discussions;可跟踪缺陷 → Issue |
| 机器先行 | CI、Labeler、Dependabot、Stale 处理常规事务 |
| 域内自治 | docs/user-guide/**、单主题目录 PR 由文档/主题维护者合并 |
| 守门聚焦 | Founder 主要 Review CODEOWNERS 路径(lib/db、next.config.js、package.json 等) |
2. 每周约 15 分钟(Maintainer)
- 浏览 Discussions:
组织成员申请、未回复的「使用问答」。 - 扫一眼 Dependabot PR(可批量合并 patch/dev 依赖)。
- 合并队列:优先
documentation/good first issue且 CI 全绿 的 PR。 - 仅在发版窗口处理
package.json版本与 changelog。
Founder 可跳过第 3 步中纯文档 PR(若已授权文档维护者)。
3. Issue / Discussion 分流
| 用户诉求 | 动作 | 管理者耗时 |
|---|---|---|
| 「怎么部署/配置」 | 转 Discussions,关 Issue 或贴链接 | 1 条评论 |
| 重复 Issue | 关为 duplicate,链到已有 | 1 条评论 |
| 缺版本/环境信息 | 贴 bug 模板 要求补全,标 needs-info |
1 条评论 |
| 长期无回复 | 交给 Stale bot(45+14 天) | 0 |
| 安全漏洞 | 转 Private Advisory,勿公开讨论 | 按 SECURITY.md |
4. PR 合并权限(建议)
| PR 类型 | 标签/路径 | 谁合并 | CI 要求 |
|---|---|---|---|
| 纯文档 | documentation、docs/** |
任一 Write 维护者 | docs-site job |
| 单主题 | theme、themes/<name>/** |
主题维护者或 Write | lint + test |
| 依赖机器人 | dependencies |
维护者批量 | CI 绿 |
| 核心 / 配置 | core、config、CODEOWNERS |
Founder 或 2 人 Review | 全部 job |
禁止:未跑 CI 合并、Contributor 自合并自己的 PR(除非维护者明确授权)。
5. 自动化一览
| 工具 | 作用 |
|---|---|
| ci.yml | PR:lint、type-check、test、lockfile、文档构建 |
| labeler.yml | 按路径打 documentation / theme / core 等标签 |
| dependabot.yml | 每周依赖 PR(默认跳过 major) |
| stale.yml | 45 天无活动标 stale,14 天后关闭 Issue |
| deploy-docs-site.yml | main 文档自动发布 |
| CODEOWNERS | 仅高影响路径 @Founder |
6. Org Admin 一次性设置(合规 + 省力)
在 GOVERNANCE.zh-CN.md 基础上建议:
- Require status checks:
Lint & type-check、Unit tests、Lockfile consistency(文档 PR 可加VitePress build) - Require PR 进
main(Founder 亦走 PR,紧急 hotfix 例外并公告) - Allow auto-merge(可选):仅对 CI 绿且仅改
docs/**的 PR 启用 - Secret scanning + Dependabot alerts 开启
- 仓库标签与 labeler.yml 一致:
documentation、theme、core、config、dependencies、stale、needs-info、good first issue、help wanted - Issue 模板勿默认 assign 给 Founder(已移除
assignees)
7. 发版(低频)
- 确认
mainCI 绿。 - 更新
docs/user-guide/changelog/latest.md。 - 由 Org Admin 打 tag / Release,或运行
bump-version-on-main(仅维护者)。 - Discussion 公告 一条即可。
8. 相关文档
Developer MAINTENANCE PHILOSOPHY.En (`docs/developer/MAINTENANCE_PHILOSOPHY.en.md`)
Maintenance and change-control philosophy
This document is for core maintainers and frequent contributors. Read it together with Contributing and Contribution workflow. The goal is to welcome contributions while reducing large, hard-to-control changes that destabilize main and fork ecosystems.
Principles
- Small, reviewable, revertible steps: Prefer several focused PRs over one huge, hard-to-review batch.
- Intent before code: For behavior or data-contract changes, align scope in an Issue or Discussion before opening the PR.
- Protect core paths: Data layer, routing, global config, and build/export pipelines affect the whole project—PRs should explain motivation, risk, and how they were verified.
- No unrelated refactors mixed in: Do not bundle wide renames, mass formatting, or major dependency bumps with unrelated fixes or features; split PRs when needed.
- Dependencies and toolchain: Major framework or lockfile-policy upgrades need rationale, breaking-change notes, and regression checks (build, critical-path tests).
Suggested PR sizing
| Kind | Suggested approach |
|---|---|
| Bugfix | Minimal fix + tests or clear repro notes |
| Small feature / theme-local | Keep within theme or a single module boundary; avoid drive-by shared-layer edits |
| Cross-theme / shared API | Agree API and defaults in an Issue first; keep migrations documented |
| Breaking changes | Document version/config migration; split into phases if it helps reviewers |
High-impact areas (extra clarity expected)
Changes here tend to affect all sites or many themes—PR descriptions and verification notes should be stronger (whether two-person review is required is up to owners and maintainers):
lib/db/(includingSiteDataApi, Notion fetch and caching)pages/SSG/ISR, i18n, and build-lifecycle logicnext.config.jsand export/build scripts- Global config (
blog.config.js,lib/config.js, and similar defaults) - Security-sensitive areas: auth, secrets, third-party callbacks, CSP, etc.
Keeping the project from drifting
- Prefer opt-in or configurable behavior for niche site assumptions; avoid baking them into global defaults.
- Theme isolation: Keep theme-specific logic under
themes/<name>/; avoid encoding one theme’s UI or routing in shared layers. - Docs in lockstep: When user-visible behavior or config keys change, update docs (EN/ZH as applicable) in the same or a follow-up PR.
GitHub roles (for owners)
Repository owners (personal repo owner, or org owners) can invite trusted maintainers (for example @qianzhu18) as collaborators with Write, Maintain, or Admin, depending on how much repo administration you want to delegate.
If branch protection or third-party checks (e.g. deploy authorization) often block merges, either add trusted actors under bypass in Settings → Branches, or agree explicitly when owners merge on behalf of maintainers.
Exact GitHub UI labels change over time; governance (who may merge, when bypass is acceptable) should be agreed in writing among maintainers, not only implied by defaults.
Related docs
Revise this document as the project evolves; for major edits, leave a short note in an Issue or Discussion so future readers understand the rationale.
Developer MAINTENANCE PHILOSOPHY.Zh CN (`docs/developer/MAINTENANCE_PHILOSOPHY.zh-CN.md`)
维护与变更尺度(共识)
本文面向核心维护者与高频贡献者,与 贡献指南、提交与 PR 规范一起阅读。目标是在欢迎贡献的同时,尽量避免大量不可控、难回滚的改动,降低 main 与下游 fork 被拖离稳定形态的风险。
原则
- 小步、可审、可回滚:宁可多几个聚焦的 PR,也不要一个巨型「一锅端」难以评审的变更。
- 先对齐意图再写代码:涉及行为或数据契约的改动,尽量先在 Issue / Discussion 里对齐范围,再开 PR。
- 守住核心路径:数据层、路由、全局配置、构建与导出链路影响全站——PR 中应写清动机、风险与验证方式。
- 禁止夹带无关重构:不要把大范围重命名、整仓格式化、大版本依赖升级与无关 bugfix/功能混在同一 PR;必要时拆分。
- 依赖与工具链:框架大版本、锁文件策略类变更需说明理由、破坏性变更与回归验证(构建、关键路径测试等)。
建议的 PR 粒度
| 类型 | 建议 |
|---|---|
| Bug 修复 | 最小改动 + 测试或可复现说明 |
| 小功能 / 单主题 | 尽量限制在主题目录或单一模块边界,避免顺手改共享层 |
| 跨主题 / 公共 API | 先在 Issue 对齐接口与默认值,迁移路径写进文档 |
| 破坏性变更 | 写清版本与配置迁移;必要时拆阶段便于评审 |
高影响区域(期望说明更充分)
以下改动往往影响全站或多主题——PR 描述与验证说明应更完整(是否必须双人评审由仓库所有者与维护者共同约定):
lib/db/(含SiteDataApi、Notion 拉取与缓存)pages/下的 SSG/ISR、i18n、构建生命周期相关逻辑next.config.js与导出/构建脚本- 全局配置(
blog.config.js、lib/config.js及同类默认行为) - 安全相关:鉴权、密钥、第三方回调、CSP 等
避免项目「漂太远」
- 小众站点假设尽量做成可选项或配置项,避免写进影响所有人的全局默认。
- 主题隔离:主题专属逻辑放在
themes/<name>/,避免把某一主题的 UI 或路由假设写进共享层。 - 文档同步:用户可见行为或配置项变更时,在同一 PR 或紧随其后的 PR 中更新文档(中英视情况)。
GitHub 权限(供仓库所有者操作)
仓库所有者(个人仓库的拥有者,或组织的 Owner)可在 Settings → Collaborators(或组织下的 Teams / Repository access)邀请信任的维护者(例如 @qianzhu18),并按信任程度授予 Write / Maintain / Admin 等角色;是否需要能改分支保护、管理部分仓库设置,决定选 Maintain 还是 Admin。
若 分支保护 或 第三方检查(如部署需授权)经常导致无法合并,可在 Settings → Branches 中为受信维护者配置 bypass,或由所有者与维护者书面约定在何种情况下由谁代为合并。
GitHub 界面文案会随产品迭代变化;谁可以合并、何时允许绕过检查等治理规则,建议在维护者之间留下文字共识(Issue、Discussion 或本仓库文档的修订说明),而不要仅依赖默认设置。
相关文档
本文档随项目演进可修订;重大修订建议在 Issue 或 Discussion 中留一句背景,便于后来者理解。
Developer MEMBERSHIP COMMENTS ROADMAP (`docs/developer/MEMBERSHIP_COMMENTS_ROADMAP.md`)
会员、权限与评论可选集成路线图
本文是 NotionNext 下一阶段“登录、会员、权限、评论”方向的克制方案草案。它不是承诺清单,也不是要把 NotionNext 做成完整会员 SaaS 平台;目标是把已有 Clerk 演示、Notion Integration 能力和评论插件体系收口成可维护、可替换、可自托管的可选方案。
丰富功能可以带来更便捷的集成体验,但也会违背工具应当专一、专业、简洁的原则。NotionNext 的默认路径仍然应该是轻量博客和内容站:能不用会员系统就不用,能用现有评论插件就不重写,能做成可选插件就不进入核心。
核心判断
NotionNext 的优势是用 Notion 维护内容,用独立站完成发布、检索、展示和运营。会员能力也应该沿用这个边界:
- Clerk 等认证服务负责登录身份。
- Notion Integration 负责读取站长在 Notion 中维护的低频权限数据。
- 评论优先复用现有评论插件。
- NotionNext 核心只保留最小接口,不强制普通站点启用登录、会员或自有评论。
不建议一开始内置支付、订单、积分、复杂 RBAC、CRM 和运营看板。那些能力差异很大,且容易把普通博客用户的部署路径变复杂。短期更适合提供字段约定、适配器接口、可选插件、最小示例和清晰文档。
目标用户
优先服务三类站点:
- 内容站:希望登录后查看特定文章、资料或页面。
- 课程/知识库站:希望用 Notion 维护会员名单和内容分层。
- 社区官网:希望展示成员资料,并逐步接入登录评论、资料页和轻量互动。
暂不优先服务:
- 高并发社区。
- 交易型会员平台。
- 多租户 SaaS。
- 需要复杂审批、积分、优惠券、分销和财务对账的商业系统。
设计边界
这条路线必须满足几个约束:
- 不影响最简单的博客部署。
- 不把 Clerk、Notion 评论或任何会员服务设为必选依赖。
- 能作为插件、适配器或示例存在的能力,不放进核心路径。
- 默认复用专业工具,只有站点深度绑定需求明确时才新增 NotionNext 侧实现。
- 文档要先讲“什么时候不需要它”,再讲“什么时候可以启用它”。
推荐架构
身份层
使用 Clerk 作为默认演示实现,但接口不绑定 Clerk,且不要求普通站点配置:
- 读取当前登录用户。
- 暴露
userId、email、name、avatar等标准字段。 - 未配置登录服务时,保持现有公开站点行为。
后续可以让 Auth.js、Supabase Auth 或自建登录实现同一接口。
权限层
Notion 作为低频权限源,推荐新增或复用 Member 数据库字段。字段约定应服务于可选插件和示例站,不应让普通博客模板变复杂:
| 字段 | 用途 |
|---|---|
email |
与登录账号匹配 |
clerkUserId |
与 Clerk 用户 ID 精确匹配 |
status |
Active / Inactive / Expired |
role |
member / editor / admin 等轻量角色 |
plan |
free / pro / vip 等站点自定义等级 |
expiresAt |
到期时间 |
allowedTags |
可访问的内容标签 |
文章或页面侧推荐增加轻量字段:
| 字段 | 用途 |
|---|---|
access |
Public / Login / Member / Role |
requiredRole |
需要的角色 |
requiredPlan |
需要的会员等级 |
requiredTag |
与会员 allowedTags 匹配 |
评论层
默认继续使用现有评论插件:
- Giscus、Utterances 适合 GitHub 生态和开源项目。
- Cusdis 适合轻量审核。
- Twikoo、Waline、Artalk 适合自托管、通知和管理后台。
只有在站点需要“评论必须绑定当前登录用户”和“评论由站点统一权限控制”时,才新增 Notion 评论适配。该适配应作为可选插件存在,并保持很小:
- 轻量公开评论场景已经由
NotionComments覆盖:独立 Notion 评论数据库、昵称、邮箱识别、嵌套回复、手动审核状态和基础频率限制。 - 登录后提交评论。
- 写入 Notion
Comments数据库。 - 默认审核后展示。
- 只提供基础分页和删除/隐藏状态。
高流量评论、实时互动、复杂反垃圾和通知系统不放进核心,继续交给专业评论系统或自建数据库。
分阶段计划
阶段 1:收口现有登录演示
目标:让已有 Clerk 演示从“能登录”变成“可被可选插件复用”,不改变默认博客路径。
任务:
- 梳理现有 Clerk Provider、middleware、登录页和 dashboard 入口。
- 新增统一的当前用户读取函数。
- dashboard 或演示页显示当前登录用户和 Notion Member 状态。
- 未配置 Clerk 时保持现有站点不受影响。
验收:
- 配置 Clerk 后可以登录并进入 dashboard。
- dashboard 能显示来自 Notion 的会员状态。
- 不配置 Clerk 时不会影响普通博客部署。
阶段 2:会员权限读取
目标:让 Notion Integration 可以作为轻量权限后台,但只在启用会员插件时参与。
任务:
- 扩展
Member官方 API 读取字段。 - 支持通过
clerkUserId或email匹配当前用户。 - 提供
getCurrentMember之类的服务端 helper。 - 增加最小测试,覆盖 active、expired、missing 三种状态。
验收:
- 站长可以在 Notion 修改会员状态。
- 服务端能稳定判断当前用户是否是有效会员。
- 不把 Notion 当实时交易数据库。
阶段 3:内容访问控制
目标:在可选模式下支持文章或页面按字段控制可见性。
任务:
- 定义
access、requiredRole、requiredPlan、requiredTag字段约定。 - 在文章页服务端判断访问权限。
- 未授权时显示登录入口或会员提示。
- 保持公开文章、密码文章、隐藏评论等现有行为不破坏。
验收:
Public内容无需登录。Login内容登录后可见。Member内容只对有效会员可见。- 权限不足时不泄露正文内容。
阶段 4:登录评论适配
目标:为深度绑定站点账号的场景提供最小评论插件,而不是替代现有评论生态。
任务:
- 定义 Notion
Comments数据库字段。 - 新增评论提交 API,要求登录。
- 写入评论时保存
postId、memberId、authorName、content、status。 - 前端新增可选
NotionComment插件/组件。 - 默认只展示
Approved评论。
验收:
- 登录用户可以提交评论。
- 站长可以在 Notion 审核评论。
- 现有第三方评论插件仍然可用。
阶段 5:文档、模板和预告
目标:让用户知道该用哪条路径,尤其是知道普通博客无需接入会员系统。
任务:
- 更新评论插件文档,说明评论、登录、会员的边界。
- 提供 Member 和 Comments 数据库模板说明。
- 写一篇从 Clerk 到 Notion Member 的配置教程。
- 在更新日志或大版本预告中说明这是可选能力,不是默认能力。
验收:
- 普通博客用户能继续只配置评论插件。
- 会员站用户能按教程逐步接入。
- 贡献者能按阶段拆 PR。
不做什么
短期不做:
- 内置支付。
- 订单和发票。
- 积分和分销。
- 多租户组织管理。
- 复杂 RBAC 权限矩阵。
- 评论实时聊天。
- 把所有评论插件替换成 Notion 评论。
- 让会员体系进入默认博客模板。
- 为了演示集成体验增加核心依赖。
这些能力可以通过外部系统、站点定制或后续适配器接入,但不应成为 NotionNext 核心路径的前提。核心要继续保持专一:读取 Notion 内容,渲染独立站点,并把扩展入口留给需要的人。
推荐的第一个实现切片
先做一个小闭环:
- 登录后读取 Clerk 当前用户。
- 用
email或clerkUserId匹配 NotionMember。 - dashboard 显示会员状态。
- 一篇测试文章设置为
access = Member。 - 未授权用户看到登录或会员提示。
这个切片足够验证插件化架构,但不会引入支付、订单、积分或完整评论系统。验证完成后,也应优先作为可选插件或示例文档交付。
Developer NOTIONNEXT CONTENT MCP.En (`docs/developer/NOTIONNEXT_CONTENT_MCP.en.md`)
NotionNext Content MCP: manage your Notion content with AI coding assistants
What is this
NotionNext Content MCP is a bundled Model Context Protocol (MCP) server that lets AI coding assistants such as Claude Code, Codex CLI, and Cursor read and write the Notion databases behind your site over a standard protocol.
Instead of editing articles word by word in the Notion web app, hand your prompts, drafts, and materials to an AI assistant. It generates the article following the NotionNext data contract, writes it into your Notion as a draft, and you review and publish from Notion with one click.
Highlights:
- Zero dependencies: implemented with the Node.js standard library only; if
noderuns, this runs - Review-first: every AI write lands as an
Invisibledraft; publishing always requires human confirmation in Notion - Write contract: structured data goes to first-class properties, body content to page blocks, covers to the native Page Cover. Writing the legacy
extfield is rejected at the schema and runtime level, so the Notion editing experience and the NotionNext render pipeline stay intact - Scoped authorization: the AI can only touch data sources registered via environment variables, and the Notion token is never exposed to the model or logs
Quick start
1. Environment variables
The server reads .env.local / .env / .env.mcp.local from the project root (or set NOTIONNEXT_MCP_ENV_FILE). Minimum:
NOTION_API_TOKEN= # Notion integration token (create at https://www.notion.so/my-integrations and share your databases with it)
NOTION_PAGE_ID= # the page / database id your NotionNext site already usesOptional per-type data source ids (unregistered databases are untouchable by default):
NOTION_POSTS_DATA_SOURCE_ID=
NOTION_PAGES_DATA_SOURCE_ID=
NOTION_RECORDS_DATA_SOURCE_ID=
NOTION_EVENTS_DATA_SOURCE_ID=
NOTION_MEMBERS_DATA_SOURCE_ID=
NOTION_CONTENT_DATA_SOURCE_ID= # generic fallbackOptional property-name overrides (defaults match the standard NotionNext template):
NOTION_CONTENT_PROP_TITLE=title
NOTION_CONTENT_PROP_TYPE=type
NOTION_CONTENT_PROP_STATUS=status
NOTION_CONTENT_PROP_SLUG=slug
NOTION_CONTENT_PROP_SUMMARY=summary
NOTION_CONTENT_PROP_CATEGORY=category
NOTION_CONTENT_PROP_TAGS=tags
NOTION_CONTENT_PROP_DATE=date2. Verify
node tools/notionnext-content-mcp/smoke-test.js
# -> NotionNext content MCP smoke test passed3. Connect your assistant
Claude Code (from the project root):
claude mcp add notionnext-content -- node tools/notionnext-content-mcp/server.jsCodex CLI (~/.codex/config.toml):
[mcp_servers.notionnext-content]
command = "node"
args = ["/absolute/path/to/NotionNext/tools/notionnext-content-mcp/server.js"]Cursor (.cursor/mcp.json in the project):
{
"mcpServers": {
"notionnext-content": {
"command": "node",
"args": ["tools/notionnext-content-mcp/server.js"]
}
}
}4. Use it
Once connected, just ask:
- "List my recent Notion drafts"
- "Turn these notes into a blog post and save it as a Notion draft — don't publish it"
- "Update the summary and tags of this article"
- "Append a section to the end of this draft"
Tools
| Tool | Purpose |
|---|---|
notionnext_status |
Report Notion token / data source configuration status (redacted) |
build_notion_draft |
Convert content into a Notion page payload preview (no write) |
create_notion_draft |
Create a draft page (defaults to Invisible) |
inspect_notion_data_source |
Read the schema of an allowed data source |
query_notion_pages |
Query pages in allowed data sources (type / status / keyword filters) |
get_notion_page |
Read a page's properties and body blocks |
update_notion_page |
Update properties, cover, icon |
append_notion_blocks |
Convert Markdown to Notion blocks and append to the body |
archive_notion_page |
Archive / restore a page |
refresh_site_cache |
(Optional) call the site's ops-protected revalidate endpoint so changes appear immediately |
The NotionNext native write contract (hard rules)
This MCP never treats ext as a compatibility layer. Tool schemas and runtime validation reject any ext write before any network request is made:
| Content | Correct location |
|---|---|
| Title, type, status, slug, summary, category, tags, date | First-class Notion properties |
| Body, sections, lists | Page body blocks |
| Cover, hero image | Native Page Cover (keeps Change / Reposition editing in Notion) |
This guarantees AI-written content remains fully editable in Notion and that what the site renders matches what you see in the database.
Recommended workflow
- Generate content with your AI assistant from your own materials
query_notion_pagesfor duplicates →build_notion_draftto preview the payloadcreate_notion_draftto write anInvisibledraft- Review in Notion: verify facts, privacy, images
- Flip
statustoPublished refresh_site_cache(if configured) so the change appears immediately
Security model
- Only data sources registered via environment variables are reachable; for a trusted local debugging session you may set
NOTIONNEXT_MCP_ALLOW_UNLISTED_DATA_SOURCE=true - Page-by-id operations fail closed: a page that does not belong to any data source (e.g. a workspace-level page) is rejected outright, because it cannot be proven to be allow-listed
- The Notion token stays inside the server process; every tool output is redacted
- Drafts default to
Invisible; the AI cannot publish directly extwrites are always rejected, preventing uneditable JSON blobs in your databaserefresh_site_cacheresolves its target URL from environment variables only (never from tool arguments), and derives the ops cookie token from the password with salted scrypt; the raw password never leaves the local process, and the receiving revalidate endpoint must derive the same token
References
Developer NOTIONNEXT CONTENT MCP (`docs/developer/NOTIONNEXT_CONTENT_MCP.md`)
NotionNext Content MCP:用 AI 编码助手直接管理你的 Notion 内容
这是什么
NotionNext Content MCP 是一个内置的 Model Context Protocol(MCP)服务器,让 Claude Code、Codex CLI、Cursor 等 AI 编码助手通过标准协议直接读写你站点背后的 Notion 数据库。
你不再需要在 Notion 网页里逐字编辑文章:把提示词、草稿、素材交给 AI 助手,它会按照 NotionNext 的数据契约生成文章并写入你的 Notion 草稿箱,你在 Notion 里审核后一键发布,站点自动呈现。
特点:
- 零依赖:纯 Node.js 标准库实现,
node可用即可运行,无需安装任何包 - 审核优先:所有 AI 写入默认
Invisible草稿,公开发布必须由人在 Notion 中确认 - 写入契约:结构化信息写独立属性、正文写页面 blocks、封面写原生 Page Cover,全面禁止写入
ext兼容字段,保证你在 Notion 中的编辑体验与 NotionNext 渲染链路完全一致 - 授权边界:AI 只能操作环境变量中登记过的 data source,Notion token 永远不会输出给模型或日志
快速开始
1. 准备环境变量
MCP 服务器会自动读取项目根目录的 .env.local / .env / .env.mcp.local(也可用 NOTIONNEXT_MCP_ENV_FILE 指定任意路径)。最少需要:
NOTION_API_TOKEN= # Notion Integration Token(https://www.notion.so/my-integrations 创建,Internal Integration 并授权给你的数据库)
NOTION_PAGE_ID= # NotionNext 站点已使用的页面 / 数据库 ID可选:为不同内容类型登记专属 data source(未登记时 AI 无法触碰对应库,这是默认安全边界):
NOTION_POSTS_DATA_SOURCE_ID=
NOTION_PAGES_DATA_SOURCE_ID=
NOTION_RECORDS_DATA_SOURCE_ID=
NOTION_EVENTS_DATA_SOURCE_ID=
NOTION_MEMBERS_DATA_SOURCE_ID=
NOTION_CONTENT_DATA_SOURCE_ID= # 通用兜底可选:属性名映射(默认与 NotionNext 标准模板一致,一般无需配置):
NOTION_CONTENT_PROP_TITLE=title
NOTION_CONTENT_PROP_TYPE=type
NOTION_CONTENT_PROP_STATUS=status
NOTION_CONTENT_PROP_SLUG=slug
NOTION_CONTENT_PROP_SUMMARY=summary
NOTION_CONTENT_PROP_CATEGORY=category
NOTION_CONTENT_PROP_TAGS=tags
NOTION_CONTENT_PROP_DATE=date2. 验证安装
node tools/notionnext-content-mcp/smoke-test.js
# 输出 NotionNext content MCP smoke test passed 即协议层就绪3. 连接你的 AI 助手
Claude Code(在项目根目录执行):
claude mcp add notionnext-content -- node tools/notionnext-content-mcp/server.jsCodex CLI(编辑 ~/.codex/config.toml):
[mcp_servers.notionnext-content]
command = "node"
args = ["/绝对路径/NotionNext/tools/notionnext-content-mcp/server.js"]Cursor(编辑项目下 .cursor/mcp.json):
{
"mcpServers": {
"notionnext-content": {
"command": "node",
"args": ["tools/notionnext-content-mcp/server.js"]
}
}
}4. 开始使用
连上之后,你可以直接对 AI 助手说:
- 「查一下我的 Notion 里最近有哪些草稿」
- 「根据这段素材写一篇博客,生成 Notion 草稿,先不要发布」
- 「把这篇文章的摘要和标签更新一下」
- 「在这篇草稿末尾追加一段」
内置工具
| 工具 | 作用 |
|---|---|
notionnext_status |
检查 Notion token、data source 配置状态(脱敏输出,不暴露 token) |
build_notion_draft |
把内容转换成 Notion 页面 payload 预览,不写入 |
create_notion_draft |
创建 Invisible 草稿页面(默认审核优先) |
inspect_notion_data_source |
读取已授权 data source 的 schema(属性名、类型) |
query_notion_pages |
查询已授权 data source 中的页面(按类型 / 状态 / 关键词过滤) |
get_notion_page |
读取单个页面属性与正文 blocks |
update_notion_page |
更新属性、cover、icon(改状态、摘要、slug、标签等) |
append_notion_blocks |
把 Markdown 转成 Notion blocks 追加到正文 |
archive_notion_page |
归档 / 恢复页面 |
refresh_site_cache |
(可选)调用站点 ops 鉴权的缓存刷新接口,写入后让前台立即可见 |
NotionNext 原生写入契约(硬规则)
这个 MCP 不把 ext 当兼容层。工具 schema 与运行时校验会在任何网络请求前拒绝任意层级的 ext 写入:
| 内容 | 正确位置 |
|---|---|
| 标题、类型、状态、slug、摘要、分类、标签、日期 | 对应的 Notion 独立属性 |
| 正文、章节、列表 | 页面正文 blocks |
| 封面、主视觉 | 原生 Page Cover(保留 Notion 中 Change / Reposition 编辑体验) |
这样保证:AI 写入的内容在 Notion 中完全可编辑,前台读取的字段与后台一一对应。
推荐工作流
- AI 生成内容(基于你的素材、提示词)
query_notion_pages查重 →build_notion_draft预览 payloadcreate_notion_draft写入Invisible草稿- 你在 Notion 中审核:核对事实、隐私授权、补图
- 把
status改为Published refresh_site_cache(如已配置),前台立即可见
安全模型
- 默认只能读写环境变量登记过的 data source;临时调试可设
NOTIONNEXT_MCP_ALLOW_UNLISTED_DATA_SOURCE=true(仅限本地可信环境) - 按 pageId 操作时执行 fail-closed 校验:页面不属于任何 data source(如 workspace 顶层页面)时直接拒绝,因为无法证明它在白名单内
- Notion token 只在服务端进程内使用,任何工具输出均脱敏
- 默认草稿状态
Invisible,AI 无法直接公开发布内容 - 所有写入禁止
ext,防止不可编辑的 JSON 富文本进入你的数据库 refresh_site_cache的目标地址只能来自环境变量(不接受工具参数覆盖),ops cookie 令牌由密码经 scrypt 加盐派生,密码本体不离开本地进程;接收端 revalidate 接口需按相同方式派生校验
参考
Developer NOTION OAUTH.Zh CN (`docs/developer/NOTION_OAUTH.zh-CN.md`)
Notion OAuth 授权入口
配置 OAUTH_CLIENT_ID、OAUTH_CLIENT_SECRET、OAUTH_REDIRECT_URI,从 /api/auth/notion 开始授权。回调地址可使用 /api/auth/callback/notion,也兼容原 /auth 入口,需与 Notion 集成配置完全一致。
生产回调地址使用 HTTPS;本机开发可使用 http://localhost 或 http://127.0.0.1。授权开始时创建有效期 10 分钟的随机 HttpOnly state cookie,回调必须与之匹配,并清除此 cookie。
成功后跳转到固定的 /auth/result?status=success。结果页不展示原始 token、个人信息或上游响应,也不把它们写入 URL、页面 props 或日志。授权流程只确认授权:仓库没有消费此 OAuth token 的后续功能,因此不会持久化 token。它不替代 Clerk 登录或管理员权限检查。
未配置或回调地址格式不合法时返回 503;过期、缺失或不匹配的 state 返回 400;token 交换失败返回 502。HTTP 回调仅允许主机名为 localhost 或 127.0.0.1,其他主机(包括局域网 IP)必须使用 HTTPS。
升级说明:授权入口的破坏性变更
升级后必须从本站 /api/auth/notion 发起授权,让浏览器先获得 state cookie。旧的直接携带 code 访问回调、直接使用 Notion 集成后台生成的 Authorization URL,或从 Notion 侧发起安装,都缺少本站签发的 state cookie,会返回 400,不能沿用。
请把站内和对外分享的授权链接改为本站 /api/auth/notion,并让升级前已打开授权页面的用户重新从该入口开始。Notion 集成后台的回调地址仍需与 OAUTH_REDIRECT_URI 完全一致;不要通过移除 state 校验兼容旧链接。
Developer POST ACCESS.Zh CN (`docs/developer/POST_ACCESS.zh-CN.md`)
文章密码与服务端访问
文章密码由 Next.js 服务端验证。公开页面数据只包含 password: "protected" 标记、标题和摘要;正文和目录在验证成功后由 POST /api/post/unlock 返回,并设置 no-store。
- 支持 SHA-256 及历史
md5(slug + password)摘要。 - 内置主题的密码框等待异步验证结果,包括 OPC 和 Landing。自定义主题应使用
await validPassword(password),返回值仍为布尔值。 - 验证成功会返回正文、上一篇、下一篇及推荐文章。服务暂不可用和密码错误有不同反馈。
- 旧密码 URL 和 localStorage 只尝试迁移一次,随后清除;新密码不写入 localStorage。刷新页面后需重新解锁。
- 密码文章解锁需要服务端。
EXPORT=true仍会成功生成密码文章的锁页,保留标题、摘要和保护标记,页面明确提示当前静态站点不能解锁,不渲染密码表单。导出时不预取这些文章的正文,即使调用者提供正确密码也不会导出正文。公开文章继续正常导出。 - UUID 入口必须属于本站目录或已发布目录文章的子页面,并继承目录祖先的密码要求。公开发布
Published与隐藏发布Invisible都允许其子页面通过 UUID 访问;隐藏发布仍不出现在文章列表中,草稿Draft不放行。[email protected]的getPage只补齐缺失的内容块,不保证返回完整祖先链;服务端因此沿parent_id补拉缺失的 block/collection 记录,最多检查 64 层。链缺失、循环、跨工作区、祖先未发布或无法找到目录祖先时返回 404。 - 仅同工作区但未关联已发布目录的独立 UUID 页面不会放行。Notion 客户端可能携带服务端 token,能读到页面不等于页面公开;要通过本站访问此类页面,请将其加入本站目录并发布。补拉的祖先记录只用于校验,不加入对浏览器返回的正文数据。
- 公共文章预览、搜索和 RSS 不应包含密码页面的嵌套正文。Algolia 不上传密码文章;已生成的旧索引和静态文件应在更新后重新生成。
接口按 IP 提供每分钟 20 次的单实例内存限流,最多保留 10000 个地址窗口,满额时淘汰最旧窗口,不会因此拒绝所有新访客。该限流只是本地兜底:Serverless 冷启动、多实例和地址轮换会削弱效果;需要统一约束时必须在可信网关配置共享限流。
自托管反向代理只有在入口不可绕过、且代理会覆盖客户端传入的转发头时才设置 TRUST_PROXY=true。代理必须覆盖 X-Forwarded-For、X-Forwarded-Host(浏览器访问的主机名与可选端口)和 X-Forwarded-Proto(http 或 https),不要追加逗号分隔的值。VERCEL=1 平台环境也会使用可信转发头。其他部署忽略转发头,使用实际 Host 和 TLS 状态校验完整 Origin;错误协议、端口、来源及歧义头会被拒绝。
公开文章只在构建或静态导出时允许降级:Notion 正文获取或适配失败时使用安全摘要;目录、AI 摘要等后处理失败时,保留处理前已完成隐私过滤的正文快照,丢弃未完成的派生内容。运行时 ISR(包括按需刷新)遇到这些异常会抛错,保留上一次成功页面,避免用摘要页覆盖完整正文;首次动态生成没有旧页面可用时会返回错误,稍后可重试。构建阶段由 Next.js 的 revalidateReason: 'build' 标识判断,不以可能残留在部署环境中的 BUILD_MODE 判断。
已通过密码验证的文章遇到同类失败始终抛出错误,解锁接口返回 503。全站目录加载失败的兜底数据会保留内部失败标记(不传给浏览器),运行时文章解析不会把兜底目录误认成文章已删除。UUID 页面若确认祖先链不符合访问要求则返回 404;运行时重试耗尽返回空值、工作区暂不可确认或获取过程抛错时会保留错误,不以临时 404 覆盖已有页面,也不会降级放行。错误提示使用当前语言字典。
此功能限制本站的正文访问;Notion 原页面自身的公开分享权限仍由 Notion 管理。
Developer PROJECT STRUCTURE.En (`docs/developer/PROJECT_STRUCTURE.en.md`)
Project Structure
Top-level directories (common)
pages/: Next.js route entry (getStaticProps/getStaticPaths)themes/: Theme implementations (UI + theme config)components/: Cross-theme reusable componentslib/: Core logic (data, cache, utilities, config read)conf/: Split config files aggregated byblog.config.js__tests__/: Unit testsscripts/: Engineering scripts.github/: Issue/PR templates and collaboration metadata
Key files
blog.config.js: aggregated config entrylib/config.js:siteConfig()read logic (with priority)lib/db/SiteDataApi.js: core site-data assemblyCONTRIBUTING.md: external contribution entrydocs/README.md: docs navigation (zh)docs/README.en.md: docs navigation (en)
Change suggestions
- Global rules: prefer
lib/db/orlib/utils/ - Theme visuals: prefer
themes// - New config keys: add in
conf/*.config.js, aggregate fromblog.config.js - Avoid copying same business logic across many
pages/*
Developer PROJECT STRUCTURE (`docs/developer/PROJECT_STRUCTURE.md`)
目录与模块说明
顶层目录(常用)
pages/:Next.js 路由入口(SSG/ISR 的getStaticProps/getStaticPaths)themes/:各主题实现(UI 与主题配置)components/:跨主题复用组件lib/:核心逻辑(数据、缓存、工具、配置读取)conf/:拆分后的配置文件(由blog.config.js聚合)__tests__/:单元测试scripts/:工程脚本(质量检查、初始化、钩子安装等).github/:Issue/PR 模板与协作元数据
关键文件
blog.config.js:聚合配置入口(通过...require('./conf/*.config'))lib/config.js:siteConfig()读取逻辑(含优先级)lib/db/SiteDataApi.js:全站数据组装核心CONTRIBUTING.md:对外贡献入口docs/README.md:文档导航入口
改动建议
- 全局规则改动:优先
lib/db/或lib/utils/ - 主题视觉改动:优先
themes// - 配置项新增:优先
conf/*.config.js,再由blog.config.js聚合 - 避免在多个
pages/*重复粘贴同一业务逻辑
Developer README.En (`docs/developer/README.en.md`)
NotionNext Docs Navigation
This docs directory helps contributors and new developers understand the project quickly and collaborate safely.
Repository and organization
The main repository is maintained by the GitHub organization notionnext-org (canonical: https://github.com/notionnext-org/NotionNext). You are welcome to request org membership when that fits your role. If you cloned before the transfer, run:
git remote set-url origin https://github.com/notionnext-org/NotionNext.gitSee Contributing (and the Chinese contributing guide) for details.
Start Here (5 minutes)
| Topic | English | 中文 |
|---|---|---|
| Getting Started | GETTING_STARTED.en.md | GETTING_STARTED.md |
| Architecture | ARCHITECTURE.en.md | ARCHITECTURE.md |
| Project Structure | PROJECT_STRUCTURE.en.md | PROJECT_STRUCTURE.md |
| Configuration | CONFIGURATION.en.md | CONFIGURATION.md |
| Contribution Workflow | CONTRIBUTION_WORKFLOW.en.md | CONTRIBUTION_WORKFLOW.md |
| Maintenance & change control | MAINTENANCE_PHILOSOPHY.en.md | MAINTENANCE_PHILOSOPHY.zh-CN.md |
| Theme Migration Guide | THEME_MIGRATION_GUIDE.md | THEME_MIGRATION_GUIDE.zh-CN.md |
Purpose
- Reduce onboarding cost for contributors.
- Keep collaboration rules consistent.
- Prevent personal/local config leaks.
- Keep PR reviews focused on real logic changes.
Theme Docs
Relationship with Root Docs
- Root
README.md: project overview and showcase - Root
CONTRIBUTING.md: public contribution entry - Root
DEVELOPMENT.md: commands and tooling docs/: architecture, configuration, and workflow details
Developer THEME COLOR TOKEN ROADMAP.Zh CN (`docs/developer/THEME_COLOR_TOKEN_ROADMAP.zh-CN.md`)
主题色变量与调色板开发计划
本文记录 #3393 的实施计划:将主题色号命名规范化、调色板化,并让主题颜色配置可以通过 Notion Config、环境变量或主题配置文件覆盖。
目标
- 所有内置主题逐步从 Tailwind 固定色名迁移到语义色变量,并最终具备可独立调整的浅色、深色两套调色板。
- 每个主题维护自己的颜色配置键,例如
HEO_COLOR_PRIMARY、HEXO_COLOR_PRIMARY;已有成熟模型可保留语义明确的旧键,例如FUWARI_THEME_COLOR_HUE。 - 每个主题在
style.js中把配置键映射为主题作用域 CSS 变量。 - 主题切换工具展示当前主题调色板,帮助用户复制配置键和值。
- 用户文档列出每个主题支持的颜色配置项。
- 发布新版本时在 changelog 中说明迁移范围和兼容策略。
非目标
- 不一次性重写所有主题。
- 不用
#theme-x .bg-indigo-600这类覆盖方式作为长期方案。 - 不要求所有主题暴露完全相同数量的扩展颜色,但必须满足下文的基础色契约。
- 不立即强制引入全局
THEME_COLOR_*,先以主题独立配置为主。
命名规范
主题颜色配置使用主题前缀:
HEO_COLOR_PRIMARY
HEO_COLOR_PRIMARY_HOVER
HEO_COLOR_PRIMARY_TEXT
HEO_COLOR_ACCENT
HEO_COLOR_BG
HEO_COLOR_CARD
HEO_COLOR_BORDER
HEO_COLOR_TEXT
HEO_COLOR_TEXT_SECONDARYCSS 变量使用小写主题前缀,且只挂载在当前主题根节点:
#theme-heo {
--heo-color-primary: ...;
--heo-color-primary-hover: ...;
--heo-color-bg: ...;
}组件使用语义变量:
className="bg-[var(--heo-color-primary)] text-[var(--heo-color-primary-text)]"最小调色板
| 语义 | 用途 |
|---|---|
PRIMARY |
主按钮、选中态、重点链接 |
PRIMARY_HOVER |
主色 hover |
PRIMARY_TEXT |
主色背景上的文字 |
ACCENT |
辅助强调、徽标、装饰 |
BG |
页面背景 |
CARD |
卡片、面板、浮层 |
BORDER |
边框、分割线 |
TEXT |
标题和正文 |
TEXT_SECONDARY |
摘要、元信息、弱化文字 |
所有内置主题的浅色和深色模式都至少实现 PRIMARY、BG、CARD、TEXT、BORDER;主题实际使用了次级文字、强调色或 hover 色时,也必须分别暴露对应 token。深色配置键统一追加 _DARK,例如 HEO_COLOR_BG_DARK。
manifest 中出现配置项不等于完成支持。对应 CSS 变量必须被主题组件真实消费,控制台修改后立即生效;浅色和深色值必须相互独立,切换模式不能串用另一组色号。默认值必须与迁移前主题视觉一致。
调色板元数据
调色板工具需要读取每个主题支持的颜色项。推荐最小结构:
{
key: 'HEO_COLOR_PRIMARY',
cssVar: '--heo-color-primary',
label: '主色',
defaultValue: '#4f46e5'
}实现位置待第一批代码落地时确认,优先选择改动面最小的位置:
conf/themeSwitch.manifest.js:适合与主题切换面板一起读取。- 独立 registry:适合后续色板字段较多时拆分。
阶段计划
Phase 1:文档和规范
- 在长期计划中记录 Tailwind 快速开发到语义色变量的演进。
- 在主题迁移指南中加入颜色 token 规则。
- 在
#3393回复完整实施计划。 - 在用户向主题文档中加入“主题调色”总说明。
Phase 2:代表主题验证
-
heo增加HEO_COLOR_*默认配置。 -
heo/style.js映射主题作用域 CSS 变量。 - 替换
heo中主色、强调色、背景、卡片、边框、文字的明显硬编码用法。 - 保留视觉默认值,避免现有站点升级后明显变样。
Phase 3:兼容已有主题色
-
hexo保留HEXO_THEME_COLOR兼容。 -
hexo增加HEXO_COLOR_PRIMARY等新键。 -
fuwari对齐单主色主题调色板模型。
Phase 4:主题切换工具调色板
- 定义调色板元数据读取方式。
- 在主题切换面板加入调色板入口。
- 展示配置键、语义名称、色块、当前值。
- 支持复制配置键和值。
- 支持本地实时预览,不强制立即写入远端配置。
Phase 5:扩展到全部主题
- 已完成扩展样本:
heo、hexo、fuwari、next、simple、matery、medium、nobelium、plog、commerce、gitbook、typography、claude、fukasawa、nav、magzine、game、movie、photo、example、thoughtlite、starter、proxio、landing、endspace。 - 按主题逐个迁移色号。
- 所有内置主题补齐浅色、深色两套基础色契约。
- 每个主题保留自己的默认视觉风格。
- 每个主题文档列出支持的颜色配置。
- 主题总览标记调色板支持状态。
Phase 6:验证与发布
- 运行最小必要测试和静态检查。
- 对代表主题做桌面与移动端视觉 smoke check。
- 更新 changelog。
- 发布新版本。
迁移顺序建议
heo:多色板代表主题。hexo:已有HEXO_THEME_COLOR,优先做兼容迁移。fuwari:单主色代表主题。- 后续新增主题必须在首版就声明
*_COLOR_*与 manifest 调色板。 - 其他主题按使用频率和改动风险推进。
验收标准
- 新增主题不再引入无语义的固定业务色名。
- 已迁移主题的主要品牌色可以通过 Notion Config 覆盖。
- 调色板工具能展示当前主题支持的色号。
- 所有内置主题的调色板都至少展示两套
PRIMARY、BG、CARD、TEXT、BORDER,且每项实时生效。 - 浅色和深色配置互不串色,主题默认配置与迁移前视觉一致。
- 用户能从文档知道配置键、默认值和影响区域。
- 旧配置不直接失效。
Developer THEME CONSOLE DESIGN.Zh CN (`docs/developer/THEME_CONSOLE_DESIGN.zh-CN.md`)
主题控制台设计与接入约定
主题控制台是在原“主题切换 / 调色板”能力上的升级。它只在当前浏览器页面实时预览,不直接写入远端 Notion 数据库;用户确认效果后,再复制配置片段写入 notion_config 或主题配置文件。
背景
早期主题大量使用 Tailwind CSS 工具类,是为了快速开发、快速验证布局和交互。随着框架和内置主题逐渐成熟,主题需要更丰富、更稳定的定制能力。后续颜色迁移应从 bg-indigo-600、text-blue-500 这类固定色名过渡到主题自己的语义色变量,例如 HEO_COLOR_PRIMARY、HEO_COLOR_TEXT_DARK。
这样做的目标不是替换 Tailwind,而是避免颜色语义混乱:代码中出现“indigo”时不再需要猜它到底是主色、强调色、hover 色,还是深色模式下的文字色。
用户体验目标
- 浮动工具只保留四个明确入口:拖拽手柄、主题切换、主题控制台、深浅模式。
- 主题控制台标题必须展示当前主题名,例如
主题控制台 · Heo。 - 控制台默认折叠“信息配置”和“配色”两个区块,用户按需展开。
- 配色只分两组:浅色模式、深色模式。不要为同一模式重复出现多个“深色模式”分组。
- 每个配置项都能分别复制配置名和配置值,也能导出当前主题的全部可写配置。
- 导入、导出、复制、重置都要给出明确提示,例如“配置已复制到剪贴板”。
- 控制台必须兼容移动端,两列布局在窄屏下退化为单列。
最小配色标准
所有内置主题至少暴露以下基础色,并分别提供浅色和深色两套配置:
| 语义 | 浅色键名示例 | 深色键名示例 |
|---|---|---|
| 主色 | THEME_COLOR_PRIMARY |
THEME_COLOR_PRIMARY_DARK |
| 页面背景 | THEME_COLOR_BG |
THEME_COLOR_BG_DARK |
| 卡片背景 | THEME_COLOR_CARD |
THEME_COLOR_CARD_DARK |
| 主文字 | THEME_COLOR_TEXT |
THEME_COLOR_TEXT_DARK |
| 边框 | THEME_COLOR_BORDER |
THEME_COLOR_BORDER_DARK |
如果主题实际使用了次级文字、弱背景、强调色、hover 色、导航背景、滚动条、标签等颜色,也应继续暴露到配色区。不要声明没有被真实 CSS 消费的“空配置”。
深色模式默认值必须遵守“深底、浅字、浅主色调”的原则。迁移默认值时优先复用原主题视觉,不允许因为接入控制台改变原版观感。
开发者接入流程
- 在主题
config.js或默认配置来源中保留原有默认值。 - 在
themes//style.js中把配置键映射为主题根节点上的 CSS 变量。 - 在组件样式中消费语义变量,而不是直接消费 Tailwind 固定色号。
- 在
conf/themeSwitch.manifest.js声明控制台元数据。 - 在真实页面验证:修改控制台值后,页面上对应颜色或配置必须立即可见。
示例:
// themes/heo/style.js
#theme-heo {
--heo-color-primary: ${siteConfig('HEO_COLOR_PRIMARY', '#4f65f0', CONFIG)};
--heo-color-text: ${siteConfig('HEO_COLOR_TEXT', '#111827', CONFIG)};
}className='text-[var(--heo-color-text)] bg-[var(--heo-color-primary)]'Manifest 约定
conf/themeSwitch.manifest.js 负责声明控制台如何展示配置,不负责实现样式。manifest 中声明的每个 palette 项都必须有真实 CSS 消费路径。
{
key: 'HEO_COLOR_PRIMARY',
cssVar: '--heo-color-primary',
label: '主色',
defaultValue: '#4f65f0',
group: 'light'
}推荐字段:
| 字段 | 说明 |
|---|---|
key |
写入 notion_config 的配置名 |
cssVar |
实时预览时写入的 CSS 变量 |
label |
控制台中文名称 |
defaultValue |
主题原版默认值 |
group |
light 或 dark |
description |
可选中文说明 |
信息配置使用 settings 声明。主题级配置不涉及密钥时可以进入控制台;全局配置必须使用白名单,不能扫描并暴露所有 blog.config.js 键。
settings: [
{
key: 'HEO_HOME_BANNER_ENABLE',
label: '首页 Banner',
description: '控制首页 Banner 是否显示。',
type: 'boolean',
defaultValue: true
}
]支持类型:
boolean:开关。text:短文本。number:数字输入。select:固定范围,用下拉框展示。color:颜色配置优先放入palette。
兼容旧主题
很多站长基于旧版 NotionNext 开发主题。新框架必须保证旧主题即使没有 manifest,也能正常运行,不应因为缺少控制台声明而崩溃。
兼容原则:
getThemeSwitchMeta()必须提供兜底元数据。themeConsoleStyle()只能注入 CSS 变量和必要别名,不能用全局选择器批量重写a、p、article等元素颜色。- 旧配置键可以继续保留,例如
FUWARI_THEME_COLOR_HUE,但调色板应映射到同一套实时变量,避免两个入口互相冲突。 - 新增变量不应改变旧主题默认视觉;默认色号要从旧代码或线上版本校对。
验收清单
- 每个内置主题都显示“配色”模块。
- 每个内置主题至少有浅色、深色两套基础色:主色、文字、背景、卡片、边框。
- 默认视觉与迁移前一致,尤其是导航栏、卡片背景、文章正文、深色模式文字。
- 修改浅色配置不会串到深色模式,修改深色配置也不会影响浅色模式。
- 控制台修改会实时反映到页面。
- 复制配置名、复制配置值、导出、导入、区块重置都有反馈。
- 未接入 manifest 的旧主题不会报错。
Developer THEME MIGRATION GUIDE (`docs/developer/THEME_MIGRATION_GUIDE.md`)
Theme Migration Guide (NotionNext)
This guide is for migrating an external theme (for example Astro/Vite themes) into NotionNext's Next.js + Notion data architecture.
1) Migration Goal
- Keep the original theme's visual language (layout, spacing, cards, motion).
- Follow NotionNext's data flow and feature conventions.
- Expose behavior through
themes//config.jsswitches instead of hardcoding.
2) Required Structure
Create a dedicated theme folder:
themes//index.jsthemes//style.jsthemes//config.jsthemes//components/*
Rules:
- Do not import UI components from other theme folders.
- Keep cross-theme shared components only from global
@/components/*when needed (for exampleNotionPage,Comment,ShareBar,FlipCard, ads widgets). - Keep theme-specific rendering and style under the theme folder.
3) Data Contract in NotionNext
Common props available in theme layouts/components:
siteInfo: site metadata, cover, title, descriptionposts,post,archivePostslatestPosts,categoryOptions,tagOptionsnoticepostCountprev,nextcustomNav,customMenurightAreaSlot
Typical post fields used by themes:
title,slug,href,summarypublishDay,lastEditedDaypageCover,pageCoverThumbnailcategory,tagItemstoc
4) Must-Have NotionNext Feature Compatibility
When migrating a new theme, verify all of these:
Data-driven menu
- Support default menu items.
- Support
customNav. - Support
CUSTOM_MENUoverriding withcustomMenu.
Notice/announcement block
- Render Notion content using
NotionPage. - If a separate announcement title is rendered, prefer the Notice page
titleand preserve the theme's existing title as a fallback. - Switchable in theme config.
- Render Notion content using
Notion cover as Hero
- Use
siteInfo.pageCoveras first priority for home hero background. - Keep fallback image config.
- Use
Dark mode support
- Use global context (
useGlobal) andtoggleDarkMode. - Avoid isolated theme-only dark state.
- Use global context (
Article module compatibility
- TOC panel switch
- Share module switch
- Comment module switch
- Copyright block switch
- Adjacent posts switch
Sidebar modularity
- Latest posts, categories, tags
- Contact card (optional flip card)
- Analytics card
- Ads card
- Plugin slot (
rightAreaSlot)
Float tools
- Back to top
- Jump to comment
- Dark mode quick switch
First-Viewport Stability and CLS
Each theme must define the first viewport during design and reserve stable space for it. The goal is not to remove real features for Lighthouse, but to keep the visual structure stable before and after Next.js scripts, dynamic theme chunks, images, fonts, ads, and plugins finish loading.
- Home, list, and landing pages must plan desktop and mobile first-viewport height. The first major visual section (hero, featured post, first post group, etc.) should use
min-h-screen,min-h-[calc(100vh-var(--header-height))], fixedaspect-ratio, or an equivalent theme-specific constraint so the footer or second-screen content does not appear in the first viewport and then get pushed away. - Dynamic theme loading fallbacks, article
!postfallbacks, and skeleton screens must stay close to the final layout height. If the final theme layout cannot be mirrored exactly, reserve at least one viewport of shell space. - Cover images, post thumbnails, sidebar images, avatars, ad slots, analytics cards, comment entry points, and plugin slots must have predefined width/height,
aspect-ratio, ormin-height. Content may load lazily, but it must not be inserted into the first viewport without reserved space. - Unstable-height modules such as dynamic categories, recommendations, tag clouds, ads, AI widgets, and comments should start below the first viewport. If they must appear in the first viewport, give their container a stable height close to the final state.
- Do not remove real features such as AOS, web fonts, analytics, or ads just to improve lab scores. Prefer reserved dimensions, correct first-viewport priority, lazy-loading boundaries, and below-the-fold deferral.
- Before merging, inspect the page under slow network or DevTools throttling from the initial HTML/fallback state through Next.js hydration. The first viewport, footer position, and main card heights should not visibly jump; CLS in Lighthouse / Performance should be near 0.
5) Config Design Pattern
Use siteConfig('<KEY>', <default>, CONFIG) consistently.
Recommended key groups:
THEME_MENU_*THEME_HERO_*THEME_POST_LIST_*THEME_WIDGET_*THEME_ARTICLE_*
Do not scatter constants in component bodies.
5.1 Theme Color Tokens
Older themes use many Tailwind CSS utility color classes because that made early development fast: layouts and interactions could ship without first designing a full token system. As the theme framework matures, new themes and theme refactors should move color semantics out of fixed Tailwind names. A class named blue, indigo, or yellow should not ambiguously mean primary color, accent color, dark-mode highlight, or status color depending on the component.
Recommended pattern:
- Put color defaults in
themes//config.jswith a theme prefix, for exampleHEO_COLOR_PRIMARY,HEO_COLOR_ACCENT,HEO_COLOR_BG. - Read them in
themes//style.jsand define scoped CSS variables on the current theme root, for example#theme-heo { --heo-color-primary: ... }; avoid writing theme tokens to global:root. - Components should use semantic variables such as
bg-[var(--heo-color-primary)]andtext-[var(--heo-color-text)]instead of adding more non-semantic fixed color classes. - Notion Config and environment variables may override these keys; theme
config.jsprovides defaults only. - A simple one-accent theme may expose only a primary color. A visually rich theme can expose background, card, border, text, secondary text, success, warning, and other tokens.
Minimum palette:
| Meaning | Example key | Usage |
|---|---|---|
| Primary | HEO_COLOR_PRIMARY |
Main buttons, selected states, important links |
| Primary hover | HEO_COLOR_PRIMARY_HOVER |
Main hover states |
| Accent | HEO_COLOR_ACCENT |
Secondary highlights, badges, decorative emphasis |
| Page background | HEO_COLOR_BG |
Body/page background |
| Card background | HEO_COLOR_CARD |
Cards, panels, floating surfaces |
| Border | HEO_COLOR_BORDER |
Card borders, dividers |
| Text | HEO_COLOR_TEXT |
Titles and body copy |
| Secondary text | HEO_COLOR_TEXT_SECONDARY |
Excerpts, metadata, muted copy |
6) Suggested Migration Workflow
- Build minimum runnable skeleton (
LayoutBase,LayoutIndex,LayoutSlug, etc.). - Split large
index.jsinto focused components. - Port original style details (cards, banner, metadata density, transitions).
- Integrate NotionNext feature modules and config switches.
- Add docs for all theme config keys and default values.
- Run lint and verify:
- Home/list/search/archive/category/tag/article/404
- Light/dark mode
- Menu behaviors (
customNav,CUSTOM_MENU) - Notice, ads, plugin slot, contact card
7) Contact Email (`CONTACT_EMAIL`) Conventions
The NEXT_PUBLIC_CONTACT_EMAIL environment variable is compiled into conf/contact.config.js and stored in siteConfig('CONTACT_EMAIL') as a Base64-encoded payload (UTF-8), so plain addresses do not appear verbatim in static HTML. When migrating or adding theme UI, pick the right helper or you will see garbled mailto: targets or wrong Gravatar hashes.
| Scenario | Do | Don't |
|---|---|---|
| Icon/link opens the system mail client | Use handleEmailClick (below) |
href={\mailto:${siteConfig('CONTACT_EMAIL')}`}` |
| Footer or copy shows the address | resolveContactEmail(siteConfig('CONTACT_EMAIL')) |
Render siteConfig('CONTACT_EMAIL') directly |
| md5 for Gravatar | Hash lowercased plaintext from resolveContactEmail |
md5 the encrypted string |
Server-generated text (e.g. security.txt) |
resolveContactEmail before mailto: |
Write the encrypted blob into the file |
Click-to-mail pattern (match themes/next/components/SocialButton.js):
import { useRef } from 'react'
import { handleEmailClick } from '@/lib/plugins/mailEncrypt'
import { siteConfig } from '@/lib/config'
const emailIcon = useRef(null)
const CONTACT_EMAIL = siteConfig('CONTACT_EMAIL')
// ...
{CONTACT_EMAIL && (
<a
onClick={e => handleEmailClick(e, emailIcon, CONTACT_EMAIL)}
title='email'
className='cursor-pointer'
ref={emailIcon}>
{/* icon */}
</a>
)}Helpers live in lib/plugins/mailEncrypt.js: handleEmailClick, decryptEmail, resolveContactEmail.
8) Contributing a theme to the main repo: preview images and Theme Switch copy
You can keep a custom theme under themes// locally or in your fork without opening a PR.
If you want the theme merged into the official NotionNext repository, you must also ship assets and manifest entries used by the theme switcher when THEME_SWITCH / NEXT_PUBLIC_THEME_SWITCH is enabled: cover previews plus human-readable name and summary.
8.1 Preview assets directory and naming (fixed location)
Commit static previews under:
public/images/themes-preview/
| File | Purpose |
|---|---|
.png |
Baseline image; must match the folder name under themes/ (lowercase), e.g. endspace.png. Used as LazyImage fallbackSrc. |
.webp |
Strongly recommended; convert from PNG (cwebp, Squoosh, ImageMagick, etc.). Used as the preferred src for smaller payloads. |
By default, getThemeSwitchMeta() resolves /images/themes-preview/.webp and .png. Submit both in PRs when possible.
8.2 Title and summary (`conf/themeSwitch.manifest.js`)
Edit conf/themeSwitch.manifest.js and add an entry under THEME_SWITCH_MANIFEST keyed by the theme id (same as the directory under themes/):
name(optional): label in the switcher; if omitted, the id is auto-formatted.summary(recommended): one-line blurb under the card title.cover/coverWebp(optional): custom image URLs. If omitted, the paths in §8.1 apply. If you only ship PNG for now, setcoverWebpto''for that theme so the UI uses PNG only.tier(optional):'free'or'paid'; defaults to'free', which shows a Free-style badge in the switcher. For future paid themes, settierto'paid'to show the paid label.
components/ThemeSwitch.js reads metadata via getThemeSwitchMeta(); you do not duplicate this inside the theme folder.
The theme switcher should also become the entry point for color palettes. A theme can declare the color config keys it supports through manifest/theme metadata, and the switcher can show key, current value, swatch, and copy actions. A one-color theme such as Fuwari may show only one primary control; a richer theme such as Heo may show a full palette so site owners can copy the final values back into Notion Config or themes//config.js.
8.3 Docs and review
- Long-form theme notes still belong under
docs/developer/themes/(see the visual fidelity checklist for doc placement). - In the PR description, list preview files and any new or updated manifest entries.
8.4 For developers: open source today and future commercial themes (roadmap)
This subsection is for theme authors: how we collaborate in the open repo today, and possible future options for paid themes. Final policies and timelines will be announced officially.
- Acknowledging the work: shipping and maintaining a theme (layout, UX, breakpoints, and ongoing compatibility) is real effort. Contributing redistributable themes to the public NotionNext repo remains highly valued.
- Current path: we still encourage free-to-use themes via PRs to the main GitHub repository, following §8.1–§8.3 for previews and manifest. Local or private-fork use is unrestricted.
- Future direction (not live yet): as the ecosystem matures, we plan to allow paid theme submissions so authors can be compensated while users get maintained, high-quality work.
- Planned shape (illustrative only): a separate private Git repository may be introduced for authors to publish and version themes; themes could be priced, and after purchase, buyers receive what they need to privately deploy the theme on their own sites (exact license, updates, and support will be defined at launch).
- Relation to code: the manifest
tierfield (free/paid) is for UI labeling in the theme switcher. Billing, entitlements, delivery, and private deployment will not rely on manifest alone; dedicated docs and tooling will ship when the program goes live.
9) Fuwari Migration Notes
For themes/fuwari, these specifics are already applied:
- Upstream style reference source: saicaca/fuwari
- Notion cover hero support
- Data-driven menu with
customNav/customMenucompatibility - Independent TOC, sidebar widgets, and right-float actions
- Flip contact card support via global
FlipCard
10) Common Pitfalls
- Hardcoded menu paths without
customMenusupport. - Reusing another theme's UI components directly.
- Local-only dark mode toggle that ignores global context.
- Missing
post?.tocandnotice?.blockMapguards. - Forgetting to expose new behaviors in theme config.
- Contact email: raw
mailto:with encrypted config or missinghandleEmailClick/resolveContactEmail(see section 7).
11) Visual Fidelity Checklist (Fuwari-like Themes)
- Layout orientation: desktop default should be left functional sidebar + right content feed.
- Hero full width: avoid
calc(50% - 50vw)scrollbar offset drift; use stable center transform strategy. - Post card variants:
- with cover: text left + cover right
- without cover: keep a right-side action rail to maintain visual rhythm
- Readmore affordance: right action rail and icon should keep consistent card height alignment.
- Profile card actions: include social icon row under avatar/bio if source theme has it.
- Theme color picker UX:
- trigger from top-right palette button
- use floating panel, not sidebar block
- real-time preview + persisted local setting
- expose each token's config key, semantic label, and current color value so operators can write it back into Notion Config or
config.js - one-primary-color themes show one control; richer themes show a full palette instead of forcing every theme into the same number of tokens
- Theme docs placement:
- avoid putting markdown docs under
themes//if build pipeline treats theme dirs as runtime modules - place theme docs under
docs/developer/themes/instead
- avoid putting markdown docs under
- Route transition feel: add lightweight page/card transition to mimic source theme interaction rhythm.
Developer THEME MIGRATION GUIDE.Zh CN (`docs/developer/THEME_MIGRATION_GUIDE.zh-CN.md`)
主题迁移指南(NotionNext)
本指南用于把外部主题(例如 Astro/Vite 主题)迁移到 NotionNext 的 Next.js + Notion 数据架构中。
1)迁移目标
- 尽量保留原主题的视觉语言(布局、间距、卡片、动效)。
- 遵循 NotionNext 的数据流与功能约定。
- 通过
themes//config.js暴露开关,避免把行为硬编码在页面里。
2)推荐目录结构
为新主题建立独立目录:
themes//index.jsthemes//style.jsthemes//config.jsthemes//components/*
原则:
- 不要直接引用其它主题目录下的 UI 组件。
- 跨主题通用能力优先复用全局组件(如
NotionPage、Comment、ShareBar、FlipCard、广告组件等)。 - 主题专属渲染与样式必须留在当前主题目录中。
3)NotionNext 数据契约
主题布局/组件常见可用 props:
siteInfo:站点元信息(标题、描述、封面等)posts、post、archivePostslatestPosts、categoryOptions、tagOptionsnoticepostCountprev、nextcustomNav、customMenurightAreaSlot
文章常用字段:
title、slug、href、summarypublishDay、lastEditedDaypageCover、pageCoverThumbnailcategory、tagItemstoc
4)必须兼容的 NotionNext 功能
迁移新主题时,至少覆盖:
数据驱动菜单
- 支持默认菜单项
- 支持
customNav - 支持
CUSTOM_MENU + customMenu覆盖
公告模块
- 使用
NotionPage渲染公告内容 - 如展示独立公告标题,应优先使用 Notice 页面的
title,并保留主题原有标题作为 fallback - 可通过主题配置开关启停
- 使用
Notion 封面作为 Hero
- 首页 Hero 优先使用
siteInfo.pageCover - 支持 fallback 配置图
- 首页 Hero 优先使用
深色模式
- 使用全局 context(
useGlobal/toggleDarkMode) - 不要单独实现与全局割裂的暗色状态
- 使用全局 context(
文章功能模块
- TOC 开关
- 分享开关
- 评论开关
- 版权信息开关
- 上一篇/下一篇开关
侧栏模块化
- 最新文章、分类、标签
- 联系卡(可选翻转)
- 统计卡
- 广告卡
- 插件插槽(
rightAreaSlot)
右下角浮动工具
- 回到顶部
- 跳到评论区
- 深色模式快捷切换
首屏稳定与 CLS 约束
每个主题在设计阶段就要明确“首屏能看到什么”,并为首屏内容预留稳定高度。目标不是删除真实功能来换 Lighthouse 分数,而是在 Next.js 脚本加载、主题动态加载、图片/字体/广告/插件补齐前后,首屏视觉结构不发生大范围位移。
- 首页、列表页、落地页必须先规划桌面端和移动端的首屏高度。首个主要视觉区(Hero、封面文章、首组文章流等)应使用
min-h-screen、min-h-[calc(100vh-var(--header-height))]、固定aspect-ratio或主题等价方案,避免加载后把页脚、第二屏模块或动态分类从首屏挤走。 - 主题动态加载 fallback、文章详情
!postfallback、骨架屏必须和最终布局的主轴高度接近。无法精确复刻主题时,至少保留一屏高度的空白壳,避免加载前露出页脚或大块下方内容。 - 封面图、文章卡图、侧栏图、头像、广告位、统计卡、评论入口和插件插槽必须提前确定宽高、
aspect-ratio或min-height。可以延迟加载内容,但不能在首屏内无占位地插入。 - 动态分类、推荐文章、标签云、广告、AI 小组件、评论等高度不稳定模块,优先放到首屏之后;如果必须出现在首屏内,需要给容器设置与最终状态接近的稳定高度。
- AOS、主题字体、统计脚本、广告脚本等真实功能默认不应为了跑分被移除。性能优化优先使用尺寸预留、首屏优先级、懒加载边界和 below-the-fold 延迟。
- 合并前用慢速网络或 DevTools throttling 观察“初始 HTML/fallback 状态”和“Next.js 脚本接管后状态”:首屏内容、页脚位置和主要卡片高度不应明显跳变;Lighthouse / Performance 面板中的 CLS 应接近 0。
5)配置设计建议
统一使用 siteConfig('<KEY>', <default>, CONFIG)。
建议按组命名:
THEME_MENU_*THEME_HERO_*THEME_POST_LIST_*THEME_WIDGET_*THEME_ARTICLE_*
避免在组件内部散落“魔法常量”。
5.1 主题颜色变量
早期主题大量使用 Tailwind CSS 工具类,是为了降低开发成本、快速验证布局与交互。现在主题框架已经更成熟,新的主题和后续重构应把颜色从 Tailwind 固定色名中抽离出来,改用主题自己的语义色变量,避免 blue、indigo、yellow 这类类名在代码里同时承担“主色”“强调色”“深色模式高亮”等不同含义。
推荐规则:
- 颜色配置放在
themes//config.js,使用主题前缀,例如HEO_COLOR_PRIMARY、HEO_COLOR_ACCENT、HEO_COLOR_BG。 themes//style.js读取配置后,在当前主题根节点下定义 CSS 变量,例如#theme-heo { --heo-color-primary: ... },不要直接写到全局:root。- 组件 className 使用语义变量,例如
bg-[var(--heo-color-primary)]、text-[var(--heo-color-text)],不要再新增无语义的固定色 class。 - Notion Config 与环境变量可以覆盖这些键;主题
config.js只保留默认值。 - 所有内置主题至少暴露主色、页面背景、卡片背景、主文字和边框,并分别提供浅色与深色两套配置;主题实际使用了次级文字、强调色或 hover 色时,也要纳入调色板。
- 深色配置键在浅色键后追加
_DARK,例如HEO_COLOR_TEXT_DARK。两套配置必须映射到独立基础变量,再由当前模式选择活动变量,避免切换模式后串色。 - manifest 只负责声明,不能代替实现;CSS 变量必须被组件真实消费,控制台修改后应立即可见。
- 迁移时沿用原主题色值作为默认值,不能因为接入调色板改变原版视觉。
建议的最小色板:
| 语义 | 示例配置键 | 用途 |
|---|---|---|
| 主色 | HEO_COLOR_PRIMARY |
主按钮、选中态、重点链接 |
| 主色悬停 | HEO_COLOR_PRIMARY_HOVER |
主按钮和重点元素 hover |
| 强调色 | HEO_COLOR_ACCENT |
辅助高亮、徽标、特殊装饰 |
| 页面背景 | HEO_COLOR_BG |
页面底色 |
| 卡片背景 | HEO_COLOR_CARD |
卡片、面板、浮层 |
| 边框 | HEO_COLOR_BORDER |
卡片边框、分割线 |
| 主文字 | HEO_COLOR_TEXT |
标题和正文 |
| 次级文字 | HEO_COLOR_TEXT_SECONDARY |
摘要、元信息、辅助说明 |
6)推荐迁移流程
- 先做最小可运行骨架(
LayoutBase、LayoutIndex、LayoutSlug等)。 - 再把大文件
index.js拆分为多个组件。 - 按原主题逐项还原视觉细节(卡片、Banner、元信息密度、动效)。
- 接入 NotionNext 的特色模块与配置开关。
- 为新增配置补齐文档。
- 执行 lint 并验证关键路由:
- 首页/列表/搜索/归档/分类/标签/文章/404
- 深浅色模式
- 菜单行为(
customNav、CUSTOM_MENU) - 公告、广告、插件槽、联系卡
7)联系邮箱(CONTACT_EMAIL)约定
环境变量 NEXT_PUBLIC_CONTACT_EMAIL 会在构建阶段写入 conf/contact.config.js,并以 Base64 形式保存在 siteConfig('CONTACT_EMAIL') 中,用于避免在静态页面里直接暴露明文邮箱。迁移或新增主题时请务必按用途选用下列方式,否则会出现「mailto 乱码」或 Gravatar 不匹配等问题。
| 场景 | 正确做法 | 错误示例 |
|---|---|---|
| 图标/链接点击打开系统邮件客户端 | 使用 handleEmailClick(见下) |
href={\mailto:${siteConfig('CONTACT_EMAIL')}`}` |
| 页脚、文案中展示邮箱地址 | resolveContactEmail(siteConfig('CONTACT_EMAIL')) |
直接渲染 siteConfig('CONTACT_EMAIL') |
| Gravatar 等需要邮箱 md5 | 对 resolveContactEmail 的结果取小写再哈希 |
对密文做 md5 |
security.txt 等服务端生成的联系行 |
resolveContactEmail 后再写入 |
把密文写进 mailto: |
点击发邮(推荐与 themes/next/components/SocialButton.js 保持一致):
import { useRef } from 'react'
import { handleEmailClick } from '@/lib/plugins/mailEncrypt'
import { siteConfig } from '@/lib/config'
const emailIcon = useRef(null)
const CONTACT_EMAIL = siteConfig('CONTACT_EMAIL')
// ...
{CONTACT_EMAIL && (
<a
onClick={e => handleEmailClick(e, emailIcon, CONTACT_EMAIL)}
title='email'
className='cursor-pointer'
ref={emailIcon}>
{/* icon */}
</a>
)}实现位于 lib/plugins/mailEncrypt.js:handleEmailClick、decryptEmail、resolveContactEmail。
8)向主仓库贡献主题:预览图与简介(主题切换面板)
你在本地或自建 fork 中,可随时将自定义主题放在 themes/<主题目录名>/ 下使用,不强制提交到 NotionNext 上游。
若希望主题被 合并进 NotionNext 官方主仓库,除完整主题代码外,还需补齐「主题切换」浮窗中的 预览图 与 文案介绍(站点启用 THEME_SWITCH / NEXT_PUBLIC_THEME_SWITCH 时展示)。
8.1 预览图目录与命名(固定)
将预览静态资源提交到仓库目录:
public/images/themes-preview/
| 文件 | 说明 |
|---|---|
<主题目录名>.png |
常规约定下需提供的基准图;与 themes/ 下文件夹名一致、小写,例如 endspace.png。用作 LazyImage 的 fallbackSrc,保证兼容性。 |
<主题目录名>.webp |
强烈建议同时提供;由 PNG 导出或转换即可。用作优先 src,体积更小、加载更快。可用 cwebp、Squoosh、ImageMagick 等将 PNG 转为 WebP。 |
组件默认按 /images/themes-preview/.webp 与 .png 读取;若某一格式缺失,面板仍能工作,但请在 PR 中尽量两者齐备。
8.2 展示名与简介(固定配置文件)
编辑 conf/themeSwitch.manifest.js,在 THEME_SWITCH_MANIFEST 中为主题 id(等于 themes/ 下目录名)增加一条配置:
name(可选):主题切换面板里显示的标题;不写则自动把目录名格式化为可读标题。summary(推荐):一句话简介,显示在卡片标题下方。cover/coverWebp(可选):自定义预览图 URL;不写则使用上一节的默认路径。若暂时只提供 PNG、不上传 webp,可将该主题的coverWebp设为'',面板将仅使用 PNG。tier(可选):'free'或'paid';缺省为'free',面板会显示对应标签(免费 / 付费)。后续若上线付费主题,将tier设为'paid'即可区分展示。
读取逻辑由 getThemeSwitchMeta()(与文件同目录导出)统一合并默认值;components/ThemeSwitch.js 只依赖该函数,主题目录内无需重复维护简介。
主题控制台承载调色板入口。主题在 manifest 中声明颜色配置项,面板读取后展示“配置键 + 当前色值 + 色块 + 复制值”。所有内置主题都必须提供浅色、深色两套基础色;复杂主题继续暴露次级文字、强调色、hover、状态色等实际使用的颜色,帮助站长直接把调整结果写回 Notion Config 或 themes//config.js。
8.3 文档与其他约定
- 主题详细说明仍建议写在
docs/developer/themes/(见下文「高还原度检查清单」中的文档放置约定)。 - 合并主仓库前请在 PR 说明中列出:预览图文件、
themeSwitch.manifest.js中新增或修改的条目。
8.4 面向开发者:开源贡献与商业化规划(路线说明)
本节面向主题开发者,说明当前开源协作方式与后续可能的商业化方向;具体规则与时间表以项目正式公告为准。
- 承认投入:完整主题涉及视觉、交互、多端适配与长期兼容,开发与维护成本高;向 NotionNext 公开主仓库贡献可再分发主题,是对社区的重要支持。
- 当前默认路径:继续鼓励通过 GitHub 主仓库 PR 提交免费使用的主题(并遵守 §8.1–§8.3 的预览与 manifest 约定)。本地或私有 fork 自用不受限。
- 后续规划(尚未落地):在生态成熟后,拟允许开发者将部分主题以付费形式提交,在尊重作者劳动的前提下,为高质量主题提供可持续路径。
- 规划中的形态(示意):后续可能建立独立私有 Git 仓库,供开发者上传、版本化与提交主题;主题可自主或平台协助定价,用户在付费后获得在自有环境私有化部署该主题所需的交付物或授权(具体许可范围、更新策略与技术支持以正式发布为准)。
- 与代码的衔接:
conf/themeSwitch.manifest.js中的tier(free/paid)用于主题切换面板的展示分层;付费鉴权、订单、交付与私有化部署流程不会仅靠 manifest 完成,上线时将另有专用文档与工具链。
9)Fuwari 迁移说明
themes/fuwari 目前已落地:
- 上游样式参考源:saicaca/fuwari
- Notion 封面 Hero 支持
- 数据驱动菜单(支持
customNav/customMenu) - 独立 TOC、侧栏模块、右下角浮动区
- 基于全局
FlipCard的翻转联系卡
10)常见坑位
- 菜单硬编码,没有接
customMenu。 - 直接复用其他主题 UI,导致耦合。
- 深色模式与全局状态不一致。
- 缺少
post?.toc、notice?.blockMap等空值保护。 - 新增功能未透出配置开关。
- 联系邮箱使用
mailto:直链密文或未使用handleEmailClick/resolveContactEmail(参见上文第 7 节)。
11)高还原度检查清单(以 Fuwari 为例)
- 布局方向:桌面端默认应为“左侧功能区 + 右侧内容流”。
- Hero 全宽:避免
calc(50% - 50vw)在滚动条场景导致偏移,优先使用居中平移方案。 - 文章卡双形态:
- 有封面:左文右图
- 无封面:保留右侧按钮导轨,保持节奏统一
- Readmore 对齐:右侧按钮区域需和卡片高度对齐,不应出现跳变。
- 侧栏个人卡:若原主题有社交按钮行,应在头像/简介下补齐。
- 主题色调色板体验:
- 从顶部右上角调色按钮触发
- 使用悬浮面板,不放在侧栏
- 实时预览 + 本地记忆
- 显示每个色号的配置键、语义名称和当前色值,便于站长回填 Notion Config 或
config.js - 单主色主题只展示主色;多色主题展示完整色板,不强行套用同一数量的色项
- 主题文档放置位置:
- 避免把 Markdown 文档直接放在
themes//下(部分构建链路会把主题目录当运行时模块处理) - 主题说明建议统一放在
docs/developer/themes/
- 避免把 Markdown 文档直接放在
- 页面跳转体感:补轻量过渡动效,接近源主题的交互节奏。
Developer UPDATE (`docs/developer/UPDATE.md`)
NotionNext 版本更新指南
本指南帮助您安全地将博客更新到上游最新版本,同时保留所有个性化配置。
按照以下流程操作,您可以:
- ✅ 获取 NotionNext 的最新功能和修复
- ✅ 保留您的个人配置(头像、标题、域名等)
- ✅ 安全处理可能的代码冲突
⚠️ 本指南适用于 Vercel 部署场景,其他平台未测试。
分支管理策略
本策略参考 NotionNext 官方升级教程 中的建议,使用双分支管理模式。
分支说明
| 分支 | 用途 | 更新策略 | 部署状态 |
|---|---|---|---|
main |
同步上游原始代码 | 快进合并 | 不部署 |
deploy |
生产环境代码 | 合并 main + 保留个性化 | Vercel 自动部署 |
feature/* |
功能开发 | 基于 deploy 创建 | 不部署 |
架构示意
GitHub Fork Repository
├── main (同步 notionnext-org/NotionNext)
├── deploy (生产分支 → Vercel)
└── feature/* (开发分支)前置准备
1. 配置 Vercel 生产分支(重要)
在 Vercel 中将生产分支设置为 deploy:
- 登录 Vercel Dashboard
- 进入你的 NotionNext 项目
- 点击 Settings → Git
- 找到 Production Branch 设置
- 将默认的
main改为deploy - 保存设置
💡 这样配置后,只有
deploy分支的更新会触发生产环境部署,main分支仅用于同步上游。
2. 配置上游仓库(仅首次)
# 添加上游仓库
git remote add upstream https://github.com/notionnext-org/NotionNext.git
# 验证配置
git remote -v预期输出:
origin https://github.com/[你的用户名]/NotionNext.git (fetch)
origin https://github.com/[你的用户名]/NotionNext.git (push)
upstream https://github.com/notionnext-org/NotionNext.git (fetch)
upstream https://github.com/notionnext-org/NotionNext.git (push)⚠️ 如果没有看到 upstream 行,说明上游仓库未成功添加
3. 识别个性化文件
更新前先了解你的个性化修改:
# 查看个性化修改文件列表
git diff --name-only main..deploy常见个性化文件:
blog.config.js- 博客配置public/avatar.png- 头像public/favicon.ico- 网站图标pages/_app.js- 全局脚本.env.local- 环境变量
标准更新流程
步骤 1:同步 main 分支
# 1.1 切换到 main 分支
git checkout main
# 1.2 拉取本地最新(防止多设备不同步)
git pull origin main
# 1.3 获取上游更新
git fetch upstream
# 1.4 合并上游代码
git merge upstream/main
# 1.5 推送到自己的仓库
git push origin main步骤 2:更新 deploy 分支
# 2.1 切换到 deploy 分支
git checkout deploy
# 2.2 【重要】同步远程 deploy 分支
git pull origin deploy
# 2.3 合并 main 分支的更新
git merge main步骤 3:处理冲突
如果出现冲突,根据文件类型处理:
| 文件类型 | 处理策略 | Git 命令 |
|---|---|---|
yarn.lock |
接受上游版本 | git checkout --theirs yarn.lock |
blog.config.js |
手动合并 | 保留个人配置,添加新配置项 |
public/avatar.png |
保留本地版本 | git checkout --ours public/avatar.png |
public/favicon.* |
保留本地版本 | git checkout --ours public/favicon.* |
处理完成后:
# 添加已解决的文件
git add .
# 提交合并
git commit -m "merge: 同步上游更新
- 保留个性化配置
- 解决冲突文件: [文件列表]"步骤 4:更新依赖并测试
# 4.1 清理并重新安装依赖
rm -rf node_modules
yarn install
# 4.2 本地测试
yarn dev
# 访问 http://localhost:3000 确认正常
# 4.3 构建测试
yarn build
# 4.4 推送到远程
git push origin deploy自动化脚本
项目提供了自动化更新脚本 scripts/update.sh,功能包括:
- 前置条件检查
- 自动备份配置文件
- 分支同步与合并
- 安全冲突处理
- 依赖更新
使用方法
# 赋予执行权限(首次)
chmod +x scripts/update.sh
# 执行更新
./scripts/update.sh脚本会引导你完成整个更新流程,遇到需要手动处理的情况会给出明确提示。
回滚操作
方法一:Git 回滚
# 查看提交历史
git log --oneline -10
# 回滚到指定版本
git reset --hard [commit-hash]
# 强制推送(谨慎使用)
git push origin deploy --force-with-lease方法二:从 Vercel 恢复
如果误操作覆盖了代码,可以从 Vercel 的部署历史中恢复:
- 登录 Vercel Dashboard
- 进入项目 → Deployments
- 找到正常的历史部署,点击右侧三个点
- 选择 "View Source" 查看当时的源代码
- 点击右上角可跳转到 GitHub 对应版本
故障排查
Vercel 部署失败
问题:推送后 Vercel 构建失败
解决方案:
- 检查 Vercel 构建日志定位具体错误
- 如果是依赖问题:bash
rm -rf node_modules yarn.lock yarn install git add yarn.lock git commit -m "fix: 重新生成 yarn.lock" git push - 如果是环境变量问题:检查 Vercel Dashboard → Settings → Environment Variables
大量文件冲突
问题:合并时出现大量冲突,难以处理
解决方案:
# 中止当前合并
git merge --abort
# 查看上游最近的提交
git log upstream/main --oneline -20
# 分步合并(先合并较早的提交)
git merge [earlier-commit]
# 解决冲突后继续合并下一个本地与远程不同步
问题:推送时提示 rejected
解决方案:
# 先拉取远程更新
git pull origin deploy --rebase
# 解决可能的冲突后推送
git push origin deploy注意事项
- 更新频率:建议每 1-2 周检查一次更新,重要安全更新应立即处理
- 备份重要文件:更新前备份
blog.config.js和其他个性化配置 - 测试验证:更新后务必在本地测试,确认功能正常再部署
- 记录修改:建议维护一份个性化修改清单,便于后续更新
相关资源
文档版本:0.1.0 | 最后更新:2025-08-19
Developer VISION ROADMAP (`docs/developer/VISION_ROADMAP.md`)
NotionNext 愿景与路线图
NotionNext 的长期目标,不是把 Notion 简单包装成另一个博客模板,而是让它成为一个稳定、可演进、可由社区共同维护的内容发布系统。
Notion 负责内容生产、资料整理和团队协作;NotionNext 负责公开访问、主题展示、SEO、部署、性能和长期运营。两者连接得越自然,站长需要手工维护的地方就越少,内容也越容易持续沉淀。
5.0 方向
5.0 不应只是“多几个功能”的版本。它更应该回答一个问题:一个普通站长如何在不被 Git、部署平台和 Notion 数据结构反复打断的情况下,长期维护自己的站点?
围绕这个目标,后续路线会优先关注这些方向。
1. 降低使用门槛
NotionNext 仍然是开源项目,但部署、升级、排错不能只服务熟悉工程流程的人。未来需要继续减少这些摩擦:
- 更清楚的升级路径,降低分支、Fork、Pull Request 带来的理解成本。
- 更稳定的构建和缓存策略,减少“代码已经更新但网站仍是旧状态”的困惑。
- 更友好的错误提示和自检工具,让站长能先判断是配置问题、缓存问题还是代码问题。
- 更完整的文档,把常见真实场景沉淀成可复用的排查步骤。
2. 更完整地承接 Notion 数据库能力
Notion 的数据库、视图、筛选和排序是许多站长真正依赖的能力。NotionNext 应尽量理解这些结构,而不是要求用户额外维护大量重复标签。
近期已经开始补齐嵌入数据库视图筛选等兼容问题。长期可以继续推进:
- 更稳定地读取 Notion 数据库视图筛选、排序和分组结果。
- 支持更多 Notion 属性类型和多条件组合。
- 降低“为了网站展示而重复造标签”的人工维护成本。
- 明确哪些 Notion 行为可以可靠支持,哪些需要降级或文档说明。
3. 主题、版型和内容模块化
NotionNext 已经有多套主题,但长期维护的关键不是主题数量,而是主题之间能否共享稳定的基础能力。
后续可以逐步沉淀:
- 更清晰的主题接口和配置边界。
- 可复用的文章卡片、列表、图库、导航、筛选页面等内容模块。
- 面向不同场景的版型能力,例如案例库、作品集、知识库、产品页和导航站。
- 更容易迁移和维护的主题文档、预览图与测试方式。
4. 更安全的升级体验
很多站长会在 Fork 后修改配置、样式或主题。项目需要承认这种现实,而不是假设所有人都只使用原始代码。
未来需要继续优化:
- 把站长自定义配置和核心代码改动尽量分离。
- 让版本升级更容易判断哪些冲突必须人工处理。
- 对常见下游分支维护方式提供更明确的建议。
- 在 CI、测试和发布流程中尽早发现破坏性变更。
5. 让更多角色能参与
开源项目不只需要核心代码贡献者。NotionNext 的真实使用场景很多,站长、设计师、文档维护者、测试者都能帮助项目变好。
我们希望把任务拆得更小、更清楚,让不同经验的人都能找到入口。
可以如何参与
如果你还不熟悉代码,可以从这些事情开始:
- 复现问题:提供网站链接、Notion 页面、分支名、部署平台和截图。
- 测试修复:在自己的站点或测试分支验证 PR 是否解决真实问题。
- 补充文档:把踩过的坑整理成教程、FAQ 或排查步骤。
- 改进体验:指出哪些概念、配置或升级流程对非开发者不友好。
- 贡献主题素材:补主题截图、使用说明、适用场景和配置示例。
如果你已经能改代码,可以优先关注:
- Notion 数据结构兼容性和测试用例。
- 主题公共组件和版型模块。
- 构建、缓存、部署和升级稳定性。
- 文档站、CI、发布流程和维护工具。
- 带有
good first issue或help wanted标签的问题。
近期适合拆分的任务
这些方向适合逐步拆成 Issue、Discussion 或 RFC:
| 方向 | 可拆任务 |
|---|---|
| Notion 数据库能力 | 补齐视图筛选、排序、状态分组、多选、日期、关系属性等兼容测试 |
| 图文卡片版型 | 为标签页、分类页或指定数据库视图提供稳定的卡片展示方案 |
| 升级体验 | 梳理 Fork 用户如何同步上游、如何处理分支和部署缓存 |
| 主题模块化 | 抽象文章卡片、列表、图库、筛选页等跨主题可复用组件 |
| 文档维护 | 把真实用户反馈整理成 FAQ、排查手册和升级指南 |
| 测试与 CI | 为关键数据格式、构建缓存、主题渲染补充小范围自动化验证 |
协作原则
- 先讨论真实场景,再设计功能。
- 大改动先写 RFC,小修复保持 PR 小而清楚。
- 优先补测试和文档,减少后续维护成本。
- 允许非代码贡献存在价值,真实反馈本身就是项目路线的一部分。
NotionNext 的 5.0 不是某个人一次性完成的大版本,而是社区持续把复杂度收拢、把门槛降下来的过程。每一次可复现的问题、一次文档修正、一个小范围 PR,都会让后来的站长少踩一个坑。
Performance 2026 06 03 Theme Performance Optimization Phase 1 (`docs/performance/2026-06-03-theme-performance-optimization-phase-1.md`)
涓婚鎬ц兘浼樺寲锛堢 1 杞級
鏃ユ湡锛?026-06-03
鍒嗘敮锛歚codex/performance-optimization-main 鐗堟湰鐩爣锛歚4.10.0
鏈疆鍙樻洿
1) 鍏ㄥ眬鎻掍欢鍔犺浇浼樺寲
- 鏂囦欢锛歚components/ExternalPlugins.js`
- 鏀瑰姩锛? - 灏嗚嚜瀹氫箟澶栭儴璧勬簮鍔犺浇浠庣粍浠舵覆鏌撴湡绉诲叆
useEffect锛屽苟鏀逛负寮傛璋冨害锛坄requestIdleCallback/setTimeout锛夋墽琛屻€? - 瀵?CUSTOM_EXTERNAL_CSS銆乣CUSTOM_EXTERNAL_JS鍋?useMemo杩囨护锛岄伩鍏嶉噸澶嶈绠椾笌閲嶅娉ㄥ叆銆? - 灏?GLOBAL_JS鎵ц浠庢棤渚濊禆鐨勫壇浣滅敤鏀逛负useEffect([GLOBAL_JS])锛屽苟鍔?try/catch锛岄伩鍏嶆瘡娆?render 閲嶅鎵ц瀵艰嚧閲嶅娉ㄥ叆涓庢綔鍦ㄩ樆濉炪€?
2) Typography 鎼滅储楂樹寒鎸夐渶鍔犺浇
- 鏂囦欢锛歚themes/typography/index.js`
- 鏀瑰姩锛? -
LayoutSearch涓皢replaceSearchResult杩佺Щ涓烘寜闇€鍔ㄦ€?import锛堜粎鍦ㄦ悳绱㈤〉鐢熸晥鏃惰Е鍙戯級锛岄伩鍏嶉椤?鏂囩珷椤靛垵濮嬪寘瑁瑰叆杩欓儴鍒嗕唬鐮併€? - 灏嗘悳绱㈤珮浜寕杞芥敼涓哄欢鍚庢墽琛岋紙requestIdleCallback鎴?fallback timeout锛夛紝闄嶄綆棣栧睆闃诲銆?
3) 鎼滅储楂樹寒閫昏緫缁熶竴浼樺寲锛堣法涓婚锛?- 鏂囦欢锛歚components/Mark.js`
- 鏀瑰姩锛? - 灏?
mark.js搴撳姞杞芥敼涓轰竴娆℃€?Promise 缂撳瓨锛岄伩鍏嶅悓涓€娆′細璇濆唴閲嶅璇锋眰銆? - 瀵规悳绱㈠叧閿瘝杩涜瀹夊叏杞箟锛岄伩鍏嶅紓甯告鍒欏鑷撮珮浜矾寰勪腑鏂€? - 鐢?requestIdleCallback锛堝吋瀹?fallback锛夊皢楂樹寒鎵ц寤跺悗锛屽噺灏戠洿鎺ラ樆濉炰富绾跨▼楂樺嘲銆? - 淇濇寔鐜版湁楂樹寒杈撳嚭锛坈lassName/element锛変笌閰嶇疆涓嶅彉銆?
4) 涓婚鎬ц兘瀹¤鑴氭湰璺ㄥ钩鍙板吋瀹逛慨澶?- 鏂囦欢锛歚scripts/audit-theme-performance.js`
- 鏀瑰姩锛? - 鎸夊钩鍙伴€夋嫨
lighthouse鍙墽琛岃矾寰勶紙Windows 浼樺厛lighthouse.cmd锛屾湭鍛戒腑鏃堕檷绾у埌lighthouse鎴栧寘鍐?CLI 鍏ュ彛锛夈€? -runLighthouse鎵ц璺緞鏀逛负鍙橀噺鍖栵紝閬垮厤 Windows 涓?spawnSync璇嗗埆闂銆? -main鏀逛负鍚屾娴佺▼锛岀Щ闄?async/.catch鐨勪笉鍖归厤璋冪敤銆?
5) 涓婚绾ф粴鍔ㄧ洃鍚紭鍖栵紙璺ㄤ富棰橈級
- 鏂囦欢锛歚themes//components/.js`
- 鏀瑰姩锛? - 灏嗗ぇ閲忎粎璇绘粴鍔ㄤ綅缃?杩涘害鐨勭洃鍚櫒鏀逛负
passive: true娉ㄥ唽锛屽噺灏戞粴鍔ㄤ簨浠跺涓荤嚎绋嬭皟搴﹀帇鍔涖€? - 瑕嗙洊鑼冨洿锛欳atalog銆丳rogress銆佹诞鍔ㄥ鑸€丅ackToTop 绛夊ぇ閲忎富棰樺唴婊氬姩鍦烘櫙锛堝叡 70+ 澶勶級銆? - 淇濇寔琛屼负涓€鑷达紙鐩戝惉閫昏緫鍜屽嵏杞戒粛淇濇寔鍘熸湁鍥炶皟鍖归厤锛夈€?
楠岃瘉
yarn type-check锛氶€氳繃yarn build锛氶€氳繃yarn lint锛氭湰鏈虹幆澧冩姤閿欌€滄湭璇嗗埆 pages/app 鐩綍鈥濓紝鏆傛湭閫氳繃璇ラ」楠岃瘉锛堜笌褰撳墠 Next.js 鍚姩鐜璺緞瑙f瀽鐩稿叧锛屼笉褰卞搷宸插畬鎴愮紪璇戜笌绫诲瀷鏍¢獙缁撴灉锛?
椋庨櫓涓庡奖鍝?- 澶栭儴鑴氭湰鍔犺浇鏀逛负寤惰繜锛屼笉褰卞搷鐜版湁閰嶇疆椤逛笌鎻掍欢寮€鍏抽€昏緫锛坄DISABLE_PLUGIN` 绛変繚鎸佷笉鍙橈級銆?- `GLOBAL_JS` 鍙湪鍐呭鍙樺寲鏃舵墽琛岋紝琛屼负涓庨厤缃粨鏋滀繚鎸佷竴鑷达紝浣嗛檷浣庝簡閲嶅娉ㄥ叆椋庨櫓銆?
涓嬩竴姝ヨ鍒掞紙P2锛?- 缁х画姊崇悊涓婚灞傞潰浠嶆湁杈冮噸鐨勯灞忛€昏緫锛堢壒鍒槸鎼滅储銆佺洰褰曘€侀珮棰?DOM 閬嶅巻閫昏緫锛夛紝鎸夊奖鍝嶉潰浼樺厛钀藉湴銆?- 寤虹珛鍙鐢ㄧ殑涓婚绾у欢杩熸墽琛屽熀绾匡紙绌洪棽/婊氬姩瑙﹀彂锛夛紝骞惰ˉ榻愬涓婚瀵规瘮鐨勮嚜鍔ㄥ寲 Lighthouse 鎶ュ憡銆?
2026-06-03 Follow-up: Next and Endspace scroll rendering pass
Version: 4.10.0
Scope
themes/next/components/BlogPostListScroll.jsthemes/next/components/StickyBar.jsthemes/next/components/Toc.jsthemes/next/components/TopNav.jsthemes/endspace/components/FloatingControls.jsthemes/endspace/components/FloatingToc.jsthemes/endspace/components/MobileToc.js
Meaning
- Replaced high-frequency lodash throttle scroll handlers with
requestAnimationFramescheduling where the UI is tied to visual scroll state. - Collapsed duplicated progress and TOC scroll listeners in Endspace into a single scroll pipeline per component.
- Added ref-based state guards for reading progress and active TOC section to avoid repeated React state updates with the same value.
- Cached DOM targets such as sticky navigation elements through refs instead of querying on every scroll tick.
- Kept theme APIs, config switches, visual behavior, and plugin behavior unchanged.
Acceptance
yarn -s eslinton affected files: passed..\\node_modules\\.bin\\tsc.cmd --noEmit --pretty false: passed.yarn -s build: passed.- Browser validation:
/article/guide?theme=next: desktop and mobile scroll progress updates, no console errors./article/guide?theme=endspace: desktop and mobile TOC/progress controls remain visible and update on scroll, no console errors.
Next optimization target
- Build output still warns that
/and selected article page-data exceed 128KB. The next priority should be reducing serialized page props and trimming data sent to the client before pursuing smaller per-component scroll wins.
Performance 2026 06 04 Performance Refactor Plan (`docs/performance/2026-06-04-performance-refactor-plan.md`)
2026-06-04 性能重构推进计划
背景
4.10.0 已完成首轮主题渲染与 page-data 瘦身,但最新体检发现,生产构建阶段仍存在跨进程缓存锁竞争。问题表现为多个 Next 静态生成 worker 同时等待同一个 Notion 数据 key,旧策略在 30 秒后会绕过锁并重复执行昂贵的 Notion 数据生成任务,导致构建时间拉长、日志噪音变大,并增加 CI 不稳定风险。
本阶段目标是在不改变现有主题、配置插件和用户可见功能的前提下,先稳定构建与缓存基础,再继续推进主题运行时性能优化。
总体优先级
P0 构建缓存与锁稳定性
- 构建阶段不再使用 30 秒超时后并发绕过锁的策略。
- 文件锁支持
bypass、wait、throw三种超时策略,默认保持兼容。 - 构建缓存调用显式使用
wait策略,优先等待锁持有者写入缓存。 - 锁释放或等待方接管前,增加缓存二次读取,降低锁释放瞬间的竞态重算。
- 文件缓存写入改为临时文件 + rename 的原子写入,避免读到半成品 JSON。
P1 生产基线与预算验收
- 每次 P0 调整后必须跑
yarn build。 - 构建成功后跑
yarn perf:page-data,确认 page-data budget 不回退。 - 后续恢复全主题生产 Lighthouse 审计,并更新主题性能基线。
P2 主题首屏 LCP 与图片
- 优先主题:
landing、magzine、matery、hexo、next。 - 明确首屏图片尺寸、
sizes、priority 边界。 - 非首屏图片保持 lazy,不抢首屏加载优先级。
P3 JS/CSS 瘦身
- 优先检查
PrismMac、NotionPage、代码高亮、搜索标记和文章页专用逻辑。 - 继续拆分主题专用、文章页专用、代码块专用模块。
- 清理所有主题共享但实际只被少数主题使用的 CSS/JS。
P4 scroll/layout 运行时治理
- 优先主题:
next、hexo、heo、commerce。 - 合并滚动监听,减少多组件重复读写 scroll 状态。
- 将同步布局读取改成 observer、缓存 ref 或 rAF 批处理。
P5 DOM 与可访问性收尾
- 控制
next、hexo的 DOM 规模。 - 继续修复
typography、magzine的可访问性低分项。
本阶段已完成
- 新建性能优化分支:
codex/perf-build-cache-stability。 - 修复 main 最新 CI 中
convertInnerUrl测试对notion-utilsESM 的直接依赖。 - 新增文件锁回归测试,覆盖:
wait策略等待锁持有者缓存结果,不重复执行昂贵函数。- 默认数字 timeout 仍保持旧的 bypass 兼容行为。
- 第二次生产构建已完成,旧的
ABSOLUTE TIMEOUT ... Bypassing lock为 0。 yarn perf:page-data通过,所有采样路由均未超过预算。
当前验收结果
yarn -s type-check:通过。yarn -s lint --file ...:通过。yarn -s test __tests__/lib/cache/file_lock.test.js --runInBand:通过。yarn -s build:通过。yarn -s perf:page-data:通过。
本地 convertInnerUrl DOM 测试仍受当前 Windows 环境中 canvas.node 原生模块缺失影响,测试环境在进入断言前失败;CI 上原始失败点是 notion-utils ESM 解析,本阶段已通过测试内 mock 修复。
下一批建议
- 增加构建阶段全站数据预热,让
global_data与site在静态 worker 扩散前完成一次共享写入。 - 统计构建日志中的
extended waiting和acquired after extended wait,将其降到接近 0。 - 在生产构建稳定后恢复全主题 Lighthouse,重新排序 LCP、CLS、unused JS/CSS 的主题优先级。
- 从
next / hexo / heo / commerce开始治理 scroll/layout 热点。
Public Ai Assistant Instructions (`docs/public/ai-assistant-instructions.txt`)
You are the NotionNext documentation assistant.
Answer in Chinese by default. Keep replies beginner-friendly and operational.
Scope:
- Help users understand NotionNext deployment, themes, Notion database setup, site configuration, comments, plugins, and common troubleshooting.
- Prefer direct steps and exact config names when possible.
- If you are unsure, tell the user where to check in the docs instead of inventing details.
Important doc entry points:
- /user-guide/start-here
- /user-guide/deploy-vercel
- /user-guide/config-site
- /user-guide/themes/THEMES_CATALOG
- /user-guide/themes/overview
- /user-guide/reference/features
- /user-guide/comments/overview
- /user-guide/plugins/notion-next-docs-chat
User Guide MAINTENANCE WORKFLOW (`docs/user-guide/MAINTENANCE_WORKFLOW.md`)
用户文档维护工作流
面向站长、贡献者、维护者:如何在仓库内正确新增、修改、排序 NotionNext 使用说明。
策略总纲:DOCUMENTATION_POLICY.md
读者导航:使用说明目录 · 官方 slug 对照:ARTICLE_INDEX.md
一、维护者先记住的三件事
- 权威位置:站长向教程在
docs/user-guide/(主题统一在user-guide/themes/.md);docs/developer/themes/仅放开发者深度文档。 - 三处必同步:改一篇教程时,视情况更新 正文、README 目录、ARTICLE_INDEX(新建或废弃时还要动 MIGRATION_STATUS)。
- 与代码一致:环境变量名、配置键、默认值以
conf/*.config.js、blog.config.js、各主题themes/*/config.js为准;版本号以package.json为准。
二、文档放在哪(目录秩序)
| 你要写的内容 | 目录 | 文件名习惯 |
|---|---|---|
| 建站介绍、总流程 | docs/user-guide/ 根目录 |
intro.md、deploy-vercel.md 等短名 |
| 部署 / 域名 / 平台 | docs/user-guide/deploy/ |
平台或主题.md,如 netlify.md |
| 站点配置、URL、搜索 | docs/user-guide/config/ |
功能名,如 url-customize.md |
| Notion 使用技巧 | docs/user-guide/notion/ |
|
| 版本与更新说明 | docs/user-guide/changelog/ |
|
| 主题(站长向) | docs/user-guide/themes/.md |
26 篇;generate-theme-user-docs.mjs 刷新配置表;Proxio/Heo 含合并专题 |
| 主题(开发向) | docs/developer/themes/ |
仅 Claude、Endspace 等全局改动长篇;勿与站长文重复 |
| 4.9.x 配置 / Notion 能力 | docs/user-guide/reference/ |
features.md、notion-4x.md(改 conf/ 后必同步) |
| 统计 / 评论 / 挂件 | analytics/、comments/、plugins/ |
一篇一插件或一总览 |
| 开发、架构 | docs/user-guide/development/ + docs/developer/GETTING_STARTED.md 等 |
用户向写短,细节放 docs/ |
| 运营、SEO | docs/user-guide/operations/ |
|
| 社群、反馈、赞助 | docs/user-guide/help/ |
不要把站长教程写进 docs/developer/ARCHITECTURE.md;不要把架构细节塞进 user-guide 除非有简短说明并链到 docs/developer/。
三、读者阅读顺序(维护时不要打乱)
README.md 里 「快速开始」 的 1→6 步是推荐路径,新增总览类文章时不要插在这 6 步中间,除非确实属于入门必经步骤。
推荐读者路径:
intro → deploy-vercel → notion-database → config-site → menu-secondary → update栏目内顺序(README.md 各小节)建议保持:
部署 → Notion → 配置扩展 → 主题 → 统计/评论/插件 → 开发/运营 → 帮助 → 更新日志四、标准工作流(按场景)
场景 A:修正错别字 / 更新步骤(小改)
flowchart LR
A[编辑对应 .md] --> B{改动了标题或路径?}
B -->|否| C[提交 PR]
B -->|是| D[更新 README + ARTICLE_INDEX]
D --> C- 找到 ARTICLE_INDEX.md 中的本地路径。
- 修改正文;保留文首
> 迁移自:(若原本有)与文末 原文链接(若仍对应源站)。 yarn无需跑;文档 PR 建议docs(user-guide): 说明类 commit。- PR 描述写清:改了什么、是否已与当前
main配置一致。
场景 B:新增一篇站长教程
- 定目录:按 第二节 选子目录,文件名用 小写英文 + 连字符,如
deploy/xxx.md。 - 写正文模板(复制后填空):
# 标题
> 迁移自:[源站标题](https://docs.tangly1024.com/article/slug) · 最后同步:YYYY-MM
(正文:步骤用有序列表;配置用表格;命令用代码块)
## 相关
- 链到本仓库其它文档
## 原文链接
https://docs.tangly1024.com/article/slug- 更新导航(必做)
- 使用说明目录:在对应栏目下增加一条链接。
- ARTICLE_INDEX.md:增加一行
slug | 本地路径。 - MIGRATION_STATUS.md:若从「待迁移」变为已迁移,改状态表。
- 交叉引用:若涉及环境变量,在正文注明
NEXT_PUBLIC_*与conf/*.config.js中的键名。 - 提 PR:标题建议
docs(user-guide): add <主题>;说明是否对应旧站某 slug。
场景 C:代码新增配置项 / 功能
与功能 PR 同一 PR 或 紧跟的 docs PR 中:
- 在
conf/*.config.js加注释时,可写参阅 docs/user-guide/...。 - 在
user-guide中更新对应插件/配置文档(或config-site.md/config/site-basics.md)。 - 若影响升级路径,同步 update.md 或 changelog/latest.md。
- 破坏性变更必须在 changelog 与文档中显眼注明。
场景 D:主题新增或主题配置大改
- 站长向:在
docs/user-guide/themes/.md维护(运行node scripts/generate-theme-user-docs.mjs刷新配置表)。 - 仅当主题涉及全局文件 / 架构:在
docs/developer/themes/增补开发者文档,并在.md中加「开发者深度文档」链接(勿重复站长正文)。 - 更新 themes/overview.md 主题列表(与
themes/目录实际文件夹一致)。 - 更新 ARTICLE_INDEX.md。
场景 E:废弃或仅保留外链
- 正文顶部加说明:
> 已废弃:请使用 … - 不要删除文件时留下死链:全文搜索仓库内指向该文件的路径。
ARTICLE_INDEX移到「仅链到源站」或删除行并注明原因。README中移除或改为「已归档(见 xxx)」。
五、提交前检查清单(Checklist)
复制到 PR 描述或自检:
- [ ] 路径符合 docs/user-guide/ 目录约定
- [ ] README.md 已增加/调整链接
- [ ] ARTICLE_INDEX.md 已更新(新 slug / 新路径)
- [ ] 无 .env、Token、个人域名 ID、真实 API Key 示例
- [ ] 环境变量名与 conf/*.config.js 一致
- [ ] 版本号与 package.json / Releases 一致(若提到版本)
- [ ] 保留或更新了「原文链接」(若源自 tangly1024 文档站)
- [ ] 站内相对链接可点击(`./` 或 `../`)
- [ ] 未把开发者长篇文档重复粘贴到 user-guide六、注意事项(常见错误)
内容与安全
| 禁止 | 建议 |
|---|---|
提交真实 NOTION_PAGE_ID、Token、私钥 |
用 your-xxx、示例 |
| 写死已失效的第三方 URL | 链到官方文档,步骤写「以控制台为准」 |
与 main 分支配置键不一致 |
改文档前打开对应 conf/*.config.js 核对 |
结构与链接
- 一篇一主题:评论插件拆在
comments/,不要全部堆进一篇(除非做总览 + 子链)。 - 总览 + 分篇:
overview.md只写对比表和链接,细节在子页面。 - 勿重复主题正文:每个主题只维护一篇站长文档
user-guide/themes/.md;docs/developer/themes/PROXIO.md、HEO.md仅为重定向存根。 - changelog:超长历史放 changelog/v4-history.md + GitHub Releases,不要在
user-guide根目录贴几千行日志。
与旧站关系
- 过渡期保留 原文链接,方便对照截图。
- 本仓库为准:与源站冲突时,以 本仓库
main+ 当前代码 为准,并在 PR 中说明。 - 不要批量删除「迁移自」行,除非该文已为仓库原创、与源站无关。
PR 与协作
- 文档专用分支:
docs/xxx或docs/user-guide-xxx。 - 文档与功能分 PR 时,在功能 PR 中写
Docs follow-up: #xxx。 - 遵循 CONTRIBUTION_WORKFLOW.md(GitHub)(lint/test 对纯文档 PR 可选,但勿改无关文件)。
七、发布与后续(可选)
- 静态站规划见 WEBSITE.md(VitePress / Nextra)。
- 发版时:检查 changelog/latest.md 是否指向当前
package.jsonversion。 - Fork 用户:README 已指向
docs/user-guide/,他们合并 upstream 即可获得文档更新。
八、一分钟决策表
| 我想… | 去做 |
|---|---|
| 改部署步骤 | deploy/*.md + README |
| 改评论/统计配置说明 | comments/ 或 analytics/ + 核对 conf/ |
| 改 Proxio 顶栏 | docs/user-guide/themes/proxio.md |
| 改开发环境 | docs/developer/GETTING_STARTED.md,user-guide 只保留链接 |
| 不知道写哪 | 查 ARTICLE_INDEX.md |
| 新功能无文档 | 场景 B + C |
English summary
Maintain end-user docs under docs/user-guide/. On every add/change: update the article, README.md, and ARTICLE_INDEX.md. Match env var names to conf/*.config.js. Never commit secrets. Use the checklists in Section 5 before opening a PR.
User Guide MIGRATION STATUS (`docs/user-guide/MIGRATION_STATUS.md`)
官方文档迁移状态
源站:https://docs.tangly1024.com
目标:docs/user-guide/
状态:旧站导航中的 104 个页面已全部迁入本地 Markdown;正文、图片链接、原文 URL 与基础元数据已从 docs.tangly1024.com 的 NotionNext 页面数据导入。对照表:ARTICLE_INDEX.md。
已迁移(按栏目)
| 栏目 | 本地目录 |
|---|---|
| 入门 / 部署入门 | 根目录 intro.md、deploy-vercel.md 等 |
| 安装部署 | deploy/ |
| 站点配置 | config/、config-site.md |
| Notion 教程 | notion/、notion-database.md |
| 菜单 | menu-secondary.md |
| 更新日志 | changelog/、UPDATE.md(GitHub) |
| 主题 | themes/(含 THEMES_CATALOG.md);开发长文 docs/developer/themes(GitHub) |
| 网站统计 | analytics/ |
| 评论插件 | comments/ |
| 外部扩展 | plugins/ |
| 开发教程 | development/ + docs/developer/GETTING_STARTED.md 等 |
| 运营 | operations/ |
| 获取帮助 / 支持 | help/ |
内容刷新(4.9.x,仓库独有)
| 文档 | 作用 |
|---|---|
| reference/features.md | 与 conf/*.config.js 对齐的全站配置 |
| reference/notion-4x.md | 近年 Notion / 站点能力 |
| themes/THEMES_CATALOG.md | 26 主题说明与配置前缀 |
| changelog/latest.md | 4.9.5.x 要点(非复制 v4.0 全文) |
维护时:改功能 → 先改 conf/ → 再改 reference/features.md 与相关 user-guide 篇目。
特殊处理
| 原文 | 处理方式 |
|---|---|
v4.0 超长 changelog |
changelog/v4-history.md 索引 + GitHub Releases |
latest |
changelog/latest.md |
example-1 |
notion/example-article.md + 旧站原文 |
notion-tutorial |
付费课程外链 |
vercel-accelerate、vercel-redploy |
deploy/vercel-accelerate.md、deploy/vercel-redeploy.md |
旧站入口与评论
- 用户向导航:help/legacy-docs.md(slug 对照 + 旧站直达)
- 文档站页底:Giscus →
notionnext-org/NotionNextDiscussions(见 maintain-docs.md) - 维护者批量拉取:
node scripts/import-legacy-docs.mjs
维护
- 修改教程 → 编辑
docs/user-guide/**并更新 ARTICLE_INDEX.md - 策略说明 → ../DOCUMENTATION_POLICY.md
- 步骤清单 → MAINTENANCE_WORKFLOW.md
User Guide WEBSITE (`docs/user-guide/WEBSITE.md`)
文档静态网站
教程与开发文档通过 VitePress 构建,发布到 notionnext.tangly1024.com。
本地命令
| 命令 | 作用 |
|---|---|
yarn docs:site:dev |
本地开发预览 |
yarn docs:site:build |
构建 → .vitepress/dist |
yarn docs:site:preview |
预览构建结果 |
在线站包含的目录
docs/
├── index.md
├── DOCUMENTATION_POLICY.md
├── user-guide/ ← 使用教程
├── developer/ ← 架构、贡献、主题迁移与维护文档
└── community/ ← 社区材料除根目录 README 这类仓库目录说明外,文档内容尽量进入在线站。配置见 .vitepress/config.mts。
配置位置
.vitepress/config.mts— 导航、侧栏docs/index.md— 站点首页
User Guide Acknowledgements (`docs/user-guide/acknowledgements.md`)
致谢
NotionNext 能持续运行、修复和更新,依赖长期参与代码、主题、文档、Issue 复现、PR Review、答疑和发布维护的所有开发者与站长。
本页用于在文档站公开致谢这些维护工作,也作为新贡献者了解项目协作入口的页面。
贡献者名单
完整贡献者名单以 GitHub 自动统计为准:
感谢每一位提交代码、维护主题、修正文档、补充翻译、复现问题、优化 CI、回复 Issue / Discussions、参与发布流程的人。很多维护工作并不会体现在单个功能里,但它们决定了项目能否被更多站长稳定使用。
文档维护者
用户文档由社区共同维护,主要位于 docs/user-guide/。以下工作同样属于项目维护:
- 修正教程中的过时步骤、错别字和失效链接。
- 补充部署平台、主题配置、插件配置和故障排查说明。
- 将 Issue / Discussions 中反复出现的问题沉淀为可搜索的文档。
- 审阅文档 PR,保持目录结构和术语一致。
如果你更新了文档,合并后会出现在 docs 提交记录 与对应 PR 记录中。
主题与生态贡献
NotionNext 的主题系统来自长期社区共建。主题作者、迁移者和维护者的工作包括视觉实现、多端适配、配置项整理、预览图、文档和后续兼容性维护。
维护者与协作规则
长期维护者、仓库协作者和负责域以仓库治理文件为准:
如何加入维护
最推荐从小改动开始:修正文档、补充截图说明、复现 Issue、提交主题配置表修正,或认领 good first issue。
我们鼓励持续、小步、可验证的贡献。哪怕只修正一处教程,也是在帮助后来的使用者减少一次踩坑。
User Guide Community Participate (`docs/user-guide/community-participate.md`)
参与社区
NotionNext 已由个人仓库移交至组织 notionnext-org,欢迎既是站长又是开发者的参与者一起维护代码与文档。所有参与代码、主题、文档、Issue、Review 与发布维护的贡献者,都会在 致谢页 与 GitHub 贡献记录中被看见。
四步参与路径
1. 使用站点 / 读文档
↓
2. 提问(Discussions 或 Issue)
↓
3. 贡献(文档 PR 或代码 PR)
↓
4. 成为维护者(可选,认领负责域)1. 使用与阅读
- 在线文档:notionnext.tangly1024.com
- 快速开始:介绍 → Vercel 部署
- 旧版 Notion 教程:docs.tangly1024.com(历史截图)
2. 提问与讨论
| 场景 | 去哪里 |
|---|---|
| 部署/配置「怎么用」 | GitHub Discussions · 使用问答 |
| 某篇教程不清楚 | 该页底部 文档反馈(Giscus)或 Discussions · 文档 |
| 确认是 Bug | Bug Report Issue |
| 功能想法 | 先在 Discussions · 想法 对齐,再开 Issue |
技术问题优先 GitHub,便于搜索与志愿者接手。微信群/Telegram 见 交流社群(非官方 SLA)。
3. 报告 Bug 与 AI Agent 修复
报告 Bug 时,优先把三件事写清楚:
- 实际现象:现在页面或功能发生了什么。
- 期望现象:正常情况下应该是什么结果。
- 复现步骤:从哪个页面开始,点击什么,刷新或切换什么,最终如何触发问题。
如果问题已经能稳定复现,可以尝试交给 AI Agent 辅助修复,例如 Codex、Cursor、Claude Code、WorkBuddy 或其他支持自动读代码、改代码、提交 PR 的工具。NotionNext 仓库已经内置较多适合 AI 阅读的开发文档、维护手册和文档站 AI 助手指令,AI Agent 可以比较快地接入项目上下文。
推荐工作流:
- 在 Issue 中整理实际现象、期望现象和复现步骤。
- 让 AI Agent 先阅读
docs/developer/、docs/user-guide/中相关页面,以及仓库里的维护手册。 - 要求 AI Agent 从最新
main创建独立分支,不要在自己的站点分支上直接改。 - 让 AI Agent 先定位根因,再做最小修复,不要顺手重构或改个人配置。
- 跑最小必要检查,把命令和结果写进 PR。
- 提交 PR 后,在原 Issue 回复 PR 链接和验证结论。
可参考提示词:
根据我的 Bug 描述,创建一个新分支修复这个问题,然后提交 PR 到云端仓库。
要求:
1. 只修复这个 Bug,不要混入我自己站点的个性化配置或无关改动。
2. 在能修复相同问题的前提下,尽量改动最少的代码,降低对其他用户的影响。
3. 修复前先阅读项目内置的开发文档、维护手册和相关主题文档。
4. 保留必要的本地检查结果,并在 PR 描述中说明改动范围、风险和验证步骤。4. 第一次贡献(推荐从文档开始)
- Fork notionnext-org/NotionNext
- 编辑
docs/user-guide/**/*.md(或修复带good first issue的 Issue) - 本地预览:
yarn docs:site:dev - 按 CONTRIBUTING.zh-CN.md 提 PR
改代码 / 主题:阅读 开发者文档(GitHub) · 贡献指南 · 大改动先写 RFC(GitHub)
5. 成为维护者与加入组织
- 完成 1~2 个合并 PR 后,在 Discussions 自荐负责域(文档 / CI / 某主题等)
- 规则见 GOVERNANCE.zh-CN.md · 名单 MAINTAINERS.md
::: info 已符合条件但未被邀请?
若你已满足组织协作的合并 PR 等条件,却尚未收到组织邀请,请到 GitHub Discussions 发帖(可选用「组织成员申请」模板),标题写 组织成员申请,并附上 GitHub 用户名、已合并 PR 链接与希望负责的域。维护者会在讨论区按队列回复,邀请可能有延迟。
:::
行为与治理
当前最需要帮助的事
在仓库 Issues 中筛选 good first issue 与 help wanted,常见包括:
- 文档迁移、错别字与 4.9.x 配置说明同步
- 单主题说明或截图更新
- 翻译与
lib/lang补充
维护者会在 Discussions 置顶「欢迎贡献」帖;草稿见 PINNED_DISCUSSION_POSTS.zh-CN.md。
User Guide Config Site (`docs/user-guide/config-site.md`)
如何配置站点
迁移自:如何配置站点
发布日期:2024-5-13
最后编辑:2026-5-2
原栏目:🛠 站点配置
标签:NotionNext
摘要:如何配置NotionNext站点
按照前面的教程部署成功后,后续您可以随时更新您的站点配置,诸如切换主题、开启音乐组件、开启评论插件、开启动画特效、修改网站字体等等。
配置方式分为三种,分别是:
在Notion笔记中修改
Github修改配置代码
Vercel环境变量添加配置
以下展开说明
新手先看:固定主题并关闭主题切换
如果你只是想把网站固定成 simple 主题,并去掉页面上的“切换主题”按钮,优先在 Notion Config 表里添加:
THEME=simple
THEME_SWITCH=false
WIDGET_PET_SWITCH_THEME=false如果你使用 Vercel 环境变量,则添加:
NEXT_PUBLIC_THEME=simple
NEXT_PUBLIC_THEME_SWITCH=false
NEXT_PUBLIC_WIDGET_PET_SWITCH_THEME=false改完后重新部署一次。若部署后仍然不是 simple,先检查 Notion Config 表里是否已有其它 THEME 配置;Notion Config 会覆盖 Vercel 环境变量和 GitHub 代码默认值。
1. 在Notion中修改
网站的图标、标题、描述、封面图将直接读取您的Notion模板
::: tip 提示
在4.1 之前的版本(1.0 - 4.0) 中,很多配置需要到配置文件或环境变量里改,这需要用户打开编辑器或者登录github,乃至登录vercel后台编辑环境变量。
4.1版本之后,支持在Notion中创建一个Config文档,并且随时可以在Notion中编辑配置文件。
:::
使用Notion-Config
::: tip 提示
在Notion中编辑一个文档,即可实时同步站点配置,开关功能等等,无需登录github、vercel或者服务器。
:::
如何使用?
在您起初复制的这份数据库模板中,我后续更新了一个 type 为 Config 的文档,文档中包含了一个数据表格,格式如下:
配置中心使用说明
仅 V4.1.0 之后的版本中支持该配置页面
此处配置的优先级最高,它将覆盖Vercel环境变量、覆盖blog.config.js。
您可以在
blog.config.js以及各个主题的config.js中找到支持的配置,在4.8.0之后的版本,为了减少blog.config.js的体积,不同模块的配置被拆分到了/conf/xx.js中
各类配置的参考路径: https://github.com/notionnext-org/NotionNext/tree/main/conf
主题支持的配置内容参考路径: https://github.com/notionnext-org/NotionNext/blob/main/themes/example/config.js
NOTION_PAGE_ID必须在你的环境变量或代码中配置,不支持Notion_Config文档配置配置中心的表格中我预置了几个常用配置,您可以按照自己的需求手动添加更多配置
点击右上角的new或者左侧加号+都可以新增一行配置,然后填入对应的“配置名”和“配置值”强烈建议添加的配置
**AUTHOR**,作者名**LINK**,你的站点网址**CONTACT_EMAIL **, 你的联系邮箱,更多联系方式,在此查看配置方式: https://github.com/notionnext-org/NotionNext/blob/main/conf/contact.config.js
(务必配置你自己的联系方式!)
表格字段说明
支持主题配置与复杂格式
基本上所有的主题配置项都可以使用NOTION_CONFIG。但需要注意的是,如果配置的内容是一个数组或者对象的话,需要将NOTION_CONFIG中的内容转成双引号的json格式,否则会无法读取,例如HEO主题下支持四项配置:
// 以下三种配置分别代表布尔、普通字符、对象、数组四种类型。
HEO_HOME_BANNER_ENABLE: true,
HEO_SITE_CREATE_TIME: '2024-05-09',
HEO_HERO_CATEGORY_1: { title: '必看精选', url: '/tag/必看精选' },
HEO_NOTICE_BAR: [
{ title: '欢迎来到我的博客', url: '/user-guide/intro' },
{ title: '访问文档中心获取更多帮助', url: '/user-guide/intro' }
],这四种类型在Notion_Config中的参考配置如下,其中对象和数组都转成了json格式:
配置后的效果示例:
Built with Notion, the all-in-one connected workspace with publishing capabilities.
如何将代码中的Config转换成JSON?
如何将config中的对象转成json可以借助AI,或者一些在线json格式化工具。
老用户升级
对于新用户(2024年起):您复制的数据库模板中已经默认自带了此配置页面。
老用户升级(2023年及以前):您可以**复制下面链接中的《配置中心》**文档,即可支持NotionConfig功能。
Notion – The all-in-one workspace for your notes, tasks, wikis, and databases.
A new tool that blends your everyday work apps into one. It's the all-in-one workspace for you and your team
单击此文档左侧的六个点即可选中,按下Ctrl+C复制文档。然后在您的Notion模板页面中按下Ctrl+V粘贴即可。
2. 修改代码
::: tip 提示
重要:站点的大部分配置都可以在您代码仓库的 blog.config.js** **文件中找到;
您只需修改对应的配置,Vercel将自动部署您Github仓库中的最新代码。
:::
::: tip 提示
若您更新到了NotionNext4.1之后的版本,推荐您直接在Notion-Config文件中添加配置,它将覆盖blog.config.js中的配置。
:::
配置方法:在您的github中找到此文件,点击右上角的编辑按钮,即可修改参数。
::: tip 提示
每次修改代码后,Vercel自动创建一个部署任务以打包部署您的最新代码,且每次部署任务都有唯一的网址提供预览。
- 若编译成功:您的线上域名会更新为此次部署的最新版本。
- 若部署失败:例如代码格式错误、拼写错误,则这次部署则会作废,线上原先运行中的旧版网站不受任何影响。您可以查看后台部署日志找到错误原因。
附-如何获取部署日志
截图您的部署日志,向群友寻求帮助
1. 在Vercel的后台看到您的每次部署记录(点击展开)
1. 请截图部署的错误日志,错误信息越完整越好;:::
修改示例
以下示例修改了网站的默认作者
- 修改前
AUTHOR: process.env.NEXT_PUBLIC_AUTHOR || 'NotionNext', // 修改前 作者 NotionNext- 修改后
AUTHOR: process.env.NEXT_PUBLIC_AUTHOR || 'momo', // 修改后 作者 momo以下示例修改了当前网站的网址
- 修改前
LINK: process.env.NEXT_PUBLIC_LINK || '/user-guide/intro', // 修改前网址- 修改后
LINK: process.env.NEXT_PUBLIC_LINK || 'https://qq.com', // 修改后::: tip 提示
请将这项配置修改为您的站点域名,否则会影响分享和版权申明的功能使用
:::
3. 在环境变量中配置
除了直接修改代码配置blog.config.js ,也可以在vercel后台添加环境变量;这样做的好处是减少对代码的改动,也避免了后续升级时代码发生冲突的概率。
::: tip 提示
网站配置优先来自NotionConfig,其次环境变量,最后代码配置。
:::
内置主题名称一览(与仓库同步)
NEXT_PUBLIC_THEME / THEME 的取值需与仓库 [themes/](https://github.com/notionnext-org/NotionNext/tree/main/themes) 下的文件夹名一致(next.config.js 会在构建时扫描该目录)。以当前 main 分支为例,内置主题包括:claude、commerce、example、fukasawa、fuwari、game、gitbook、heo、hexo、landing、magzine、matery、medium、movie、nav、next、nobelium、opc、photo、plog、proxio、simple、starter、typography。
默认一般为 simple;与
blog.config.js中THEME的写法保持一致即可。example 多为主题/配置的参考示例,生产站点更常选用 simple、hexo、heo、fuwari、claude 等其它主题。
文件夹名为 magzine(与英文 magazine 拼写不同,请勿写错)。
各主题个性化选项与预览方式见文档 《⭐️主题配置》;若你本地或 fork 的
themes/与官方不一致,以实际目录为准。在
blog.config.js文件中可以看到类似process.env.NEXT_PUBLIC_THEME的格式,这意味着此类参数支持在Vercel中使用环境变量来配置。默认主题为simple;若需在页面上显示主题切换菜单,可在仓库conf/widget.config.js中配置THEME_SWITCH(可选用环境变量NEXT_PUBLIC_THEME_SWITCH)。
NOTION_PAGE_ID: process.env.NOTION_PAGE_ID || '02ab3b8678004aa69e9e415905ef32a5',
THEME: process.env.NEXT_PUBLIC_THEME || 'simple', // 默认主题(与仓库 blog.config.js 一致)
LINK: process.env.NEXT_PUBLIC_LINK || '/user-guide/intro', // 站点域名- 网站优先读取环境变量配置、其次是文件中的配置。
::: tip 提示
用后台环境变量配置的好处:有些敏感信息不适合直接在代码中修改,例如一些第三方插件的key,这时候推荐通过环境变量来配置。
:::
Vercel环境变量如何操作 (点击展开教程)
项目主页点击
Settings,并选择Environment Variables配置环境变量找到Setting → Environment Variables
在Key中填写配置名称,Value中填写配置的值,如下图:
环境变量修改后,点击顶部
Deployments标签,将列表中最上面的一条部署记录Redeploy即可(如下图)
修改示例
如何知道key?
在blog.config.js文件中可以看到大量的配置项,配置项中的类似 process.env.``**NEXT_PUBLIC_THEME**** **; 这样的结构中、加粗部分就是key的名字。例如以下配置表明当前仓库默认值主题为 simple(也可通过环境变量改为 hexo 等)。
THEME: process.env.NEXT_PUBLIC_THEME || 'simple', // 默认主题如果需要将主题变为 hexo,则可以添加如下环境变量:
获取key示例2
同样地,再以修改网站的联系邮箱地址为例,blog.config.js中修改邮箱地址的配置如下:
CONTACT_EMAIL: process.env.NEXT_PUBLIC_CONTACT_EMAIL || '' // 填写邮箱地址如果直接修改配置是这样的:
CONTACT_EMAIL: process.env.NEXT_PUBLIC_CONTACT_EMAIL || '[email protected]' // 填写邮箱地址若不想修改文件,只改环境变量,则添加以下环境变量即可
VPS本地部署如何操作环境变量
若您不是用vercel托管,而是在自己的服务器上部署,则可以直接在项目根目录的 .env.local 文件中添加环境变量即可:
# 环境变量 @see https://www.nextjs.cn/docs/basic-features/environment-variables
NOTION_PAGE_ID=xxxxxxxx
NEXT_PUBLIC_THEME=simple
NEXT_PUBLIC_LINK=http://xxx.com4. 不同主题的个性化配置
每个主题都有自己个性化的配置,例如Hexo这个主题首页有个专属的欢迎语
hi,我是一个程序员
这该如何更改?需要访问这个主题的说明文档,请参阅此文档教程的 《⭐️主题配置》部分
原文链接
https://docs.tangly1024.com/article/how-to-config-notion-next
User Guide Deploy Vercel (`docs/user-guide/deploy-vercel.md`)
Vercel 部署 NotionNext
迁移自:Vercel部署NotionNext
发布日期:2023-2-10
最后编辑:2026-5-2
原栏目:🚀 安装部署
标签:NotionNext、部署方案
摘要:Vercel是一款国外的Serverless托管平台,对个人用户使用几乎免费,而且方便快捷,用Vercel托管你的Notion站点,无需再操心服务器的维护与资费问题。
前言
遵循此教程您将在Vercel上免费搭建一个NotionNext博客。
::: info 问题
NotionNext是一个开源站点系统,可以把你的 Notion 内容发布为博客、作品集、知识库、导航站或产品官网。
Vercel是一个来自国外的在线脚本托管平台,对于个人使用,其免费版已经完全足够,因此您无需购买服务器即可搭建自己的网站。
:::
站点效果预览→:https://preview.tangly1024.com/ , 站点左下角图标点击可以体验主题切换:
想查看更多网站搭建效果,欢迎访问友情链接:https://blog.tangly1024.com/links
部署步骤
部署站点只需三步,分别是:
复制官方 Notion 模板
Fork 官方 GitHub 仓库
在 Vercel 中一键部署
部署文档已经过大量站长实践验证。若无法完成独立部署,先查看 获取帮助 中的社区支持和付费协助说明。
视频帮助
我录了一个1分38秒的简略视频,演示了整个部署过程,最终以文档为主。
另外有 YouTube 网友也分享了部署过程,可以参考:
text**将您的 Notion 笔记变为博客站,所有文章的编写发布都只在您的 Notion 笔记中完成** Maple Tech 分享的 NotionNext 建站与 Vercel 部署过程。 <small>youtube.com/watch?v=zWlPyDQCkrk</small>text**零基础入门 NotionNext 网站搭建、个人博客、网站快速搭建部署教程** 404 实验室分享的零基础 NotionNext 网站搭建教程。 <small>youtube.com/watch?v=AbI70b9KfXE</small>
一、创建您的Notion页面
复制模板
请先注册登陆您的Notion账号。
点击下方链接,打开模板
Notion Blog
一个NotionNext搭建的博客
- 在右上角点击Duplicate复制模板,如图所示。点击后会将这个博客数据模板复制到您的笔记空间中。
获取页面ID
- 在Notion笔记中:在页面右上角的菜单栏中,依次点击Share→Published→Share To Web,开启页面分享,获取共享链接
- 如下图所示,点击右上角 **Share ,**在弹出窗口中点击 **Publish **→ Share to web (点击展开截图)
- 复制页面ID
页面ID在您的共享链接中、域名中间的一串32位字母与数字。
如下图所示:
页面ID注意
如何识别页面ID
页面 ID 是 Notion 共享链接中那段连续 32 位的字母和数字。只复制这 32 位字符串即可,不要复制
?v=、?pvs=以及它们后面的参数。示例一:
https://www.notion.so/tanghh/02ab3b8678004aa69e9e415905ef32a5?v=b7eb215720224ca5827bfaa5ef82cf2d这里的页面 ID 是:
02ab3b8678004aa69e9e415905ef32a5示例二:新版 Notion 可能会把页面标题放进链接里,例如:
https://www.notion.so/tanghh/Today-261c36d269a74acd97682af86d7bc9a0?pvs=4这里的页面 ID 是:
261c36d269a74acd97682af86d7bc9a0
请将您的页面ID记录下来,步骤三配置环境变量时会用到。
二、复制源代码
::: tip 提示
注意,请不要使用qq邮箱等国内邮箱,尽量使用hotmail或gmail等国际邮箱,否则下一步登陆vercel后会提示账号被封禁。
:::
请先注册并登陆Github账号,
仅需点击下方链接,即可一键 Fork(复刻) 官方项目。
Fork NotionNext
三、Vercel部署
准备账号
注册登陆Vercel ,这里推荐选择Github账号登录。
注册vercel账号可能遇到的问题
若注册时提示 Error:This user account is blocked.Contact [email protected] for more information.
这是由于 Vercel 不支持大部分国内邮箱。可以将 github 账号主邮箱改为 Gmail 邮箱。
但是根据群友反应,将 github 账号主邮箱切换为 Gmail 以后,Vercel 又会提示需要使用手机号码验证。然而 github 并没有提供手机号码绑定的内容。
综上,建议一开始注册 github 账号时就使用 Gmail 等国外邮箱进行注册。
- 国内访问
Gmail的方案:
- 直接使用 QQ 邮箱手机版,它提供
Gmail的访问路线,可以直接注册并使用。使用Ghelper等浏览器插件访问。详情可以参考这篇文章:玩转 Microsoft-Edge
- 若是执着于当前
Github账号,可以参考以下方案进行尝试:
- 完成了
Gmail等国外邮箱的注册,打开 github-> 头像 ->settings->Emails>Add email address, 并完成邮箱验证。在Add email address 下方的Primary email address 选项中将Gmail设置为主邮箱。
导入代码
- 点击下方创建新项目
New Project - Vercel
To deploy a new Project, import an existing Git Repository or get started with one of our Templates.
- 在代码仓库列表中选择导入NotionNext
::: tip 提示
注意:这里步骤放慢些,不要急着点击页面上的Deploy按钮,先看下方教程。
:::
配置页面ID并部署
- 点击Environment Variables(环境变量),并添加一个属性名称为
**NOTION_PAGE_ID**,值为步骤一获取的页面ID。
例如,我的页面ID是:02ab3b8678004aa69e9e415905ef32a5,则配置如下:
填写后要点击右边的**Add****按钮**确认添加
- 点击
Deploy按钮,静候两分钟等待部署。
可选:开启 Fluid Compute
NotionNext 默认兼容未开启 Fluid Compute 的 Vercel Hobby 项目,部署时无需为此更改设置。若希望 Vercel Functions 复用运行实例、改善冷启动并提升并发处理能力,可在项目的 Settings → Functions → Fluid Compute 中开启,然后重新部署使设置生效;也可在 vercel.json 显式设置 "fluid": true,将选择随仓库配置。两种方式选其一即可。
Fluid Compute 是可选的性能优化,不是 NotionNext 的部署前提。不开启时,Hobby 旧计算模式的函数时长上限为 60 秒;NotionNext 的缓存维护函数兼容此限制,/api/revalidate 每批运行约 45 秒后通过 HTTP 202 和 remainingPaths 续传。开启后 Hobby 函数时长上限为 300 秒,Fluid Compute 可优化函数实例复用与并发,但 NotionNext 仍采用较短批次预算以便及时返回续传结果。其他套餐的限制请以 Vercel 当前方案文档为准:Functions 最大执行时间、Fluid Compute。
四、完成🎉🎉🎉
在部署完成页面,点击
Go to Dashboard访问控制台在控制台右上角的
Visit按钮访问您的站点。或在DOMAINS中获取您的网站地址
注意事项
::: tip 提示
NotionNext会实时抓取Notion笔记内容
(由于缓存和网络延迟,最多刷新两次页面即可看到同步结果)。
:::
::: warning 注意
若您的站点始终无法同步笔记的数据,请再次检查上面的步骤,或者干脆重来一遍:
- 在Notion中检查您的
NOTION_PAGE_ID格式是否正确、并已开起页面分享。 - Vercel后台环境变量中
NOTION_PAGE_ID是否配置,并重新配置后尝试Redeploy。
如何检查Vercel后台环境变量配置:
如何重新部署
:::
自定义您的站点
到这里,您已拥有了自己的独立博客,站点的一切内容:标题、描述、头像、菜单栏等所有配置都可随心所欲地定制。
接下来,请访问下方的《NotionNext 操作手册》获取更多站点配置的帮助!
NotionNext-快速免费搭建网站 | NotionNext文档
无需服务器、即使是小白也能几分钟搭建自己的独立博客站~如果你在使用Notion这款神级笔记本的话,不妨来试试顺手建个网站🤣🤣🤣,这是一款基于NotionAPI的博客系统。
原文链接
https://docs.tangly1024.com/article/vercel-deploy-notion-next
User Guide Maintain Docs (`docs/user-guide/maintain-docs.md`)
参与维护在线文档
第一次参与?先看 参与社区(提问、PR、维护者路径)。
在线文档站:https://notionnext.tangly1024.com
源码与 GitHub 上的 Markdown 一一对应;改仓库 → 合并 main → 自动发布。
每一次文档修正都会帮助后来的站长少踩一次坑。参与维护文档的开发者会出现在 文档提交记录 与 致谢页 中。
改当前这一页
任意教程页底部有 「在 GitHub 上维护此页」,直达该文件的编辑界面。
浏览文档目录
| 链接 | 说明 |
|---|---|
| docs/ | 目录说明(本 README 在 GitHub 可见) |
| docs/user-guide/ | 使用教程、主题配置、运营与维护 |
| docs/developer/ | 架构、贡献、主题迁移与维护文档(在线站可见) |
推荐流程(贡献者)
- Fork notionnext-org/NotionNext 或具备组织仓库写权限。
- 编辑
docs/user-guide/**/*.md或docs/developer/**/*.md(主题配置表可运行node scripts/generate-theme-user-docs.mjs)。 - 本地预览:
yarn docs:site:dev。 - 提交 PR,合并
main后由 GitHub Actions 部署。
代码 PR 也要检查文档
代码改动只要影响站长使用方式,就应该同步更新文档。常见场景包括新增或修改主题配置、环境变量、Notion Config 键、插件开关、部署步骤、默认行为和可见 UI 交互。
PR 模板中的“用户文档不适用”只适合内部重构、测试、CI、依赖维护、拼写修正等不改变使用方式的改动。新增用户可配置项时,请至少补充对应主题或配置文档,并在 PR 描述里说明文档位置。
详细检查清单:MAINTENANCE_WORKFLOW.md · 策略:DOCUMENTATION_POLICY.md
部署原理(简述)
push main(docs/user-guide/ 等变更)
→ GitHub Actions: yarn docs:site:build
→ .vitepress/dist → Cloudflare Pages与旧版在线手册
docs.tangly1024.com 为历史 Notion 托管;以 docs/user-guide/ 与 notionnext.tangly1024.com 为准。
- slug 对照与旧站直达:help/legacy-docs.md · ARTICLE_INDEX.md
- 可选批量拉取旧文:
node scripts/migrate-legacy-docs.mjs --slug <slug>(加--images下载图片到docs/public/legacy/)
文档站评论(Giscus)
每篇教程页底可显示 文档反馈(Giscus → 仓库 notionnext-org/NotionNext 的 GitHub Discussions)。
当前复用仓库默认分类 General(可在 Discussions 查看):
| 变量 | 值(公开 ID,非密钥) |
|---|---|
VITE_GISCUS_REPO_ID |
R_kgDOGHdxTw |
VITE_GISCUS_CATEGORY_ID |
DIC_kwDOGHdxT84CBR2I |
GitHub Actions:已在组织仓库 Secrets 中配置上述两项(构建 workflow 会自动注入)。
本地预览:复制根目录 .env.docs.example 为 .env.local 后执行 yarn docs:site:dev。
Cloudflare 直连构建:若不用 Actions,在 Pages 环境变量中写入同上两项。
可选 VITE_GISCUS_ENABLED=false 关闭评论区。未配置 ID 时页底仅显示 Issue 链接。单页 frontmatter:comments: false。
User Guide Menu Secondary (`docs/user-guide/menu-secondary.md`)
菜单管理-二级菜单
迁移自:菜单管理-二级菜单
发布日期:2023-3-23
最后编辑:2024-7-2
原栏目:🛠 站点配置
标签:NotionNext
摘要:NotionNext 3.13.0上线,支持更灵活的菜单配置
菜单功能
在NotionNext 3.12 之前的旧版本中,网站的菜单栏由Page控制。
类型为
Page的文章,不会展示在博文列表,而是在导航栏中出现菜单入口。
这一旧方案有两个弊端:一是若想关闭自带菜单,例如分类、归档、搜索,旧需要修改配置文件,很不方便;另一个弊端是,此方案若要实现二级下拉菜单显得力不从心。于是本文的自定义菜单Menu方案诞生了。
新菜单效果
所有菜单都在您的Notion中自定义,旧的Page菜单将被完全覆盖。同时、系统自带的主页分类、归档、搜索等按钮都需要您自行配置。
开始
首先,请更新您的NotionNext至3.13.0以上版本;访问升级指南或在交流群寻求帮助。
NotionNext升级指南 | TANGLY’s BLOG
当NotionNext发布新版后,如何更新你的项目?
其次,在您的blog.config.js中,开启完全自定义菜单:
**CUSTOM_MENU**: process.env.NEXT_PUBLIC_CUSTOM_MENU || true, // 支持Menu 类型当该值为true时,原先读取Page生成菜单的功能将被自定义菜单覆盖。
::: tip 提示
老版本推荐在环境变量中配置;4.0以后得版本可以在Notion_Config中设置: ‣
:::
添加普通菜单-`Menu`
在notion中添加一个类型为Menu的页面:并包含以下字段
示例配置
添加子菜单-`SubMenu`
子菜单绑定方法:在列表中,SubMenu紧跟在Menu后面即可做为子菜单。
子菜单3点注意:
⚠️
**Menu**后面一旦挂载了**SubMenu**,则此**Menu**就无法点击跳转,只能作为展开菜单使用。⚠️只有普通菜单
Menu后能挂子菜单SubMenu;Menu不能挂Menu、SubMenu不能挂SubMenu;SubMenu若没有紧跟在一个Menu后面,则成为孤儿菜单,不会显示。
::: tip 提示
提示: 菜单的路径分为相对路径和绝对路径;请使用绝对路径。
:::
::: tip 4.10.9 更新
如果菜单 slug 指向一个 status=Invisible 的隐藏页面,NotionNext 会优先使用该隐藏页面最终生成的 href。这适合把“隐藏页面”作为菜单入口背后的真实内容页,同时仍避免它出现在首页、归档、RSS、Sitemap 和搜索索引里。
未发布的 Draft 页面不会因为同名菜单而被公开;如果只是想跳转到外部链接或手写路径,继续在 slug 中填写完整路径即可。
:::
/about 这是一个绝对路径,它以左斜杆/开头,在博客的任意页面点击此菜单都会跳到 http://域名/about 该路径。
about 这是一个相对路径,它没有左斜杆/开头,如果在博客首页点击菜单会跳到 http://域名/about 该路径,然如果在 其它页面,例如 http://域名/tag/标签 这个页面下,点击菜单,会跳到 http://域名/tag/标签/about ,这会导致你的页面访问错误。
参考配置
可参考我的notion模板进行配置:
特别注意
::: tip 提示
Menu,SubMenu 这两个类型本质只是菜单,唯一功能是跳转到slug指定的页面,指定页面可以是任意page\post\外链; 但Menu和SubMenu本身不应该放文章内容。
:::
::: tip 菜单图标4.10.9 修复了 Claude、Typography、Game、Nobelium、Plog 等主题中菜单或子菜单图标缺失的问题。若你在 Notion 菜单数据里配置了 Font Awesome 类名,例如 fas fa-home,升级后这些主题会按菜单项自身的 icon 字段显示。
:::
::: tip 提示
特别提醒:
在V3.13版本中 ,不要在您的数据库中添加多个视图,这将会导致您的菜单乱序。如需添加视图以便分类整理文章,建议另外新建一个视图单页,参考下文: https://github.com/notionnext-org/NotionNext/issues/1056
:::
在V4.0之后的新版本可以忽略此问题。
关于菜单的使用方式示例
::: info 说明
notion中添加Menu类型数据,将仅作为跳转功能使用,menu的slug字段将指定跳转的路径,而menu这条数据的页面内容没有任何实际作用。
:::
Menu的五种使用示例:
Menu菜单总共可以有五种用法,下面是每一种用法的示例,表格第一列是这种用法的称呼,右边两列分别是 title、slug两个值的示例,最右一列是说明。
关于菜单缓存
NotionNext为每一个页面都单独做了缓存,如果改动了菜单,即使刷新首页,让新菜单生效;但其它每个文章页面的菜单仍然是旧的版本,只有但用户访问了一次其他页面,会出发刷新缓存,再次访问就是新的菜单。
如果嫌每个页面都要刷新很麻烦,则可以在vercel后台直接redeploy,彻底清除所有缓存。
原文链接
https://docs.tangly1024.com/article/notion-next-secondary-menu
User Guide Notion Database (`docs/user-guide/notion-database.md`)
Notion数据库的使用
迁移自:Notion数据库的使用
发布日期:2023-6-27
最后编辑:2024-9-4
原栏目:✒ Notion教程
标签:Notion
摘要:数据库的每一列有不同的功能;
第一列type表是文章的类型 ,有 post、page、menu这几种类型,post表示博文列表、page表示单独页面、menu是菜单。
第三列summary 是文章摘要,只有post会用到,显示在文章列表中
第七列 slug ,在menu中表示跳转到那个页面, 在post和page中表示 这篇文章在博客中的访问地址。
基本操作
如何进行写作?
将鼠标指向数据库表中的title这一栏,会浮现一个OPEN的按钮,点击即可查看编写文章;点击右上角的蓝色NEW按钮创建新文章。
如何排序或置顶文章?
Notion数据库支持手动拖拽排序,鼠标选停在表格的左侧会出现六个点构成的按钮,并提示“Drag to move”,此时即可拖动文章进行排序。
Notion数据库说明
在部署NotionNext项目时,您必须复制我提供的Notion数据库,这个数据库预先填充了以下字段:
4.10.9 之后的兼容性说明
Notion 自身会不断调整数据库块的内部类型。新版 NotionNext 已兼容以下场景:
- 配置库既可以是旧的
collection_view,也可以是新版页面数据库常见的collection_view_page。 - 页面正文中包含数据库视图、HTML 块、Tabs 块或空内容块时,不会因为
content is not iterable这类异常中断构建。 - 文章纯文本摘要和目录会跳过无法安全展开的特殊块,优先保证页面能正常生成。
如果升级后发现配置没有生效,优先检查:
- Notion Config 数据库是否仍在主页面内容中,而不是被放进未公开页面。
- 配置库里的
key、value、enable字段名称是否和模板一致。 - 部署记录是否已经使用包含
4.10.9的最新提交。
Notion进阶教程
::: tip 提示
Notion是一个能让效率暴涨的生产力引擎,可以帮你书写文档、管理笔记,搭建知识库,甚至可以为你规划项目、时间管理、组织团队、提高生产力、还有当前最强大的AI技术加持。
:::
如果希望进一步探索Notion的功能,可以尝试《Notion All in One 搭建高能效率系统》课程
原文链接
https://docs.tangly1024.com/article/start-to-write
User Guide Showcase (`docs/user-guide/showcase.md`)
用户作品墙
这里收集使用 NotionNext 搭建的真实站点,帮助新用户按场景选择主题,也让更多人看到社区成员的作品。
作品征集活动
如果你已经用 NotionNext 搭好了网站,欢迎把站点提交到这里。
提交作品可以帮助:
- 让更多人看到你的博客、作品集、知识库、产品官网或导航站。
- 帮助新用户参考真实案例,少在主题选择上反复试错。
- 让维护者知道哪些主题和场景被真实使用,后续优先补文档、截图和模板。
无需写长文,提供站点链接和使用主题即可。
如何提交
在 用户作品征集帖 回复,或直接提交文档 PR 修改本页,提供以下信息即可:
| 字段 | 说明 |
|---|---|
| 站点名 | 公开展示的名称 |
| 站点链接 | 可访问的公开 URL |
| 用途 | 博客、作品集、知识库、产品官网、导航站等 |
| 主题 | 使用的 NotionNext 主题 ID,例如 simple、gitbook、starter |
| 提交人 | GitHub 用户名或站点作者名 |
站点列表
| 站点 | 用途 | 主题 | 提交人 |
|---|---|---|---|
| NotionNext 主题预览站 | 主题预览 | 多主题 |
NotionNext |
| Tangly Blog | 个人博客 | magzine |
@tangly1024 |
| 茉灵智库 | 个人博客 | heo |
@88lin |
| Cloud09_Space | 个人空间 | endspace |
@cloud09 |
推荐格式
| [站点名](https://example.com) | 个人博客 | simple | @yourname |只收录公开、合法、能正常访问的站点。维护者可移除失效链接、违法内容或明显与 NotionNext 无关的提交。
User Guide Start Here (`docs/user-guide/start-here.md`)
从这里开始
如果你第一次接触 NotionNext,不需要先读完整文档。按下面路线走,先把站点跑起来,再逐步配置主题、域名和运营功能。
你属于哪一类?
| 身份 | 你最关心的事 | 建议入口 |
|---|---|---|
| 技术小白 | 能不能照着步骤搭好,不写代码 | 20 分钟部署路线 |
| 内容创作者 | 写作是否仍在 Notion,网站是否好看 | 按目标选择模板 |
| 潜在用户 | NotionNext 和普通博客、Notion 公共页有什么区别 | 首页介绍 |
| 开发者 | 源码结构、配置项、主题扩展是否可控 | 开发者路线 |
| 社区贡献者 | 如何反馈问题、补文档、贡献主题 | 参与社区 |
20 分钟部署路线
1. 先看效果
打开 主题预览站 看最终效果。左下角可以切换主题,先确认你想要的是博客、文档、作品集、官网还是导航站。
2. 复制 Notion 模板
NotionNext 以 Notion 数据库作为内容源。你需要先复制官方模板,然后在自己的 Notion 空间里维护文章、分类、标签、封面和菜单。
继续阅读:场景模板入口 · Notion 数据库的使用
3. Fork 项目代码
Fork GitHub 仓库后,你拥有自己的站点源码。后续配置、主题、插件和部署都在自己的仓库里完成。
4. 一键部署到 Vercel
新手优先使用 Vercel:流程简单、免费额度够用、文档案例最多。
继续阅读:Vercel 部署 NotionNext
5. 选择主题
部署成功后,再根据站点目标选择主题。不要一开始就陷入所有配置项;先选对主题,后续配置会轻很多。
继续阅读:按场景选主题
6. 补齐运营能力
上线后再逐步配置:
- 独立域名:Vercel 绑定自定义域名
- 站点基础信息:配置站点
- 评论系统:评论插件说明
- 访问统计:站点统计相关
- 搜索引擎收录:搜索引擎收录
开发者路线
如果你已经会前端或想深度定制,建议从这些页面开始:
常见疑虑
不会代码能不能用?
可以。最小路径是复制模板、Fork 仓库、Vercel 部署、填写环境变量。后续只在 Notion 中写文章,也能持续更新站点。
为什么不用 Notion 公共页面?
Notion 公共页面适合分享单页内容;NotionNext 更适合长期运营独立站。你可以使用自己的域名、主题、SEO、评论、统计、搜索和更多插件。
内容会不会被锁死?
Notion 是内容源,GitHub 仓库是站点源码,部署平台只是托管层。你可以备份 Notion、迁移 Markdown、切换主题或更换部署平台。
先看哪三篇就够?
User Guide Templates (`docs/user-guide/templates.md`)
场景模板入口
如果你还不知道从哪种站点开始,先按目标选择模板路线。当前先复用官方 Notion 基础模板,再通过主题和少量配置变成不同类型的网站。
官方基础模板:Notion Blog
按目标选择
| 目标 | 推荐主题 | 先改什么 |
|---|---|---|
| 个人博客 | simple、hexo、next |
站点标题、作者信息、文章分类、菜单 |
| 知识库 / 文档站 | gitbook、claude |
菜单层级、文档分类、首页说明 |
| 作品集 / 个人品牌 | proxio、opc、starter |
个人介绍、作品案例、联系方式 |
| 产品官网 / SaaS 落地页 | starter、landing、commerce |
产品标题、功能区块、价格或 CTA |
| 导航站 / 资源聚合 | nav |
链接分类、资源描述、导航菜单 |
最小上线步骤
内容源说明
NotionNext 的内容源是 Notion。文章、页面和菜单先在 Notion 模板里维护,GitHub 仓库主要负责代码、配置和部署。
如果你的目标是直接在 GitHub 里写 Markdown 文章,NotionNext 不是最短路径;这种需求更适合 GitHub Pages 或其他 Markdown 博客。
个人博客路线
适合:个人写作、技术笔记、生活记录和长期内容沉淀。
先改这几处:
- 站点标题、作者名和头像。
- 首页菜单,只保留首页、归档、分类、关于。
- 3-5 篇示例文章,覆盖你的主要写作方向。
推荐主题:simple 适合快速上线,hexo 和 next 适合更传统的博客样式。
知识库路线
适合:教程文档、学习笔记、项目手册和产品帮助中心。
先改这几处:
- 菜单层级,先控制在 2-3 层。
- 首页说明,写清楚这个知识库解决什么问题。
- 文档分类,每类先放 2-3 篇核心页面。
推荐主题:gitbook 适合文档目录,claude 适合更轻的知识整理。
先不要一次打开所有插件。评论、统计、搜索、广告、邮件订阅都可以等站点跑通后再补。
User Guide Update (`docs/user-guide/update.md`)
NotionNext-升级教程
迁移自:NotionNext-升级教程
发布日期:2022-6-2
最后编辑:2025-1-21
原栏目:✨ 更新日志
标签:NotionNext、升级教程
摘要:当NotionNext发布新版后,如何更新你的项目?
::: tip 提示
4.8版本加入一些新的功能和配置,同时大量调整了配置文件,更新时blog.config.js文件会发生大量冲突,请小心驾驶。
推荐做法是:备份所有原先的文件(下载保留或拉另一个分支备份),或者迁移到NOTION_CONFIG等方式,会后在更新时选择放弃你的原有代码,从而确保代码一致性。版本同步一致后,再参考您的备份文件进行重新配置。
:::
前言
通过此文档您将学会如何将NotionNext升级至最新版本,参考此文档您可以完成整个项目的升级。
若您实在无法独立完成可以参考文末的求助方式。
版本号说明
请按需更新你的版本,每个版本由三位数字的版本号构成,例如某个版本号 4.7.13, 它的含义如下:
第一位: 4 大版本升级,架构调整时,此数字会增加,目前表示第4代: 通常整体重构对代码的更新影响比较大,需要谨慎备份与操作。
第二位: 7 新功能、新特性等调整后会修改此数字,目前是第7次新增功能:添加新功能后blog.config.js或者主题的config.js文件会有些变化,可能带来冲突,因此也需要谨慎备份与更新。
第三位: 13 微小功能调整,修复bug的补丁,13代表打了13个补丁:
版本历史
本项目在长期维护更新中,不时将修复一些bug和增加新特性。新版本中对页面样式以及加载速度都做了大量的优化,因此推荐您更新到最新版。
您可以在NotionNext的Github仓库右上角点击Star,以便关注项目动态,您将第一时间收到新版本发布的消息。
访问以下文章可以查看版本更新记录:
NotionNext教程
4.11.0 升级提示
4.11.0 包含两项不兼容变更,升级前请先确认:
- 调用
/api/cache清理缓存的脚本,需要在部署平台配置CACHE_REVALIDATION_TOKEN,并在请求头携带Authorization: Bearer <令牌>;未配置时接口返回 503。详见 数据缓存与页面重建。 - 使用 Notion OAuth 授权的站点,必须从本站
/api/auth/notion发起授权。详见 Notion OAuth 授权入口。
另外,默认不再加载第三方中文 Web Font,之前为解决图片过期而设置 API_BASE_URL=https://www.notion.so/api/v3 的站点升级后不再需要该设置。其余普通站点同步最新 main 后重新部署即可。完整发布说明见 最新版本更新日志。
4.10.10 升级提示
4.10.10 是一次小版本维护发布。普通站点同步最新 main 后重新部署即可,不需要新增必填环境变量。
如果你希望 Notion 文章中的未收录内嵌子页面 URL 跟随父级文章路径,推荐在 Notion Config 配置中心添加:
Key: INNER_PAGE_URL_PARENT_PATH
Value: true该方式不需要修改代码。也可以在部署平台添加环境变量:
NEXT_PUBLIC_INNER_PAGE_URL_PARENT_PATH=true开启后,文章 /article/fpga-studying-notes 中未收录的子页面链接会显示为 /article/fpga-studying-notes/{pageId}。已收录到数据库并配置了 slug 的页面仍优先使用自己的正式地址。
使用说明见 URL 自定义:内嵌子页面跟随父路径,完整发布说明见 最新版本更新日志。
4.10.9 升级提示
4.10.9 是一次小版本维护发布。普通站点同步最新 main 后重新部署即可,不需要新增必填环境变量。
建议升级后重点检查:
- 首页和菜单是否仍能正确读取 Notion Config;新版已兼容 Notion 的
collection_view_page配置库块。 - 含有数据库视图、HTML 块、Tabs 块或同步块的文章是否可以正常构建和打开。
- 自定义菜单如果指向隐藏页面,目标页面可以设为
Invisible,菜单会跳转到该页面真实生成的地址。 - 使用 Matery、Claude、Typography、Game、Nobelium、Plog 等主题时,检查移动端标签、分享栏、菜单图标和加密文章提交按钮。
如果你的 fork 很久没有同步,仍然推荐先备份 blog.config.js、主题配置和自定义代码,再执行 Sync fork。
关于代码备份
如果你的代码做了大量自定义的改动,我建议备份你的代码,避免日后操作时误操作删除了代码。如果你只是很小的样式微调,例如所有的样式和配置都在NotionConfig中设置,而非改动源代码,则无需关注此部分文章:
最简单的方法是下载备份有一个完整的备份
如果出现更新过程不小心覆盖了自己的代码,还可以通过vercel还原,vercel每次更新都会拉取一次你的代码版本,并针对此版本进行编译打包和部署,每一次部署都留有完整的代码备份。
可以在这里找到:
打开项目→点击Deployments
找到你的合适的旧版本部署记录,点击右侧三个点,再点击viewsource,下图中我任选了一个两天前的部署记录:
这里面就是当时编译时的源代码,逐一查找即可:
当然,你可以直接点击此处的右上角,将直接跳转到这个版本在Github中的快照:
跳转后这里显示的都是当时打包的代码备份,这里的4400400就是当时的快照版本号。
简单更新方法
当您的代码版本落后于NotionNext最新版时,项目右上角将会出现一个更新按钮,这个按钮可能会有三种情况:
显示
Fetch upstream按钮,点击并选择Fetch and merge即可更新为最新的代码。显示
Sync fork按钮,点击并选择Update branch按钮,即可自动更新。
::: tip 按需开启自动同步
NotionNext 默认不再每天自动运行 Upstream Sync,避免 fork 站长在同步失败时反复收到 GitHub Actions 邮件。
平时建议使用上面的 Sync fork 按钮手动更新。只有你确实希望仓库每天自动同步上游时,再打开 .github/workflows/sync.yaml,在 on: 下加入:
schedule:
- cron: "0 0 * * *"保存并提交后,GitHub Actions 会恢复每日自动同步。若后续又收到失败邮件,删除这段 schedule 即可恢复为手动更新。
:::
::: warning 旧自动流程导致 Vercel 构建失败
如果 Vercel 里出现 chore(release): bump package.json ... [skip-version] 之类的失败记录,通常是旧版自动更新流程触发了无意义的生产重建。
先恢复线上站点:进入 Vercel 项目 Deployments,找到最近一条绿色 Ready 的 Production 记录,点击右侧 ...,选择 Promote to Production 或 Redeploy。
再处理根因:同步最新 NotionNext 代码。本仓库已默认关闭 Upstream Sync 定时任务,并让 Vercel 跳过 [skip-version] 版本号提交,减少自动流程对站长的打扰。
:::
- 没有上面两种情况的按钮,这种情况下大概率是因为修改了相同部分的代码导致冲突,需要手动确认才能合并,请看下文。
出现冲突
当我和你的代码发生冲突(confilcts),(例如我修改了blog.config.js文件,你也修改了此文件),导致在更新时,Git需要人工确认要合并代码时需要保留的最终代码版本。
这里的弹框按钮具体内容有挺多情况,其中一种是这样,显示 Disard xx commits 或者 open pull request.
Discard xx commits的意思是放弃修改的代码,这样就可以消除你与我的代码冲突,然后就可以点击update更新。点击此选项请注意备份自己在代码中修改的配置。Open Pull Request非专业人士请勿点击此项。它意味着你希望将你修改的功能或者修复的bug,提交到NotionNext的中央仓库,简称**PR(贡献代码)****,**我会审核你的提交内容,如果审核通过将会在新版本中发布。
带有冲突的更新
目前可以有以下几种方式更新。
备份并完全覆盖
备份自己改动的配置文件 例如 blog.config.js ,以及主题 /themes/xx/config.js
然后点击放弃xx次提交, 点击 Discard 21 commits,表示放弃自己的修改,
然后就可以正常更新, 点击Update branch,页面上方出现一个蓝色的提示横幅,告诉我已经成功更新。
更新后,按照之前备份的配置文件,重新配置
重头再来
若你并不是熟悉Git的操作,推荐做法是备份一下您的代码,诸如blog.config.js配置文件,然后重新fork一遍项目,再更新新版本中的配置项,重新配置即可。
所有文章数据都存在你的notion笔记中,此处重新部署的速度其实很快,无需太多配置。找我帮忙
::: warning 注意
这个不是免费的,不然我根本忙不过来😭
由我帮你合并最新的代码,并将更新后的版本用推送的方式发到您的仓库中,收到推送后您只需要按以下步骤,点击3个按钮即可完成升级:点击推送给你的页面链接,然后找到底部的 Merge pull request按钮;
在弹出的选择框中,选择第一项:Create a merge commit;
然后再次点击Confirm Merge 确认接口
此时站点已经开始自动升级,您只需要稍等片刻,或者到vercel后台督促一下部署记录。
⚠️
操作方式,联系小助理告知”代码付费升级“,定价是¥**9.9/**次。
:::
NotionNext更新冲突?网上教程还要VS code和git?通通不需要,马上解决冲突!
047 一种更新NotionNext版本的简单方法 | Dongdong’s Blog
这是一种简答的更新notionNext版本的方法
手动 NotionNext 版本更新教程 | D_SUPER BLOG
勤劳的 tangly1024 [ Github][ Blog] 大大又更新了 NotionNext 内容。之前的更新内容不涉及 blog.config.js 文件(配置博客唯一要更改的文件),可以直接 Fetch upstream → Fetch and merge 跟进版本。但是这次涉及到 blog.config.js 文件的修改,新旧内容冲突导致 Github 懵了,需要手动更新。数日前就看到需要更新,今天才得以抽空完成这一"大工程"(实在是懒)。 (1) 浏览器 [Github 已经 Fork 过 NotionNext 项目]; (2) Github desktop 客户端 [ 安装地址]; (3) Visual Studio Code - VS Code [ 安装地址].
Github 自动化(高阶方法,需要一定知识)
除了手动点击 Fetch upstream / Sync fork 按钮,仓库内置了一个 GitHub Actions workflow(.github/workflows/sync.yaml),可以自动帮你完成每日同步上游最新代码的工作。
功能说明
该 workflow 每天 UTC 0点(对应北京时间早上8点)自动运行一次,将上游仓库 notionnext-org/NotionNext 的 main 分支同步合并到你 fork 仓库的 main 分支,不需要每天手动点击更新按钮。
关键配置如下:
on:
schedule:
- cron: "0 0 * * *" # every day
workflow_dispatch:
jobs:
sync_latest_from_upstream:
if: ${{ github.event.repository.fork }}
steps:
- uses: aormsby/[email protected]
with:
upstream_sync_repo: notionnext-org/NotionNext
upstream_sync_branch: main
target_sync_branch: main启用自动化(重点)
::: warning 注意
GitHub 出于安全考虑,新 fork 的仓库默认关闭了 Actions(自动化)功能,需要手动启用一次才能生效:
:::
- 打开自己 fork 的仓库,点击顶部的
Actions标签; - 如果看到提示条 "Workflows aren't being run on this forked repository",点击
I understand my workflows, go ahead and enable them按钮启用 Actions; - 启用后,左侧列表中会出现
Upstream Syncworkflow,代表自动化已生效,之后会按计划每天自动运行一次; - 你也可以随时打开该 workflow 页面,点击右上角的
Run workflow按钮手动立即触发一次同步。
注意事项
- GitHub 会在 fork 仓库连续60天没有任何活动时自动禁用其 Actions,届时需要重新按上述步骤启用一次。
- 若上游仓库修改了 workflow 文件本身,GitHub 会自动暂停本仓库该 workflow 的运行,导致自动同步失败,此时需要按前文"简单更新方法"章节中手动
Sync fork的方式操作一次,才能恢复自动化。 - 该自动化只负责同步代码,仍可能产生代码冲突(例如你修改过
blog.config.js),冲突的处理方式与手动更新一致,参考上文"带有冲突的更新"章节。
优化建议
尽量不改动代码
您可以借助Notion_Config,或者环境变量等方式来调整站点的配置。从而最大程度减小代码的冲突。
建立一个专用部署分支
您可以选择在Git仓库中,建立属于自己的分支,例如我建了一个 deploy/tangly1024.com 分支, 并在vercel中导入并选择使用该分支进行部署,main分支则用于提交更新最新的代码版本。
这样,以后您只需在自己的分支修改代码,然后每次更新NotionNext版本只是main分支的更新,然后在自己的仓库中选择将main合并到自己建立的部署分支即可。
部署更新失败如何解决
::: info 问题
更新后打开网页,版本号还是旧的?
:::
请检查Vercel部署日志,查看日志方法。
Deployment模块
打开Vercel后台的Deployment标签,这里可以查看您的所有部署记录。
其中,部署状态是绿色的Ready表示成功,标注为红色的Error则失败
查看错误日志
点击此次部署记录的标题,打开详情页面
详情页下方,是打包编译的日志,在Error分组中展现了出现错误的原因,以及对应的代码行数。按照提示修正github中的代码即可重新部署。
寻求帮助
开始练习写作的小白,我觉得相比写什么、怎么写、写得如何来说,更重要的是坚持写作。
开始练习写作的小白,我觉得相比写什么、怎么写、写得如何来说,更重要的是坚持写作。
原文链接
https://docs.tangly1024.com/article/how-to-update-notionnext
Design Xuhome DESIGN (`docs/design/xuhome/DESIGN.md`)
name: XuHome
colors:
primary: '#0284c7'
primary-hover: '#0ea5e9'
accent: '#fde68a'
on-primary: '#000000'
on-accent: '#000000'
background: '#faf8f5'
surface: '#ffffff'
on-surface: '#0f172a'
text-secondary: '#475569'
dark-background: '#0b1120'
dark-surface: '#172033'
dark-on-surface: '#f8fafc'
dark-text-secondary: '#cbd5e1'
typography:
body:
fontFamily: ui-sans-serif
fontSize: 16px
fontWeight: 500
lineHeight: 1.6
label:
fontFamily: ui-sans-serif
fontSize: 12px
fontWeight: 800
lineHeight: 1.2
letterSpacing: 0.05em
rounded:
sm: 0.125rem
spacing:
xs: 4px
sm: 8px
md: 16px
lg: 24px
components:
page:
backgroundColor: '{colors.background}'
textColor: '{colors.on-surface}'
page-dark:
backgroundColor: '{colors.dark-background}'
textColor: '{colors.dark-on-surface}'
button-primary:
backgroundColor: '{colors.primary}'
textColor: '{colors.on-primary}'
typography: '{typography.label}'
rounded: '{rounded.sm}'
padding: 8px
button-primary-hover:
backgroundColor: '{colors.primary-hover}'
textColor: '{colors.on-primary}'
chip-accent:
backgroundColor: '{colors.accent}'
textColor: '{colors.on-accent}'
typography: '{typography.label}'
rounded: '{rounded.sm}'
padding: 4px
card:
backgroundColor: '{colors.surface}'
textColor: '{colors.on-surface}'
rounded: '{rounded.sm}'
padding: 16px
card-dark:
backgroundColor: '{colors.dark-surface}'
textColor: '{colors.dark-on-surface}'
rounded: '{rounded.sm}'
padding: 16px
metadata:
textColor: '{colors.text-secondary}'
typography: '{typography.label}'
metadata-dark:
textColor: '{colors.dark-text-secondary}'
typography: '{typography.label}'
Overview
XuHome uses a compact neo-brutalist blog layout: hard borders, offset shadows and small accent blocks. Color customization must preserve legibility before preserving a particular foreground color.
Colors
Light and dark palettes are independent. Dark mode uses dark page and card surfaces across all large areas; light surfaces must not remain as large blocks. Primary, hover and accent backgrounds always derive their foreground from the candidate with the higher WCAG contrast ratio.
Typography
Body copy stays compact and readable. Labels, dates and controls use heavy uppercase text to retain the neo-brutalist character.
Layout
Use an 8px rhythm with compact 4px adjustments. Content remains centered with a readable main column and a narrower sidebar.
Elevation & Depth
Depth comes from hard offset shadows in the active border color, never from soft white glows. Dark mode keeps those shadows saturated but avoids bright surface blocks.
Shapes
Cards, buttons and inputs use a restrained 2px radius and visible 2–3px borders.
Components
Buttons and tags use the same interaction rules: primary backgrounds use on-primary, hover backgrounds use on-primary-hover, and accent backgrounds use on-accent. Text colors must change together with their background state. Hero text uses its custom colors in light mode and the active dark primary/text colors in dark mode.
The theme console behaves like a fast right-side drawer. It enters from just beyond the viewport in 200ms with an ease-out curve and exits before unmounting, so users can visually locate it. Respect prefers-reduced-motion by removing the transition.
Do's and Don'ts
- Do keep body and secondary text light on dark surfaces.
- Do switch border and hard-shadow colors with the active mode.
- Do derive button foreground colors whenever a palette background changes.
- Do animate the theme console from the screen edge instead of making it appear abruptly.
- Don't hardcode
text-whitefor arbitrary user-selected colors. - Don't write active light-mode aliases inline; doing so prevents dark-mode CSS from taking effect.
Developer Performance Theme Audit Latest (`docs/developer/performance/theme-audit-latest.md`)
Theme Performance Audit
Base URL: http://localhost:3000
Generated: 2026-05-01T14:36:12.458Z
| Theme | Perf | SEO | LCP(ms) | INP(ms) | CLS | JS(KB) | Total(KB) |
|---|---|---|---|---|---|---|---|
| gitbook | 14 | 92 | 9966 | - | 1.4717919999999998 | 0 | 1403 |
| fukasawa | 15 | 92 | 7773 | - | 1 | 0 | 1421 |
| fuwari | 18 | 83 | 7115 | - | 1 | 0 | 2259 |
| commerce | 20 | 83 | 10709 | - | 1.094845 | 0 | 1493 |
| hexo | 25 | 92 | 7567 | - | 1.015376 | 0 | 1425 |
| game | 30 | 100 | 10602 | - | 1.001675 | 0 | 1680 |
| magzine | 31 | 92 | 6224 | - | 1.013977 | 0 | 1354 |
| heo | 34 | 92 | 6786 | - | 1.006132 | 0 | 1499 |
| example | 36 | 100 | 8284 | - | 1.000021 | 0 | 1089 |
| claude | 38 | 100 | 5829 | - | 1 | 0 | 1038 |
| starter | 38 | 92 | 5096 | - | 1.4528780000000001 | 0 | 1634 |
| movie | 39 | 100 | 7835 | - | 0.20054300000000003 | 0 | 1106 |
| simple | 40 | 92 | 7012 | - | 0.381928 | 0 | 1165 |
| proxio | 45 | 92 | 5401 | - | 0.003425 | 0 | 1105 |
| photo | 47 | 100 | 6730 | - | 0.17810600000000001 | 0 | 1037 |
| plog | 50 | 100 | 8741 | - | 0.016871 | 0 | 1111 |
| nobelium | 52 | 100 | 6473 | - | 0.010607 | 0 | 1160 |
| medium | 54 | 92 | 6306 | - | 0.050975 | 0 | 1275 |
| nav | 56 | 100 | 5661 | - | 0.000009 | 0 | 912 |
| landing | 62 | 100 | 2946 | - | 1.1633749999999998 | 0 | 1090 |
| matery | 72 | 100 | 3993 | - | 0.0014019999999999998 | 0 | 1182 |
| next | 75 | 92 | 4022 | - | 0 | 0 | 1261 |
| typography | 79 | 100 | 4002 | - | 0.075396 | 0 | 1026 |
Top Priority Themes
- gitbook: Perf 14, LCP 9966ms, JS 0KB
- fukasawa: Perf 15, LCP 7773ms, JS 0KB
- fuwari: Perf 18, LCP 7115ms, JS 0KB
- commerce: Perf 20, LCP 10709ms, JS 0KB
- hexo: Perf 25, LCP 7567ms, JS 0KB
Developer Rfc 2026 Originality Proof Auto Manifest (`docs/developer/rfc/2026-originality-proof-auto-manifest.md`)
原创存证自动公开清单任务
状态:已实现,本地验收通过
背景
手动填写 proof、proofHash 或 proofUrl 已经足够低风险,但对全站原创长文用户仍然偏手动。NotionNext 更适合先提供开源友好的自动化方案,而不是直接绑定商业版权平台或区块链服务。
目标
- 构建期自动生成
public/proofs/originality.json。 - 清单只保存哈希、URL、标题、页面 ID、算法和时间,不保存正文。
- GitHub Actions 可选自动提交清单,借助公开 commit 时间线形成轻量证据。
- 已有清单记录能自动触发文章页原创存证展示。
非目标
- 不上传正文到第三方服务。
- 不接入 OpenTimestamps、RFC 3161、OriginStamp 或版权平台 API。
- 不默认运行官方仓库 workflow;必须由仓库变量显式开启。
实现
ORIGINALITY_PROOF_AUTO_MANIFEST=true时,processPostData会复用现有 SHA-256 生成逻辑并写入清单。- 如果仓库已有
public/proofs/originality.json,文章页会识别对应记录并显示为“公开清单”。 .github/workflows/originality-proofs.yml默认跳过,只有设置 GitHub Actions 变量ORIGINALITY_PROOF_AUTO_MANIFEST=true才会运行。
验收记录
- manifest helper 有单测覆盖。
- 原创存证 helper 能应用公开清单记录。
- VitePress 教程包含全自动开启步骤和限制。
- VitePress 教程包含 manifest JSON 示例和常见问题排查。
- workflow 默认不会在未设置变量时运行。
本地验证
yarn test __tests__/lib/utils/originalityProof.test.js __tests__/lib/utils/originalityProofManifest.test.js --runInBand:通过。yarn lint --file components/OriginalityProof.js --file lib/utils/originalityProof.js --file lib/utils/originalityProofManifest.js --file lib/utils/post.js --file __tests__/lib/utils/originalityProof.test.js --file __tests__/lib/utils/originalityProofManifest.test.js:通过。yarn docs:site:build:通过,仅有既有语法高亮和 chunk size 警告。git diff --check:通过,仅有 Windows LF/CRLF 提示。
Developer Rfc 2026 Originality Proof Ux (`docs/developer/rfc/2026-originality-proof-ux.md`)
原创存证体验优化任务
状态:已落地,本地验收通过
背景
Issue #4278 的 MVP 已经支持本地 SHA-256 哈希和外部凭证字段,但文章页默认展示为完整信息块。对普通站长来说,它更像开发调试信息,不像面向读者的“原创凭证”入口。
对标结论
主流方案通常分三类:
| 方案 | 交互 | NotionNext 取舍 |
|---|---|---|
| 内容凭证 / C2PA | 徽章入口,展开后看来源和历史 | 采用“先徽章、再详情”的低干扰入口 |
| 时间戳 / 哈希存证 | 复制哈希或打开凭证链接自行验证 | 保留哈希、时间、凭证链接,并新增一键复制 |
| 版权登记平台 | 平台页承载法律化证明 | 不内置法律承诺,只允许链接外部凭证 |
本轮目标
- 文章页默认显示紧凑徽章:
原创存证 · 外部凭证/本地哈希 · 短哈希。 - 点击后展开完整算法、时间、哈希和凭证链接。
- 提供“复制证据”按钮,便于站长提交平台、发邮件或处理维权沟通。
- 复制后给用户明确反馈,剪贴板不可用时提示手动复制。
- 教程改成按真实操作路径说明:填一个
proofUrl或proofHash即可开始。
非目标
- 不接入 OpenTimestamps、RFC 3161、GitHub 自动提交或版权平台 API。
- 不上传正文到第三方服务。
- 不声明等同于法律公证或版权登记。
验收记录
- 默认视觉从大块说明改成可展开徽章。
- 外部凭证和本地哈希能显示不同状态。
- 证据文本可复制,格式稳定并有单测覆盖。
- 复制后有“已复制”反馈,剪贴板不可用时提示手动复制。
- 用户教程同步说明徽章、展开和复制。
本地验证
yarn test __tests__/lib/utils/originalityProof.test.js --runInBand:通过。yarn lint --file components/OriginalityProof.js --file lib/utils/originalityProof.js --file __tests__/lib/utils/originalityProof.test.js:通过。yarn docs:site:build:通过,仅有既有语法高亮和 chunk size 警告。git diff --check:通过,仅有 Windows LF/CRLF 提示。
Developer Rfc TEMPLATE (`docs/developer/rfc/TEMPLATE.md`)
RFC: (标题)
- 作者: @github-username
- 日期: YYYY-MM-DD
- 状态: 草案 | 讨论中 | 已接受 | 已拒绝 | 已替代
摘要
一两句话说明要做什么、解决什么问题。
动机
- 当前痛点是什么?
- 影响哪些用户/主题/部署方式?
方案
提议
具体设计、API、配置项、文件路径变更。
备选方案
曾考虑过的其他做法及为何不选。
兼容性
- 是否破坏性变更?
- 迁移步骤(环境变量、Notion 字段、主题配置)。
文档与测试
- 需要更新的
docs/user-guide/路径 - 建议的验证方式(
yarn build、关键页面、主题列表)
开放问题
- 待讨论点 1
- 待讨论点 2
讨论记录
(合并 PR 或 Discussion 链接后在此追加)
Developer Rfc Issue 2941 Code Block Ui Refinement (`docs/developer/rfc/issue-2941-code-block-ui-refinement.md`)
RFC: 代码折叠块桌面与移动端 UI 收敛
- 作者: @RHZHZ
- 日期: 2026-08-01
- 状态: 已实现
- 关联 Issue: https://github.com/notionnext-org/NotionNext/issues/2941
- 前置 RFC:
docs/developer/rfc/issue-2941-code-sidebar.md
摘要
在现有长代码折叠和桌面端侧栏预览的基础上,进行一轮 CSS 级 UI 收敛。重点解决折叠头与代码内容之间存在额外空隙、桌面与移动端容器层级不一致、移动端代码横向溢出观感较强等问题。
本次改造不重写 PrismMac 的行为逻辑,不改变配置项,也不改变移动端“折叠/展开”的交互模型。目标是让折叠头、代码块和操作按钮呈现为一个连续、稳定、可扫描的代码组件。
背景与问题
当前实现已经具备以下能力:
- 长代码块可折叠。
- 桌面端可点击“在侧栏查看”。
- 代码块支持 Mac 三色点和 Prism 高亮。
- 移动端隐藏侧栏入口,保留原有折叠行为。
根据本地页面验证,主要问题集中在视觉层:
- 折叠头使用
.collapse-panel-wrapper,代码内容内部仍保留.code-toolbar的默认上下外边距,导致两者之间出现明显空隙。 - 折叠容器和代码容器分别拥有边框、圆角、背景和阴影,容易产生“卡片嵌套卡片”的观感。
- 桌面端按钮、折叠箭头和语言标签在同一行的优先级不够清晰,长语言名称或窄窗口下可能挤压内容。
- 移动端代码不换行是正确的,但当前左右裁切感较强,代码区内边距和滚动提示需要收敛。
- 主题级样式,特别是 Claude 主题的代码块覆盖规则,可能覆盖共享
.collapse-*与.code-toolbar样式,造成不同主题的视觉不一致。
目标
- 折叠头与展开后的代码内容共享同一个视觉外框。
- 消除折叠头与代码块之间不必要的垂直空隙。
- 桌面端和移动端使用一致的容器层级与间距语义。
- 保留代码横向滚动,不强制换行破坏代码可读性。
- 让“在侧栏查看”成为桌面端次要操作,不抢占折叠标题和箭头的注意力。
- 保持现有
CODE_COLLAPSE、CODE_COLLAPSE_MIN_LINES和CODE_COLLAPSE_EXPAND_DEFAULT的行为不变。 - 不引入新的站长配置项,不增加额外运行时状态。
非目标
- 不重写
PrismMac的 DOM 注入流程。 - 不将现有 DOM helper 改造成 React Portal。
- 不改变移动端的侧栏策略。
- 不让代码块自动换行。
- 不重做各主题的整体排版系统。
- 不在本次改造中统一所有主题的代码配色。
设计原则
单一视觉容器
.collapse-panel-wrapper 作为代码折叠组件的唯一外框,负责:
- 外部间距
- 边框
- 圆角
- 背景
- 阴影
- 溢出裁切
内部的 .code-toolbar 不再承担独立卡片职责。展开状态下,它应当成为外框内部的代码内容区。
结构间距归属清晰
.collapse-wrapper负责组件与文章正文之间的间距。.collapse-panel-wrapper负责折叠头与代码内容的组合。.collapse-header-row负责头部高度和按钮布局。.collapse-panel负责展开动画和内容裁切。.code-toolbar与.notion-code不再额外贡献外部 margin。
代码优先于装饰
代码区域应优先保证:
- 等宽字体稳定。
- 代码行不被意外换行。
- 长行可横向滚动。
- 代码内容边界清晰。
- 高亮颜色在浅色和深色模式下可读。
视觉方案
统一组件结构
目标结构保持现有 DOM 方向,仅通过 CSS 收敛视觉层级:
.collapse-wrapper
└── .collapse-panel-wrapper
├── .collapse-header-row
│ ├── .collapse-header
│ └── .collapse-side-panel-button # 仅桌面端
└── .collapse-panel
└── .code-toolbar
└── pre.notion-code桌面端
折叠头
- 高度保持在
36px左右。 - 语言和行数作为主要信息。
- 折叠箭头固定在右侧。
- “在侧栏查看”位于箭头左侧或头部操作区,作为次要按钮。
- 语言标签过长时使用省略号,不推动代码块宽度变化。
代码区
- 与折叠头共用外框。
- 取消
.code-toolbar的上下 margin。 - 取消内部独立圆角和阴影。
- 代码区保留 Mac 三色点和 Prism 高亮。
- 代码内容区允许横向滚动。
侧栏入口
- 继续只在
min-width: 1024px显示。 - 使用低对比度边框和背景,避免与正文主操作竞争。
- 文本保持单行,避免窄桌面窗口中按钮高度变化。
移动端
- 隐藏“在侧栏查看”按钮。
- 保留折叠头、箭头和展开/收起行为。
- 折叠头与代码区仍使用同一个外框。
- 代码区左右内边距收敛到约
10–12px。 - 代码字号使用固定的小尺寸,不随视口宽度缩放。
- 保持
white-space: pre,避免代码自动换行。 - 使用
overflow-x: auto,允许用户通过横向滑动查看长行。 - 代码块底部滚动条不应撑大组件高度或造成布局跳动。
- 不新增移动端固定定位元素,避免遮挡文章内容。
间距建议
| 位置 | 当前风险 | 目标 |
|---|---|---|
| 组件与正文 | 外层 margin 与主题规则叠加 | 由 .collapse-wrapper 单独控制 |
| 折叠头与代码区 | .code-toolbar margin 造成空隙 |
0–4px,推荐 0px |
| 折叠头左右内边距 | 按钮与标题容易挤压 | 桌面 12px,移动 10px |
| 代码区左右内边距 | 手机端裁切感较强 | 桌面 16–18px,移动 10–12px |
| 代码区顶部内边距 | Mac 三色点与代码可能重叠 | 保留独立顶部安全区 |
| 侧栏入口与箭头 | 操作区层级不清 | 统一 8px 间距 |
样式实现边界
共享样式
主要修改范围:
public/css/prism-mac-style.css
建议优先处理以下规则:
.collapse-panel .code-toolbar {
margin: 0 !important;
border: 0;
border-radius: 0;
box-shadow: none;
}
.collapse-panel .code-toolbar > pre.notion-code {
margin: 0 !important;
border-radius: 0;
}实际实现应结合现有主题覆盖规则调整选择器优先级,避免仅通过扩大 !important 范围解决冲突。
主题覆盖
如果内置主题对 .code-toolbar 或 .collapse-wrapper 有专门样式,应采用以下顺序处理:
- 先确认共享样式的结构语义是否正确。
- 再为主题增加最小范围的覆盖。
- 避免在主题文件中复制整套折叠样式。
- 主题覆盖只处理颜色、字体和视觉风格,不改变折叠结构。
重点检查:
themes/claude/style.jsstyles/notion.csspublic/css/prism-mac-style.css
交互与可访问性
- 折叠头保持
button元素,并同步维护aria-expanded。 - “在侧栏查看”不能触发折叠头的点击事件。
- 移动端隐藏侧栏按钮时,不应留下空白占位。
- 长标题使用省略号,但完整语言和行数应保留在可访问名称中。
- 侧栏继续支持关闭按钮、Esc 和点击遮罩。
- 所有按钮保持可见的键盘焦点状态。
- 代码横向滚动不应阻止页面纵向滚动。
兼容性
本改造不改变以下行为:
CODE_COLLAPSE = false时不创建折叠组件。- 未超过
CODE_COLLAPSE_MIN_LINES的代码块不显示折叠头。 CODE_COLLAPSE_EXPAND_DEFAULT继续控制默认展开状态。- 桌面端侧栏仍只展示当前代码块,并在关闭时清理节点和监听器。
- 移动端不显示侧栏入口。
- 普通代码块、Mermaid、行号和复制功能保持现有行为。
实施步骤
- 调整共享 CSS,使折叠头和
.code-toolbar形成单一视觉容器。 - 增加桌面和移动端的明确间距规则。
- 检查 Claude 主题和全局 Notion 样式的覆盖关系。
- 在桌面端验证展开、收起、侧栏入口和代码横向滚动。
- 在移动端验证折叠头、代码滚动、正文纵向滚动和无侧栏入口。
- 根据截图和 DOM 检查结果进行一次小范围视觉微调。
- 更新用户文档中的代码块行为说明。
验收标准
桌面端
- 折叠头与代码块之间没有明显空白卡层。
- 折叠头和代码内容共享边框、圆角和背景层级。
- “在侧栏查看”按钮不改变折叠头高度。
- 长语言名称不会挤压箭头或按钮。
- 代码长行可横向滚动,不发生页面整体横向溢出。
- 侧栏打开后不会被主题代码样式透明穿透。
移动端
- 侧栏入口不显示。
- 折叠头与代码块之间保持
0–4px的视觉间距。 - 代码块左右内边距适合小屏阅读。
- 长代码行可以横向滑动查看。
- 横向滚动不会导致页面整体横向滚动。
- 折叠和展开不会造成明显布局跳动。
- 代码块底部滚动条不遮挡最后一行代码。
回归
-
CODE_COLLAPSE关闭时页面保持原有代码块表现。 - 普通短代码块不出现折叠头。
- Prism 高亮仍正常。
- 复制按钮仍正常。
- Mermaid 代码块没有新增异常边框或空白。
- 路由切换后侧栏节点和键盘监听器被清理。
测试计划
自动化测试
继续使用:
__tests__/components/PrismMac.test.js重点保证:
- 桌面端显示侧栏入口。
- 移动端隐藏侧栏入口。
- 折叠头点击不会被侧栏按钮干扰。
- 侧栏关闭、Esc 和遮罩关闭行为不回归。
如 CSS 调整涉及稳定的 DOM class,可补充轻量 DOM 断言,但不建议在 Jest 中测试具体像素值。
手动验证
使用本地测试页面:
http://localhost:3000/article/notion-tabs-test至少检查以下视口:
- 桌面:
1440 × 900 - 窄桌面:
1024 × 768 - 手机:
390 × 844 - 小屏手机:
375 × 667
验证内容:
- 长代码块默认展开和默认折叠两种状态。
- 代码块存在超长单行时的横向滚动。
- 代码块上下相邻正文时的间距。
- 浅色和深色模式。
- Claude 主题与至少一个非 Claude 主题。
风险与取舍
风险
- 主题 CSS 选择器优先级可能覆盖共享样式。
- 取消内部 margin 后,某些主题的代码块可能显得过于贴边。
- 移动端滚动条样式在不同浏览器中表现不一致。
- 代码块内部使用
min-width或white-space时,可能引入局部横向溢出。
取舍
- 选择 CSS 收敛而不是重写组件,降低 PR 范围和回归风险。
- 保留代码横向滚动而不是强制换行,优先保证代码语义和复制体验。
- 以共享容器统一结构,以主题覆盖处理风格差异。
开放问题
- 移动端代码字号最终采用
12px还是13px? - 是否需要为横向滚动区域增加渐隐提示?
- 是否需要在所有主题中统一代码块外部上下间距?
- 是否将“在侧栏查看”按钮文案抽取到多语言字典?
讨论记录
当前文档基于 2026-08-01 本地页面截图和 smart-code-collapse 分支现有实现整理,已完成对应的 CSS/UI 收敛。
实现记录
public/css/prism-mac-style.css- 折叠面板内部的
.code-toolbar不再额外贡献 margin、边框和阴影。 - 手机端收紧了折叠头高度、代码区内边距和字号。
- 折叠面板内部的
themes/claude/style.js- 折叠外框改为统一承载代码 shell。
- 只保留一层视觉容器,避免内部 pre 再次画框。
Developer Rfc Issue 2941 Code Sidebar (`docs/developer/rfc/issue-2941-code-sidebar.md`)
RFC: 代码块侧栏预览
- 作者: @RHZHZ
- 日期: 2026-08-01
- 状态: 已实现
- 关联 Issue: https://github.com/notionnext-org/NotionNext/issues/2941
摘要
为长代码块增加“在侧栏查看”的交互,目标是让用户在阅读上下文时,不必把代码块完整展开到正文里。
本方案严格按维护者建议走最小版本:
- 复用现有
CODE_COLLAPSE - 只先覆盖桌面端
- 移动端保持现有折叠行为
- 不先引入 Portal、懒加载或复杂状态管理
问题
当前代码块直接占据正文流,会带来三个典型问题:
- 长代码块会打断文章阅读节奏。
- 用户需要频繁滚动,难以在看代码和看解释之间来回切换。
- 把代码块完全展开在正文中,会显著增加页面高度。
Issue #2941 的目标不是重做代码块体系,而是在现有折叠能力上补一个更适合桌面阅读的预览方式。
目标
- 桌面端对长代码块提供“在侧栏查看”按钮。
- 点击后在右侧打开一个固定侧栏,展示当前代码。
- 关闭时清空侧栏内容并释放事件监听。
- 保留原有折叠代码块能力,不破坏现有行为。
非目标
- 不做全新的代码块渲染器。
- 不做 React Portal 重构。
- 不引入全局状态管理。
- 不重写 Prism 高亮流程。
- 不改变移动端的折叠交互。
现状
当前代码相关链路已经存在:
components/PrismMac.js负责 Prism、行号、Mermaid 和代码折叠注入。public/css/prism-mac-style.css已经承载.collapse-*的代码块样式。components/Collapse.js已有通用折叠动画,但更适合内容面板,不适合固定侧栏。docs/user-guide/config/notion-next-code-style.md已经说明CODE_COLLAPSE配置。
这意味着侧栏预览最适合落在 PrismMac 这条现有注入链路里,而不是单独开一套新的组件体系。
方案
核心思路
继续以 renderCollapseCode() 为入口,在检测到长代码块时:
- 保持当前折叠包装不变。
- 额外注入一个“在侧栏查看”按钮。
- 点击按钮时,把当前 code 的内容放入一个固定右侧侧栏。
- 侧栏以轻量 DOM 节点方式挂在
document.body上,不使用 Portal。 - 侧栏外层提供遮罩,点击遮罩、Esc 或关闭按钮均可退出。
触发条件
CODE_COLLAPSE开启。- 当前代码块行数达到
CODE_COLLAPSE_MIN_LINES。 - 当前视口满足桌面端条件。
桌面 / 移动分流
- 桌面端:显示侧栏预览按钮。
- 移动端:保持现有折叠/展开行为,不额外加侧栏入口。
侧栏结构
侧栏建议包含:
- 语言标题
- 行数信息
- 关闭按钮
- 复制按钮
- 代码内容区
- 背景遮罩
侧栏以固定定位展示,默认从右侧进入,关闭时向右收起。
内容策略
优先复用当前 Prism 已处理后的代码内容,保证:
- 代码高亮风格一致
- 语言 class 不丢失
- 不需要重新跑一次高亮
生命周期
- 打开时只保留一个侧栏实例。
- 再次点击同一个按钮时,直接更新侧栏内容或保持当前内容。
- 路由切换、组件卸载或 Esc 关闭时,移除侧栏与监听器。
实现落点
`components/PrismMac.js`
建议新增一组很小的 helper:
openCodeSidePanel()closeCodeSidePanel()syncCodeSidePanelContent()
以及一个视口判断 helper,例如:
isCodeSidePanelSupported()
renderCollapseCode() 继续负责遍历 .code-toolbar,只是在长代码块上额外挂一个按钮事件。
`public/css/prism-mac-style.css`
继续把样式集中在这里,新增:
- 侧栏容器
- 侧栏标题区
- 侧栏关闭按钮
- 侧栏复制按钮
- 代码内容滚动区
- 桌面/暗色模式适配
`components/Collapse.js`
保持现状,不强行复用到侧栏场景。
原因很简单:
- 它适合内容展开/折叠
- 不适合固定侧栏的宽度动画和固定定位
- 直接复用会让职责变宽
实现记录
components/PrismMac.js- 追加桌面端侧栏预览 helper。
- 在长代码块折叠头部旁增加“在侧栏查看”按钮。
- 路由切换和卸载时自动关闭侧栏。
public/css/prism-mac-style.css- 补充折叠头部按钮位样式。
- 增加 fixed 侧栏、背景遮罩与深色模式样式。
__tests__/components/PrismMac.test.js- 覆盖桌面/移动端分流、打开/关闭、Esc 关闭、遮罩关闭、按钮注入。
docs/user-guide/- 同步
CODE_COLLAPSE的桌面侧栏预览说明。
- 同步
兼容性
CODE_COLLAPSE = false时,不出现侧栏入口。CODE_COLLAPSE_EXPAND_DEFAULT继续只控制原有折叠默认状态。- 现有复制、行号、Mac 风格、Mermaid 不受影响。
- 未命中的普通代码块不新增任何额外 DOM。
风险与约束
- 代码内容来自 DOM,必须注意清理事件监听,避免路由切换残留。
- 代码块可能有多个实例,侧栏需要单实例覆盖,避免重复挂载。
- 如果直接复用高亮后的
innerHTML,要避免引入多余包装破坏复制体验。 - 桌面阈值需要和站点布局保持一致,避免在中等分辨率下误触发。
测试计划
自动化测试
建议新增或补充:
components/PrismMac.js的 DOM helper 测试- 侧栏打开 / 关闭测试
- 桌面端显示入口、移动端不显示入口测试
- 多个代码块只生成一个侧栏实例的测试
手动验证
建议在本地文章页验证:
- 长代码块出现“在侧栏查看”
- 点击后侧栏从右侧打开
- 代码内容与正文一致
- 关闭按钮、Esc 与点击遮罩均可关闭侧栏
- 移动端仍保持现有折叠交互
文档验证
实现完成后,再补充更新:
docs/user-guide/config/notion-next-code-style.mddocs/user-guide/reference/features.md
实施顺序
- 确认当前
PrismMac注入链路和折叠逻辑。 - 先做设计级 helper 拆分。
- 再做侧栏 DOM 和样式。
- 最后补测试和文档。
开放问题
- 侧栏宽度是固定值还是按视口比例自适应。
- 关闭按钮是否需要额外保留快捷键提示。
- 复制按钮是否必须放在首版里,还是与侧栏内容同步即可。
- 桌面断点是否直接沿用现有布局断点。
Developer Rfc Issue 3948 Notion Tabs (`docs/developer/rfc/issue-3948-notion-tabs.md`)
RFC: 支持 Notion 选项卡块
- 作者: @RHZHZ
- 日期: 2026-08-01
- 状态: 已实现(待评审)
- 关联 Issue: https://github.com/notionnext-org/NotionNext/issues/3948
摘要
为 NotionNext 增加 Notion 原生选项卡块的渲染支持,使文章中用于多版本、原文译文、方案对比等场景的选项卡内容可以在站点前台正常展示和切换。
实现建议采用数据适配加自定义组件的方式:在 Notion blockMap 格式化阶段识别选项卡块,将其标记为 NotionNext 内部可识别的特殊 embed,再由现有 NotionEmbed 扩展点分流到 NotionTabs 组件渲染。
动机
Notion 已新增选项卡能力,作者可以在同一块区域内通过顶部标签切换不同内容。当前 NotionNext 使用 [email protected] 渲染正文,该版本对未知 block type 会输出 Unsupported block type ... 并渲染空内容,导致选项卡块在站点中不可用。
该问题影响所有主题,因为正文最终都复用 components/NotionPage.js。因此实现应位于 Notion 数据格式化和通用 Notion 组件层,而不是逐个主题补丁。
背景与约束
components/NotionPage.js直接将post.blockMap传给NotionRenderer。react-notion-x的components覆盖点只支持既有组件,如Code、Collection、Embed、Quote等,没有通用UnknownBlock或Tab扩展点。react-notion-x的 block 分发逻辑是硬编码switch (block.type),未知类型会渲染空节点。styles/notion.css是当前项目覆盖和扩展 Notion 渲染样式的统一入口。- Notion 官方 Block 文档说明
tabblock 的直接子节点是 paragraph,paragraph 标题作为标签文本,paragraph 的子节点作为标签页内容。
方案
提议
新增一个项目内部选项卡渲染链路:
- 在
lib/db/notion/getPostBlocks.js的formatNotionBlock()中识别 Notion 选项卡块。 - 保留原始
content层级,只将选项卡容器 block 转换为特殊 embed:type = 'embed'format.embed_variant = 'notion_tabs'format.notion_next_original_type = 原始类型
- 在
components/NotionEmbed.js中优先判断embed_variant === 'notion_tabs',命中时渲染NotionTabs,否则沿用现有 iframe embed 逻辑。 - 新增
components/NotionTabs.js:- 通过
useNotionContext()获取recordMap。 - 使用当前 block 的
content作为 tab item id 列表。 - 每个 tab item 从
properties.title提取标签文案。 - 当前激活面板渲染该 tab item 的子内容。
- 提供
role="tablist"、role="tab"、role="tabpanel"与aria-selected,保证基础可访问性。
- 通过
- 在
styles/notion.css中新增.notion-tabs-*样式,保证所有主题共享。
实现记录
当前实现已落地在通用正文渲染链路,不依赖具体主题:
lib/db/notion/getPostBlocks.js在formatNotionBlock()中识别tab、tabs容器,并转换为embed。components/NotionEmbed.js优先分流format.embed_variant === 'notion_tabs',避免进入普通 iframe embed 的 source 校验。components/NotionTabs.js从useNotionContext()读取recordMap,将容器 block 的content解析为 tab item 列表。styles/notion.css提供.notion-tabs-*通用样式,覆盖浅色、深色和横向滚动场景。
转换后的内部 block 形态:
{
id: 'tabs-block-id',
type: 'embed',
content: ['tab-item-a', 'tab-item-b'],
format: {
embed_variant: 'notion_tabs',
notion_next_original_type: 'tab'
}
}真实数据结构
本地页面 http://localhost:3000/article/notion-tabs-test 返回的 Notion 私有 API 结构与官方文档略有差异:
- 容器 block type 为
tab。 - 容器
content指向多个text子块,而不是paragraph。 - 每个 tab item 的
properties.title是标签文本,例如是、不是、选项卡 3。 - 每个 tab item 的
content指向该标签页正文子块。
示意结构:
page
└─ tab
├─ text title="是"
│ ├─ text title="阿松大现在才"
│ └─ text
├─ text title="不是"
│ ├─ text title="123123"
│ └─ text
└─ text title="选项卡 3"
├─ text title="213123123"
├─ text
└─ text title="123213213"因此首版兼容策略以 tab/tabs 容器 + content 子块链路为准,标签项不强依赖具体 block type,只要能从 recordMap.block[id] 读取到 block 即可。
组件职责
NotionTabs 的职责保持收敛:
- 只负责 tab list、激活状态、键盘切换和 panel 容器。
- 不复制
react-notion-x的 block 分发逻辑。 - panel 中逐个渲染 active tab item 的子 block,而不是渲染 tab item 本身,避免标签标题在内容区重复出现。
- 继续把
recordMap、components、mapPageUrl、mapImageUrl等上下文传回NotionRenderer,保证嵌套内容继续使用站点已有渲染配置。
交互设计
- 默认激活第一个有效 tab item。
- 点击 tab button 切换当前 panel。
- 支持
ArrowLeft、ArrowRight、Home、End键切换并移动焦点。 - 使用
role="tablist"、role="tab"、role="tabpanel"、aria-selected、aria-controls和aria-labelledby提供基础可访问性。 - 未激活 panel 当前不保留在 DOM 中,减少重复渲染和复杂状态同步。
数据兼容策略
Notion 私有 API 与官方 API 的 block type 命名可能存在差异。实现时应兼容以下形态:
- 容器类型:
tab、tabs、后续发现的等价类型。 - 标签项类型:
paragraph、text。 - 标签文本:优先读取
properties.title。 - 标签图标:若私有 API 中存在
format.page_icon或等价字段,可以作为后续增强;首版不依赖图标能力。
如果某个标签项没有标题,使用 Tab 1、Tab 2 等稳定 fallback。
渲染策略
NotionTabs 不应复制 react-notion-x 的完整 block 分发器。为保持 KISS 和 DRY,建议复用 NotionRenderer 渲染单个 tab item 或其子内容。
推荐结构:
<div className="notion-tabs">
<div className="notion-tabs-list" role="tablist">
<button role="tab" aria-selected={active}>...</button>
</div>
<div className="notion-tabs-panel" role="tabpanel">
<NotionRenderer recordMap={recordMap} blockId={activeTabId} ... />
</div>
</div>为避免渲染标签项标题重复出现在内容区,可以在渲染 active tab 时构造一个轻量 recordMap 副本,将 active tab item 的 properties.title 临时移除,或只渲染 active tab item 的 content 子块。优先选择后者,减少对数据结构的修改。
样式原则
- 标签栏支持横向滚动,避免移动端溢出。
- 默认激活第一个有效标签。
- 保持与
react-notion-x浅色/深色模式类名兼容。 - 不引入新的设计系统或主题配置。
- 不添加全局配置开关,除非后续维护者要求。
备选方案
方案 A:升级 `react-notion-x`
优点是可以减少本项目自定义代码。缺点是当前无法确认新版本已支持 Notion tabs,且依赖升级会影响大量正文渲染路径,PR 风险较高。
结论:不作为首选。
方案 B:修改或复制 `react-notion-x` 的 Block 分发器
优点是可以直接支持新 block type。缺点是会引入较大的维护成本,未来依赖升级容易冲突,也违背 DRY。
结论:不采用。
方案 C:将 tabs 降级为 toggle 或普通文本
优点是实现简单。缺点是用户无法获得 issue 期望的选项卡切换体验,多版本和原文译文对比场景体验明显下降。
结论:仅可作为失败兜底,不作为主要方案。
兼容性
- 不引入破坏性变更。
- 不新增环境变量。
- 不要求用户修改 Notion 数据库字段。
- 不要求主题适配,所有主题通过
NotionPage统一获得支持。 - 旧文章和普通 embed 不受影响。
潜在影响点:
- 如果 Notion 私有 API 返回的 tabs 结构与官方文档不同,首版需要根据真实 recordMap 补充兼容分支。
- 如果某些标签页内容中包含需要全页面上下文的块,单独渲染子内容时要确保
recordMap、mapPageUrl、mapImageUrl仍被正确传递。
文档与测试
测试
建议新增或更新:
__tests__/lib/db/notion/getPostBlocks.test.js- 验证
tab或tabs容器会被转换为embed + notion_tabs。 - 验证
content不丢失。 - 验证普通
embed不受影响。
- 验证
__tests__/components/NotionTabs.test.js- 渲染多个标签按钮。
- 默认展示第一个标签页内容。
- 点击第二个标签后展示对应内容。
- 空标题使用 fallback。
手动验证
建议使用包含 Notion 原生选项卡块的测试页面验证:
- 页面无
Unsupported block type tab/tabs控制台日志。 - 首屏正常展示标签按钮与第一个标签页内容。
- 点击标签可以切换内容。
- 移动端标签栏不溢出布局。
- 深色模式下按钮与面板可读。
当前验证结果
已完成的自动化验证:
yarn jest --testMatch "**/__tests__/**/*.test.js" --runTestsByPath "__tests__\\lib\\db\\notion\\getPostBlocks.test.js" "__tests__\\components\\NotionEmbed.test.js" "__tests__\\components\\NotionTabs.test.js" --runInBand
yarn lint结果:
__tests__/lib/db/notion/getPostBlocks.test.js覆盖tab、tabs容器转换为embed + notion_tabs,并确认content不丢失。__tests__/components/NotionEmbed.test.js覆盖notion_tabs分流,确认无 iframe source 时不会被普通 embed 逻辑吞掉。__tests__/components/NotionTabs.test.js覆盖标签渲染、默认首个 panel、点击切换、空标题 fallback 和富文本标题展平。yarn lint通过;输出为项目既有 warning,无新增 error。
已完成的本地页面验证:
- 测试页面:
http://localhost:3000/article/notion-tabs-test。 - SSR 输出包含
.notion-tabs与.notion-tabs-tab。 - SSR 输出包含三个标签:
是、不是、选项卡 3。 - SSR 输出包含首个标签页正文
阿松大现在才。 - SSR 输出不再包含原始
"type":"tab"。 - 页面 HTML 未出现
Unsupported block type tab。
受限项:浏览器插件在当前 Windows 沙盒中启动失败,因此未完成截图级浏览器自动化验证;本轮以 SSR 检查和组件交互测试作为验证依据。
用户文档
如实现后需要面向用户说明,可在 docs/user-guide/notion/ 下新增短文档,说明 Notion 原生选项卡块已支持,以及推荐使用场景。
实施顺序
- 新增数据层识别逻辑和单元测试。
- 新增
NotionTabs组件和组件测试。 - 在
NotionEmbed中增加最小分流。 - 添加
styles/notion.css样式。 - 跑目标单测和
yarn lint。 - 使用真实页面做 SSR 输出验证。
- 使用浏览器截图验证;当前受 Windows 沙盒中的 Browser 插件启动失败限制。
开放问题
- 需要拿到真实 Notion 私有 API recordMap,确认容器类型到底是
tab、tabs还是其他命名。当前样例确认为tab容器,兼容实现保留tabs。 - 是否需要首版支持标签图标。
- 是否需要键盘左右方向键切换标签。当前已支持
ArrowLeft、ArrowRight、Home、End。 - 是否要让未激活标签页内容保留在 DOM 中以支持浏览器搜索和锚点跳转。
讨论记录
- Issue: https://github.com/notionnext-org/NotionNext/issues/3948
- Notion Block 文档: https://developers.notion.com/reference/block
Developer Themes CLAUDE.En (`docs/developer/themes/CLAUDE.en.md`)
Claude 3.5 Theme
Applies to:
themes/claude(with some global changes inpages/_app.js,pages/index.js, andcomponents/SEO.js)
This theme combines the clean reading experience of Claude Docs with the rich personal profile structure of GitHub, creating a professional yet personal blog for developers.
Core Philosophy
- Reading Experience: Minimal distractions, clear typography (Anthropic Sans/Serif), and excellent code block readability.
- Personal Branding: A homepage that mirrors your GitHub profile (Bio, Activity, Heatmap).
- Data Persistence: Activity and contributions are tracked via Supabase for historical accuracy.
- Performance: Multi-layer caching ensures fast loads and stable rendering.
Quick Start
Configure Environment:
Add to your.envor.env.local(see below for details):bash# Activate Theme NEXT_PUBLIC_THEME=claude # or configure in notion configuration page NOTION_PAGE_ID=<your-notion-page-id> # [Optional] Enable Contribution Persistence (Recommended) SUPABASE_URL=<your-supabase-url> SUPABASE_SECRET_KEY=<your-supabase-key> CLAUDE_CONTRIBUTION_TRIGGER_TOKEN=<secure-token-for-api>Create Profile README:
Create a Notion page with the slugreadme.md. This page will be automatically rendered on your blog homepage.Launch:
bashyarn devYour blog is now running with the Claude theme.
1. Design Strategy
Desktop View
The layout uses a 3-column structure inspired by technical documentation sites:
- Left Sidebar: Persistent navigation, profile card, contact info, and a simulated terminal prompt.
- Center Content: The main reading area, optimized for long-form content.
- Right Sidebar: Table of Contents (TOC) that tracks scrolling position (Article pages only).
Mobile Adaptation
Mobile design is a first-class citizen, not an afterthought:
- Navigation: Collapses into a clean top bar.
- Heatmap: Preserves the square aspect ratio of contribution cells; allows horizontal scrolling instead of shrinking cells.
- Typography: Maintains readability with appropriate font scaling.
- Interactions: Touch-friendly targets for all clickable elements.
2. Features Details
Contribution Heatmap & Activity
The homepage features a GitHub-style contribution graph and activity feed.
- Heatmap: Displays daily contribution levels (0-4) based on article creation and updates.
- Activity Feed: A chronological stream of your "commits" (article updates) and "created repositories" (new articles).
- Yearly View: Switch between a rolling 1-year window or specific calendar years.
README Rendering
Your readme.md Notion page is rendered directly on the homepage, serving as your "Profile README".
- Rendering Pipeline: Notion Blocks -> Markdown -> HTML.
- Engine: Prioritizes GitHub's
/markdownAPI for perfect GFM (GitHub Flavored Markdown) fidelity, falling back to a local parser if the API limit is reached. - Caching: Rendered HTML is cached to prevent redundant API calls and speed up page loads.
Terminal Widget
A dynamic element in the sidebar that shows:
- Last login time (simulated).
- Current "user" and "machine" (e.g.,
user@Macintosh ~ %). - Typing effect for the blog title.
3. Configuration
Config file: themes/claude/config.js
| Config Key | Description | Default |
|---|---|---|
CLAUDE_BLOG_NAME |
Main blog title | '活字印刷' |
CLAUDE_BLOG_NAME_EN |
Subtitle / English title | 'Typography' |
CLAUDE_MENU_CATEGORY |
Show sidebar categories | true |
CLAUDE_MENU_TAG |
Show sidebar tags | true |
CLAUDE_MENU_ARCHIVE |
Show sidebar archives | true |
CLAUDE_TOC_ENABLE |
Enable Table of Contents | true |
CLAUDE_TOC_SHOW_LEVEL3 |
Show H3 in TOC | true |
CLAUDE_TOC_SCROLL_BEHAVIOR |
TOC scroll animation | 'instant' (or 'smooth') |
CLAUDE_PROFILE_AVATAR |
Custom avatar URL | '' (Use global avatar) |
CLAUDE_README_CACHE_ENABLED |
Cache README HTML | true |
CLAUDE_CONTRIBUTION_PERSIST_ENABLED |
Enable Supabase persistence | true |
CLAUDE_CONTRIBUTION_EVENT_LIMIT |
Max events to fetch | 50000 |
Most options can be overridden via
NEXT_PUBLIC_env vars.
4. Environment Variables
To fully enable all features, especially contribution persistence, configure the following in .env.local or your deployment platform.
Basic Setup
NEXT_PUBLIC_THEME=claude
NOTION_PAGE_ID=<your-page-id>Supabase (Required for Persistent Contributions)
Without this, the heatmap is generated on-the-fly from the current post list, which loses historical accuracy (e.g., deleted posts, precise update times).
NEXT_PUBLIC_CLAUDE_CONTRIBUTION_PERSIST_ENABLED=true
# Supabase Connection
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SECRET_KEY=your-service-role-key-or-secretAdvanced Cache Control
# Enable internal caching (recommended)
ENABLE_CACHE=true
# Optional: Use Redis for distributed caching
REDIS_URL=redis://user:pass@host:port5. Database Schema (Supabase)
If using Supabase, create these two tables to store contribution data.
1. Events Table (`claude_contribution_events_v1`)
Stores individual contribution events (create/update).
create table if not exists public.claude_contribution_events_v1 (
event_id text primary key, -- e_md5(type|repoId|ts)
event_type text not null check (event_type in ('create', 'update')),
repository_id text not null, -- Normalized Post ID
timestamp_ms bigint not null,
title text default '',
slug text default ''
);
-- Indices for performance
create index if not exists idx_claude_contrib_events_ts
on public.claude_contribution_events_v1 (timestamp_ms desc);
create index if not exists idx_claude_contrib_events_repo
on public.claude_contribution_events_v1 (repository_id);2. Snapshots Table (`claude_contribution_snapshots_v1`)
Tracks the state of posts to detect changes during builds.
create table if not exists public.claude_contribution_snapshots_v1 (
repository_id text primary key,
title text default '',
slug text default '',
created_at_ms bigint not null default 0,
updated_at_ms bigint not null default 0,
synced_at_ms bigint not null default 0
);
create index if not exists idx_claude_contrib_snapshots_updated
on public.claude_contribution_snapshots_v1 (updated_at_ms desc);Update Logic
- Sync: On build (
getStaticPropsof index), the system compares current Notion posts againstsnapshots. - Detect:
- New post? -> Insert
createevent. - Updated post (
updatedAt > lastSnapshot.updatedAt)? -> Insertupdateevent.
- New post? -> Insert
- Persist: Updates are upserted to Supabase.
- Display: The heatmap reads from the
eventstable (filtered to exclude today to prevent jitter).
6. Caching Strategy
The theme employs a multi-level caching strategy for stability.
Contribution Daily Cache (Local Memory):
- Aggregates events for the day.
- Reduces database reads.
- Refreshes on new builds or via API.
README HTML Cache:
- Caches the expensive GitHub API markdown rendering.
- Key:
readme_render_snapshot_v2_${pageId}.
GitHub Markdown API Cache:
- Caches the raw response from GitHub to avoid rate limits (60 requests/hr for unauthenticated IPs).
- Fallback: If the API fails or limits, falls back to a local
marked+highlight.jsrenderer.
7. Troubleshooting
Q: My heatmap is empty.
- Ensure
NEXT_PUBLIC_CLAUDE_CONTRIBUTION_PERSIST_ENABLED=true. - Check if Supabase tables exist and keys are correct.
- Verify
NOTION_PAGE_IDallows access to the posts.
Q: Changes made today are not showing.
- By design, the heatmap shows data up to yesterday to ensure the grid is stable and complete. Today's dots appear tomorrow.
- You can force a refresh manually if needed via the refresh API.
Q: The README styling looks different.
- This usually means the GitHub API rate limit was hit, and the theme fell back to the local renderer. It will recover automatically when the cache expires or the limit resets.
8. Sidebar Persistence Architecture
Problem
In Next.js Pages Router, every client-side navigation can re-render or even remount LayoutBase. This causes the left sidebar (avatar, terminal widget, navigation) to reload on every page transition.
Three-Layer Solution
The theme uses three layers so the sidebar only refreshes on browser refresh:
Layer 1: `pages/_app.js` — Stabilize the Layout Component Reference
Merge warning: this modification is in global
pages/_app.js, not inside the claude theme directory.
The original code had two problems:
themememo depended on the entirerouteobject ([route]), which changes reference every route change.GLayoutwrapper insideMyAppcalledgetBaseLayoutByTheme(theme)on each render.
The fix:
const theme = useMemo(() => {
return (
getQueryParam(route.asPath, 'theme') ||
pageProps?.NOTION_CONFIG?.THEME ||
BLOG.THEME
)
}, [route.asPath, pageProps?.NOTION_CONFIG?.THEME])
const Layout = useMemo(() => getBaseLayoutByTheme(theme), [theme])
<Layout {...pageProps}>
<SEO {...pageProps} />
<Component {...pageProps} />
</Layout>Layer 2: `themes/claude/index.js` — Memoized SidebarContent
Desktop sidebar is wrapped with React.memo(() => true) to block parent-prop-driven rerenders.
Layer 3: `themes/claude/components/NavBar.js` — Module-Level Terminal Session Cache
Terminal login time and tty are stored in module-level variables outside React lifecycle, so they survive remounts and reset only on full refresh.
Files Affected
| File | Scope | Change |
|---|---|---|
pages/_app.js |
Global | Removed GLayout; memoized Layout reference |
themes/claude/index.js |
Theme | Added SidebarContent memo wrapper |
themes/claude/components/NavBar.js |
Theme | Terminal session moved to module cache |
9. Development
Project Structure
themes/claude/components/: UI components (NavBar, Catalog, etc.)themes/claude/style.js: CSS variables and global styleslib/server/claude/contributionStore.js: Supabase logicpages/api/claude/: API endpoints for cache revalidation
Commands
yarn dev: Run locallyyarn build: Production build (triggers contribution sync)
10. Additional Global Changes (RSS + Homepage Title)
These changes are outside themes/claude but affect runtime behavior.
10.1 Stop RSS content fetching when RSS is disabled
- File:
pages/index.js - Change:
generateRss(props)now runs only whenENABLE_RSS=true.
10.2 Remove subtitle from homepage ``
- File:
components/SEO.js - Route:
/ - Change: homepage title changed from
site title | site descriptiontosite titleonly.
10.3 Merge / Upgrade Notes
When pulling upstream updates, verify:
pages/_app.jsstill memoizesLayoutwithuseMemo(() => getBaseLayoutByTheme(theme), [theme]).themememo deps stay as[route.asPath, pageProps?.NOTION_CONFIG?.THEME], not[route].- No wrapper component reintroduces indirect
getBaseLayoutByThemecalls. pages/index.jskeeps RSS generation gated byENABLE_RSS.components/SEO.jskeeps homepage title as site title only.
Developer Themes CLAUDE (`docs/developer/themes/CLAUDE.md`)
Claude Theme README
适用目录:
themes/claude(部分修改涉及全局pages/_app.js、pages/index.js、components/SEO.js)本文档描述当前
claude主题的实际实现,重点覆盖:
- 主题特性与视觉设计目标
- 文章页(Claude Code Docs 风格)与首页(GitHub Profile 风格)
- 移动端复刻与优化策略
- Contribution 热力图生成逻辑
- 数据库设计与更新逻辑
- 缓存设计
- 配置项与环境变量说明
- 如何启用并使用该主题
- 侧边栏持久化架构(含全局
_app.js修改,合并时需注意)
1. 主题定位与核心特性
claude 主题是一个“混合型”主题:
- 文章阅读体验:参考 Claude Code Docs 的排版与色彩体系。
- 首页信息架构:1:1 借鉴 GitHub 个人主页(头像、资料、联系方式、贡献热力图、活动流)。
- 交互策略:内容优先、低干扰、轻动效。
- 数据策略:首页活动数据支持持久化到 Supabase,避免每次都从前端即时推导。
主要能力:
- 三栏布局(左侧资料栏 / 中间正文 / 右侧 TOC)。
- 文章页 Notion 原生渲染(
NotionPage)+ 主题化样式。 - 首页 README 卡片:Notion blockMap 转 Markdown,再转 HTML 渲染。
- GitHub 风格 Contribution 热力图 + 活动摘要流。
- Contribution 事件持久化(
create/update)与去重。 - 多层缓存(页面缓存、README 缓存、Contrib 日缓存)与失败回退。
快速开始 (Quick Start)
只需要简单三步即可体验:
配置环境变量:
在.env或.env.local中添加(完整配置见下文):bash# 启用主题 NEXT_PUBLIC_THEME=claude # 或者在notion配置页面中配置 NOTION_PAGE_ID=<your-notion-page-id> # [可选] 启用贡献热力图持久化 (推荐) SUPABASE_URL=<your-supabase-url> SUPABASE_SECRET_KEY=<your-supabase-key> CLAUDE_CONTRIBUTION_TRIGGER_TOKEN=<secure-token-for-api>创建个人资料页:
在 Notion 中新建一个页面,并将其 slug 设置为readme.md。该内容将显示在首页。启动:
bashyarn dev
2. 目录结构与关键文件
主题核心文件:
themes/claude/index.js- 主题布局入口(
LayoutBase/LayoutIndex/LayoutSlug等)。
- 主题布局入口(
themes/claude/style.js- 主题变量与全量样式(含桌面/移动端规则)。
themes/claude/config.js- 主题配置项与默认值。
themes/claude/components/ProfileHome.js- 首页 README、热力图、Contribution activity 逻辑。
themes/claude/components/NavBar.js- 左侧资料栏(头像、联系方式、导航、终端模拟块)。
themes/claude/components/MenuList.js- 菜单渲染与 icon 规则(支持 Notion icon 字段写 Font Awesome)。
themes/claude/components/Catalog.js- 右侧目录(TOC)与滚动联动。
服务端数据链路相关:
pages/index.js- 首页
getStaticProps:README 渲染、Contrib 同步、缓存回退。
- 首页
lib/server/claude/contributionStore.js- Supabase 读写、事件生成、去重、日缓存。
lib/db/notion/notionBlocksToHtml.js- Notion blockMap -> Markdown -> HTML(GitHub API 优先,本地回退)。
pages/api/claude/contribution-refresh.js- 手动刷新 Contribution 缓存与 ISR 触发。
3. 文章样式(仿 Claude Code Docs)
3.1 布局风格
文章页采用 LayoutSlug + NotionPage 渲染正文,外层由 LayoutBase 提供:
- 左侧固定宽资料/导航区域。
- 中间内容区(多档
max-w-*宽度控制)。 - 右侧目录区(文章页 + 桌面端 + TOC 开启时显示)。
3.2 样式体系
themes/claude/style.js 中定义了大量 CSS 变量:
- 配色变量:正文、边框、强调色、暗色模式等。
- 字体变量:
- 标题:
Anthropic Serif Display - 正文:
Anthropic Sans Text - 等宽:
JetBrains Monofallback 链
- 标题:
- Notion 内容区域样式覆写:链接、引用、代码、表格、callout、目录高亮等。
3.3 目录(TOC)行为
目录组件:themes/claude/components/Catalog.js
- 支持 L1/L2 必显。
- L3 由
CLAUDE_TOC_SHOW_LEVEL3控制。 - 滚动监听并高亮当前 section,同时联动父级。
On this page标题可回到顶部。- 滚动行为支持
smooth或instant(CLAUDE_TOC_SCROLL_BEHAVIOR)。
4. 首页(1:1 GitHub Profile 复刻)
首页组件:themes/claude/components/ProfileHome.js
从上到下主要区块:
- README 卡片(
README.md标签头 + 内容区) - Contribution 热力图区块
- Contribution activity 时间流
左侧资料栏组件:themes/claude/components/NavBar.js
- 圆形头像(GitHub 风格)。
- 昵称 + Bio。
- 联系方式(GitHub / Email)。
- 导航菜单(支持图标)。
- 终端模拟区:
- 第一行:
Last login: ... on ttys00x - 第二行:
{author}@Macintosh ~ % {blogName}+ 光标 - 通过
ResizeObserver自动缩放字体,尽量保证同一行展示。
- 第一行:
5. 移动端复刻与优化
移动端保留“与桌面一致的字体风格和信息层级”,但对结构做适配:
- 左侧栏折叠为顶部简化导航。
- Contribution 热力图容器允许横向滚动(保持 cell 尺寸,不压缩方块)。
- 滚动条隐藏但可滑动。
- Year 选择器改为移动端友好的下拉菜单,放在
Contribution activity标题行。 - README / 活动卡片边距与圆角在窄屏下重新平衡。
实现重点:
- 桌面端 cell 尺寸随宽度动态计算。
- 移动端强制固定
contribCellSize=11,避免字体/格子被缩放破坏视觉一致性。
6. Contribution 热力图生成逻辑
核心代码:themes/claude/components/ProfileHome.js
6.1 输入数据
优先使用持久化事件(props.contributionEvents):
type:create或updaterepositoryIdtimestampMstitle/slug
如果持久化不可用,则回退到前端从 posts 直接推导:
- 每篇文章产生一个
create(createdAt) - 若更新时间与创建时间不同,再产生一个
update(updatedAt)
6.2 统计区间
两种模式:
- 默认模式:最近 1 年(滚动窗口)
- 年份模式:固定某一年(1 月 1 日到 12 月 31 日)
区间会对齐到整周边界:
- 起点对齐到周日
- 终点对齐到周六
6.3 颜色分级(level)
CONTRIBUTION_LEVEL_THRESHOLDS:
0: 无贡献1:count === 12:count >= 23:count >= 34:count >= 6
说明:1 contribution/day 必须稳定映射到同一颜色等级。
6.4 月标签策略
默认滚动年模式:
- 按周列起始日期所属月份生成 marker(接近 GitHub 视觉规则)。
固定年份模式:
- 每个月从当月第一天所在周列生成 marker。
6.5 交互
- Hover cell 显示 tooltip(延迟触发,避免抖动)。
- 点击某一天可过滤下方 activity(再次点击取消)。
Less/Morelegend 与热力图颜色等级一致。
7. Contribution Activity 生成逻辑
核心代码仍在 themes/claude/components/ProfileHome.js。
渲染策略:
- 默认按“月”分组(如 March 2026)。
- 点选某一天后,切换成“日”分组(如 March 3, 2026)。
- 组内分别聚合:
update事件 -> commit summary(按仓库聚合,统计 commitCount)create事件 -> created repositories 列表
显示逻辑:
- 无数据时展示 empty state。
- 有更新和创建则分别渲染摘要行。
- 链接点击跳转对应文章。
8. 数据库设计(Supabase)
服务端存储实现:lib/server/claude/contributionStore.js
使用两张表:
claude_contribution_events_v1claude_contribution_snapshots_v1
8.1 推荐表结构
create table if not exists public.claude_contribution_events_v1 (
event_id text primary key,
event_type text not null check (event_type in ('create', 'update')),
repository_id text not null,
timestamp_ms bigint not null,
title text default '',
slug text default ''
);
create index if not exists idx_claude_contrib_events_ts
on public.claude_contribution_events_v1 (timestamp_ms desc);
create index if not exists idx_claude_contrib_events_repo
on public.claude_contribution_events_v1 (repository_id);
create table if not exists public.claude_contribution_snapshots_v1 (
repository_id text primary key,
title text default '',
slug text default '',
created_at_ms bigint not null default 0,
updated_at_ms bigint not null default 0,
synced_at_ms bigint not null default 0
);
create index if not exists idx_claude_contrib_snapshots_updated
on public.claude_contribution_snapshots_v1 (updated_at_ms desc);8.2 字段语义
events 表:
event_id:事件主键,规则为e_${md5(type|repositoryId|timestampMs)}event_type:create/updaterepository_id:文章 ID 归一化(去-+ 小写)timestamp_ms:事件时间戳(毫秒)title/slug:冗余展示信息
snapshots 表:
repository_id:文章唯一标识(主键)created_at_ms:创建时间updated_at_ms:最近更新时间synced_at_ms:本次同步时间
9. 更新逻辑(从 Notion 到数据库)
入口:pages/index.js 的 getStaticProps。
9.1 同步步骤
- 获取已发布文章(排除
readme.md)。 - 每篇文章构建 snapshot:
repositoryIdcreatedAtMsupdatedAtMs
- 调用
syncContributionSnapshots(snapshots):- upsert snapshot(冲突键
repository_id) - 根据“新旧快照差异”生成事件
- upsert snapshot(冲突键
- 拉取事件
listContributionEvents(limit)。 - 过滤到“昨天为止”:
filterContributionEventsUntilYesterday- 当天事件不显示在首页(稳定 UI,避免当天多次刷新抖动)
- 写入本地日缓存,返回给前端。
9.2 事件生成规则(关键)
在 syncContributionSnapshots 内:
- 若快照不存在(新文章):
- 创建
create事件(created_at_ms) - 如果
updated_at_ms > created_at_ms,再创建update事件
- 创建
- 若快照已存在:
- 仅当
updated_at_ms大于旧快照时,新增update事件
- 仅当
- 事件写入前按
event_id去重,保证同一逻辑事件只存在一份。
10. 缓存设计
本主题使用多层缓存,目标是减少重复请求并提高稳定性。
10.1 Contribution 日缓存(进程内)
位置:lib/server/claude/contributionStore.js
- 缓存键:
globalThis.__claude_contribution_daily_cache_v1 - 内容:
dayKey/events/updatedAtMs/dirty - 刷新条件:
- 手动强制(
CLAUDE_CONTRIBUTION_FORCE_REFRESH=true) - build/export 阶段
- 当日尚未刷新
- 通过 API 标记
dirty
- 手动强制(
失败回退:
- 刷新失败时优先使用 stale 缓存(
allowStale=true) - 仍不可用则回退到前端即时计算
10.2 README 快照缓存
位置:pages/index.js
- 键:
readme_render_snapshot_v2_${pageId}_${locale} - 缓存内容:
bodyFingerprintexcerptreadmeHtmlreadmeHtmlSource
- 逻辑:
- 若正文指纹未变,直接复用缓存 HTML
- 若变化,重新执行转换与渲染
10.3 GitHub Markdown API 缓存
位置:lib/db/notion/notionBlocksToHtml.js
- 键:
readme_github_md_${md5(markdown)} - 策略:
- 先查缓存,命中直接返回。
- 调 GitHub
/markdownAPI。 - API 失败/超限,再查一次缓存。
- 仍失败则回退到本地
marked + highlight.js。
说明:GitHub 匿名接口有速率限制,本层缓存用于显著降低超限概率。
10.4 全站缓存后端
统一缓存门面:lib/cache/cache_manager.js
- 优先 Redis(
REDIS_URL) - 否则文件缓存(
ENABLE_FILE_CACHE) - 否则内存缓存(开发 120 分钟,生产 10 分钟)
11. README 渲染链路
目标:在首页 README 卡片中稳定展示富文本与代码高亮,避免 hydration 相关问题。
当前实现:
- 从 Notion 拉
readme.md的blockMap notionBlocksToMarkdown(blockMap, pageId)转 MarkdownrenderMarkdownToHtml(markdown)转 HTML- 优先 GitHub API
- 失败则本地 fallback
- 前端
ProfileHome直接渲染:- ``
样式来源:
styles/claude-readme.css导入 GitHub Markdown CSS_app.js导入highlight.js主题(本地 fallback 时生效)
12. 配置项说明(Claude 主题)
配置文件:themes/claude/config.js
以下配置可由环境变量覆盖(NEXT_PUBLIC_*),并可被 Notion 配置页同名项再覆盖:
| 配置项 | 默认值 | 说明 |
|---|---|---|
CLAUDE_BLOG_NAME |
活字印刷 |
主题主标题 |
CLAUDE_BLOG_NAME_EN |
同主标题 | 副标题/英文标题 |
CLAUDE_POST_AD_ENABLE |
false |
列表插广告 |
CLAUDE_POST_COVER_ENABLE |
false |
列表显示封面 |
CLAUDE_ARTICLE_RECOMMEND_POSTS |
true |
文章页推荐文章 |
CLAUDE_MENU_CATEGORY |
true |
显示分类菜单 |
CLAUDE_MENU_TAG |
true |
显示标签菜单 |
CLAUDE_MENU_ARCHIVE |
true |
显示归档菜单 |
CLAUDE_TOC_ENABLE |
true |
启用右侧目录 |
CLAUDE_TOC_SHOW_LEVEL3 |
true |
目录显示三级标题 |
CLAUDE_TOC_SCROLL_BEHAVIOR |
instant |
TOC 点击/联动滚动行为 |
CLAUDE_SUBTITLE_DARK_ONLY |
false |
副标题仅暗色显示 |
CLAUDE_PROFILE_AVATAR |
'' |
侧栏头像 URL |
CLAUDE_FOOTER_COPYRIGHT |
'' |
自定义页脚版权文案 |
CLAUDE_README_CACHE_ENABLED |
true |
README 快照缓存开关 |
CLAUDE_CONTRIBUTION_PERSIST_ENABLED |
true |
Contribution 持久化开关 |
CLAUDE_CONTRIBUTION_EVENT_LIMIT |
50000 |
拉取事件上限 |
13. 环境变量说明
13.1 必需(最小可运行)
NEXT_PUBLIC_THEME=claude
NOTION_PAGE_ID=<your notion database/page id>13.2 Notion 访问(可选,私有库常用)
NOTION_TOKEN_V2=<token_v2>
NOTION_ACTIVE_USER=<optional>说明:
NOTION_TOKEN_V2:用于访问非公开 Notion 数据。NOTION_ACTIVE_USER:可选,不填时使用 token 仍可工作(取决于 Notion 侧权限)。
13.3 Contribution 持久化(Supabase)
NEXT_PUBLIC_CLAUDE_CONTRIBUTION_PERSIST_ENABLED=true
NEXT_PUBLIC_CLAUDE_CONTRIBUTION_EVENT_LIMIT=50000
SUPABASE_URL=<https://xxx.supabase.co>
SUPABASE_SECRET_KEY=<service key> # 或 SUPABASE_SERVICE_ROLE_KEY
# 可选前端命名回退
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY=补充控制项:
CLAUDE_CONTRIBUTION_FORCE_REFRESH=false
CLAUDE_CONTRIBUTION_TRIGGER_TOKEN=<optional token>13.4 README 缓存与全站缓存
NEXT_PUBLIC_CLAUDE_README_CACHE_ENABLED=true
ENABLE_CACHE=true
REDIS_URL=<optional>14. 如何使用该主题
步骤 1:切换主题
在 .env.local:
NEXT_PUBLIC_THEME=claude步骤 2:准备首页 README 页面
在 Notion 中准备一个页面,slug 必须为:
readme.md首页会自动识别该页面并渲染到 README 卡片。
步骤 3:可选启用 Contribution 持久化
- 在 Supabase 创建两张表(见第 8 节 SQL)。
- 配置 Supabase 环境变量。
- 打开
NEXT_PUBLIC_CLAUDE_CONTRIBUTION_PERSIST_ENABLED=true。
步骤 4:启动
yarn dev生产构建:
yarn build
yarn start步骤 5:手动触发贡献刷新(可选)
接口:/api/claude/contribution-refresh
示例:
curl "http://localhost:3000/api/claude/contribution-refresh?token=<token>&revalidate=1&path=/"15. 运行日志与排障
15.1 日志前缀
- Contribution:
[Contrib] ... - README 渲染:
[README] ...
注意:这些日志在服务端终端输出,不在浏览器控制台。
15.2 常见问题
- 热力图无数据
- 检查
NEXT_PUBLIC_CLAUDE_CONTRIBUTION_PERSIST_ENABLED是否为true - 检查 Supabase 连接变量是否正确
- 检查两张表是否已创建
- 当天更新未显示
- 当前逻辑默认过滤“今天”的事件,只显示到昨天(设计行为)
- README 代码块高亮不稳定
- 若 GitHub
/markdown超限会自动回退到本地marked + highlight.js - 可通过缓存复用此前成功渲染结果
16. 侧边栏持久化架构
16.1 问题背景
在 Next.js Pages Router 中,每次客户端导航(点击链接跳转)都会重新渲染甚至重新挂载(remount)LayoutBase。这导致左侧栏(头像、终端模拟块、导航菜单)每次跳转都重新加载,用户体验不佳。
16.2 三层防护方案
本主题通过三层机制确保左侧栏仅在浏览器刷新时才重新加载:
第一层:`pages/_app.js` — 从根源消除 Layout 组件 remount
::: warning 合并注意:此修改位于全局 pages/_app.js,非 claude 主题目录内。合并时请特别关注此文件。
:::
原始代码存在两个问题:
theme的useMemo依赖整个route对象([route])。useRouter()每次路由变化都返回新的对象引用,导致theme每次都重新计算。GLayout是在组件内部通过useCallback定义的包装组件,每次渲染都在内部调用getBaseLayoutByTheme(theme)。
修复后:
// 依赖改为具体值,而非整个 route 对象
const theme = useMemo(() => {
return (
getQueryParam(route.asPath, 'theme') ||
pageProps?.NOTION_CONFIG?.THEME ||
BLOG.THEME
)
}, [route.asPath, pageProps?.NOTION_CONFIG?.THEME])
// 用 useMemo 缓存 Layout 组件引用,相同 theme 下始终返回同一个组件
const Layout = useMemo(() => getBaseLayoutByTheme(theme), [theme])
// 直接使用 Layout,不再通过 GLayout 包装
<Layout {...pageProps}>
<SEO {...pageProps} />
<Component {...pageProps} />
</Layout>关键效果:Layout(即 LayoutBase)在同一主题下始终是同一个组件引用,React 不会因组件类型变化而 remount 整棵子树。
第二层:`themes/claude/index.js` — SidebarContent 记忆化
桌面端侧边栏用 React.memo(() => true) 包裹:
const SidebarContent = memo(function SidebarContent(props) {
return (
<div className='flex flex-col justify-between h-full py-6 px-5'>
<div><NavBar {...props} /></div>
<div className='mt-auto'><Footer /></div>
</div>
)
}, () => true) // 始终返回 true -> 阻止所有来自父组件的 prop 变化触发重渲染React.memo的第二个参数() => true表示"props 始终相等",阻止父组件 re-render 传播。MenuList内部的useRouter()基于 React Context,路由变化仍会绕过 memo 正常更新菜单激活状态。
第三层:`themes/claude/components/NavBar.js` — 模块级终端会话缓存
终端区域的登录时间和 tty 编号存储在 JS 模块级变量(非 React 状态)中:
let _cachedTerminalSession = null
function getOrCreateTerminalSession() {
if (!_cachedTerminalSession) {
_cachedTerminalSession = {
loginTime: formatTerminalLoginTime(new Date()),
tty: `ttys00${Math.floor(Math.random() * 10)}`
}
}
return _cachedTerminalSession
}- 模块级变量在 JS 模块作用域中,不属于任何 React 组件实例。
- 即使极端情况下组件被 remount,缓存值不会丢失。
- 只有浏览器刷新(JS 模块重新加载)时才重置。
16.3 涉及文件清单
| 文件 | 所属 | 修改内容 |
|---|---|---|
pages/_app.js |
全局(非主题目录) | 移除 GLayout,用 useMemo 缓存 Layout 引用 |
themes/claude/index.js |
主题 | 新增 SidebarContent memo 组件 |
themes/claude/components/NavBar.js |
主题 | 终端会话改为模块级缓存 |
17. 设计约束与已知行为
claude主题只影响自身主题目录,但侧边栏持久化修改涉及全局pages/_app.js(见第 16 节)。- Contribution 事件是幂等写入,不应重复产生同一
create事件。 - README 渲染采用“服务端转换 + 前端静态 HTML 注入”,目标是稳定优先。
- 移动端优先保持桌面视觉语言一致,不随屏宽自动降级字体粗细/大小。
18. 维护建议
- 如果你修改了热力图规则,请同步更新:
themes/claude/components/ProfileHome.js- 本 README 的第 6、7 节
- 如果你修改了表字段,请同步更新:
lib/server/claude/contributionStore.js- 本 README 的第 8、9 节 SQL 与字段说明
- 如果你修改了缓存策略,请同步更新:
lib/cache/*pages/index.jslib/db/notion/notionBlocksToHtml.js
19. 全局改动补充(RSS 与首页标题)
以下变更位于主题目录之外,但会直接影响 claude 主题实际运行行为:
19.1 RSS 关闭时不再触发 RSS 内容抓取
- 文件:
pages/index.js - 变更:
generateRss(props)从“无条件执行”改为“仅在ENABLE_RSS=true时执行”。 - 结果:
- 当你禁用 RSS 后,不再调用
getPostBlocks(..., 'rss-content')。 - 服务端日志中的
from:rss-content不会再出现。
- 当你禁用 RSS 后,不再调用
19.2 首页标签页标题不再拼接副标题
- 文件:
components/SEO.js - 路由:
/(首页) - 变更:首页 title 从
site title | site description改为仅显示site title。 - 结果:
- 未配置副标题时,不会再出现默认文案“这是一个由NotionNext生成的站点”。
- 分隔符
|也不会显示。
19.3 ⚠️ 合并 / 升级注意(汇总)
若后续合并上游更新,请统一检查以下项是否仍保留:
pages/_app.js中Layout仍通过useMemo(() => getBaseLayoutByTheme(theme), [theme])缓存引用(见第 16.2 节第一层)。pages/_app.js中theme的useMemo依赖仍为[route.asPath, pageProps?.NOTION_CONFIG?.THEME],而非[route]。pages/_app.js中仍不使用useCallback包装组件来间接调用getBaseLayoutByTheme。pages/index.js里 RSS 生成仍受ENABLE_RSS开关控制。components/SEO.js里首页 title 仍仅使用主标题,不拼接 description。
Developer Themes ENDSPACE.En (`docs/developer/themes/ENDSPACE.en.md`)
Endspace Theme (NotionNext)
Endspace is a NotionNext theme inspired by the visual language of Arknights: Endfield’s official site, maintained by the community. Upstream repository: cloud-oc/endspace. Tracking issue: #3990.
Original author / upstream: @cloud-oc (cloud-oc/endspace).
Enable
- Install dependencies at the repo root (
yarn install):@tabler/icons-reactremixicon-react
- Set
THEME/NEXT_PUBLIC_THEMEtoendspace. - Tune
ENDSPACE_*keys inthemes/endspace/config.jsas needed.
Features
- Industrial sci-fi layout, optional immersive loading sequence.
- Desktop side rail + mobile bottom navigation; includes an integrated music player widget.
- Article pages wrap
NotionPageinside#article-wrapper. - Optional
NESTanimation:#__nestis the mount point used bypublic/js/nest.js(this port sets nest attributes viaref+useEffectto avoid invalid React DOM props).
License
Upstream theme is from cloud-oc/endspace and is licensed under Apache-2.0. The NotionNext repository remains primarily MIT; if you redistribute this theme’s code, comply with Apache-2.0 attribution/notice/reciprocal terms (full text: https://www.apache.org/licenses/LICENSE-2.0).
Preview asset
Theme preview: public/images/themes-preview/endspace.webp (generated from endspace.png in the same folder). After updating the PNG, run yarn perf:compress-theme-previews to regenerate WebP.
Maintenance
Follow the Theme migration guide for data/prop conventions (menus, dark mode, comments, TOC, etc.). Upstream ships the theme as a single package on the theme branch—prefer directory-level diffs when syncing updates.
Developer Themes ENDSPACE (`docs/developer/themes/ENDSPACE.md`)
Endspace 主题(NotionNext)
Endspace 是受《明日方舟:终末地》官网视觉风格启发的 NotionNext 主题,由社区作者维护;上游仓库见 cloud-oc/endspace。收录相关讨论见 Issue #3990。
原作者 / 上游:@cloud-oc(仓库 cloud-oc/endspace)。
启用方式
- 安装依赖(根目录已声明,首次拉代码后执行
yarn install):@tabler/icons-reactremixicon-react
- 环境变量或 Notion 配置中将主题设为
endspace(与blog.config.js中THEME说明一致)。 - 按需调整
themes/endspace/config.js中的ENDSPACE_*配置项。
功能概览
- 工业科幻风布局与动效(含可选全屏加载序列)。
- 桌面端左侧竖向导航 + 移动端底栏;集成音乐播放器组件等。
- 文章区使用
article-wrapper包裹NotionPage,与全站文章渲染能力兼容。 - 可选
NEST背景动效:在#__nest挂载点上由public/js/nest.js创建画布(收录版通过ref写入 nest 所需 DOM 属性,避免无效 React DOM 属性)。
许可
主题来源于 cloud-oc/endspace,上游以 Apache-2.0 授权。NotionNext 主仓库整体仍以 MIT 为主;若你二次分发该主题代码,请同时遵守 Apache-2.0 对归属、NOTICE 与再许可条款的要求(完整文本见 https://www.apache.org/licenses/LICENSE-2.0)。
预览图
主题预览为 public/images/themes-preview/endspace.webp;源图为同目录 endspace.png。更新截图后可运行 yarn perf:compress-theme-previews 重新生成 webp。
维护注意
- 与 主题迁移指南 对齐:菜单、暗色模式、评论、TOC 等应走 NotionNext 全局约定。
- 上游
theme分支为单一主题包;若上游更新,建议以目录为单位对比合并。
Developer Themes FUWARI (`docs/developer/themes/FUWARI.md`)
Fuwari Theme (NotionNext)
This is the NotionNext port of the Fuwari visual style.
Upstream Reference
- Source project: saicaca/fuwari
- Demo site: fuwari.vercel.app
Design Goal
- Keep Fuwari's card-based visual language and light interaction feeling.
- Stay fully compatible with NotionNext data flow and feature modules.
Key Features in This Port
- Data-driven menu (
customNav,CUSTOM_MENU + customMenu) - Full-width Hero with Notion cover priority (
siteInfo.pageCover) - Left sidebar + right content layout (desktop default)
- Post list dual layout (with-cover / without-cover)
- Right-side readmore action rail
- Profile card + social links row (
CONTACT_*keys) - Announcement block, TOC, analytics, ads, plugin slots
- Global dark mode integration via NotionNext context
Online Theme Color Picker
The top-right palette button opens a floating hue panel (Fuwari-like UX):
- Real-time color preview for key theme elements
- Persisted in browser local storage
- Operators can copy hue/hex and write default into config
Related config keys:
FUWARI_WIDGET_THEME_COLOR_SWITCHERFUWARI_THEME_COLOR_FIXEDFUWARI_THEME_COLOR_HUE
Important Config Keys
- Layout/menu:
FUWARI_MENU_*FUWARI_PROFILE_PATH
- Hero:
FUWARI_HERO_ENABLEFUWARI_HERO_BG_IMAGEFUWARI_HERO_CREDIT_TEXTFUWARI_HERO_CREDIT_LINK
- Post list:
FUWARI_POST_LIST_*
- Article:
FUWARI_ARTICLE_*
- Sidebar widgets:
FUWARI_WIDGET_*
Migration Notes
For migration guidance and pitfalls, see:
docs/THEME_MIGRATION_GUIDE.mddocs/THEME_MIGRATION_GUIDE.zh-CN.md
Developer Themes HEO (`docs/developer/themes/HEO.md`)
HEO 主题文档(已合并)
本站 Heo 说明已统一维护在:
请勿再编辑本文件;修改请直接改 heo.md。
Developer Themes PROXIO (`docs/developer/themes/PROXIO.md`)
Proxio 主题文档(已合并)
本站 Proxio 说明已统一维护在:
docs/user-guide/themes/proxio.md
请勿再编辑本文件;修改请直接改 proxio.md。
--- METRICS ---
- Files Extracted: 93
- Estimated Token Budget: ~70720 tokens
- Canonical Reference: https://codewiki.google/github.com/tangly1024/NotionNext