用next.js来实现兼容obsidian的博客系统
08:34
阅读次数: 0最近在用nextjs实现新的博客系统。
之前一直没有找到obsidian发布笔记的合适办法。 obsidian发布笔记,一类方案是使用hexo之类的框架,手动生成,意味着发布的时候,需要手动构建一次。通过github管理的话,还需要处理各种冲突。
最终选择采用nextjs
和cloudflare pages
为什么使用nextjs呢?因为nextjs 的笔记来源,可以直接从对象存储中获得,而对象存储可以通过我本地的obsidian来直接上传,这样,就可以使用本地obsidian来编辑博客,更新的时候,直接使用remote save插件,把本地文档上传到oss中。
下面说下几个主要的步骤
remotely save + obsidian
在obsidian中,创建一个新的仓库,安装remotely save插件。
配置remotely save插件,使得本地的内容同步到对象存储中,这里我使用的是cloudflare的对象存储R2
。因为cloudflare还可以直接通过pages
来访问R2
或者 KV
数据库。
具体的配置方法,参照 remotely save
插件官网的描述。
cloudflare pages
这里使用 cloudflare pages
创建一个nextjs项目。
在next项目中,使用app router 定义一个read/[slug]/page.tsx的路由。 这个页面是承载文章的。
通过路径中的slug参数,获取当前访问的文章路径。路径一定是encode的。
通过getRequestContext
函数获取R2对象存储。
const myR2 = getRequestContext().env.MY_BLOG_BUCKET; const blogResponse = await myR2.get(decodeURIComponent(slug));
markdown
因为obsidian的笔记都是markdown格式的,可以直接使用react-markdown相关的插件,直接把对象存储中的文件渲染为html
这里,经过最终比较,我选用了react-markdown
这个包,非常适配于react。
还可以通过自定义组件,实现更丰富的功能。
<Markdown remarkPlugins={[remarkGfm]} components={{ img: ({ src, alt }) => ( <Img src={src || ""} alt={alt || ""} /> ), code: ({ node, className, children, ...props }) => ( <CodeWordAI {...props}>{children}</CodeWordAI> ), pre: ({ node, className, children, ...props }) => ( <Pre {...props}>{children}</Pre> ), a: ({ node, className, children, ...props }) => ( <A {...props}>{children}</A> ), }} > {finalContent} </Markdown>
踩坑
nextjs 的 缓存管理一直有点问题,使用unstable_cache
非常容易不成功。
如果要缓存页面,其实直接使用cloudflare
的cache rules
就行,配置缓存规则之后,当前页面下的所有内容都会被缓存到CDN
。
这里再次感谢cloudflare
大善人