一直认为 Docusaurus 默认的博客文章页面太过单调,可能对于只是在网上找一地方单纯记录文字的人来说已经够了。但是我是把它打造成一个用户体验很棒的知识分享产品来打造。
首先我们来看看一个好的博客或者也可以扩大点范围叫 Web 信息资讯类产品都有哪些功能?
- 社交平台转发分享
- 点赞,鼓励
- 评论互动
- 快速复制文章链接
- 二维码扫描手机端阅读
还有一个我觉得很好的最近几年才在各大产品频繁出现的文字的收听功能,比如微信公众号的“听全文”,国外的 Medium 也有播放音频。好处很多,对于很多不愿意或者不方便看文字的人来说他可以通过另外一条途径 来了解你分享的东西。
我很喜欢 Medium 简洁大气的设计,两边大量的留白,中间以文章内容为中心,而且该有的功能又很丰富。我直接参考了它的样式。然后花了一天的时间把这几个功能实现了。
下面简单说下这几个功能的实现思路,不是很难,给需要的人一个参考:
给作者一个鼓励
由于本网站是纯静态的,没法收集用户的点赞(喜欢)数据,只能借助第三方的服务实现。比如评论用的 Giscus 就是用的 Github Discussions 功能集成的,这个详细的放到下面再说。 这里我用了一个偷懒的方式,当你点击鼓掌的图标时,会喷发出彩带的效果。为了让阅读文章的人有个表达的地方,至于收不收集这个数量我觉得是其次。
可以点击下面的按钮体验下实际效果:
代码的实现,彩带效果这里借助了 canvas-confetti
这个库,你可以发现本站很多地方都有使用到。
import confetti from 'canvas-confetti';
function onClap (e) {
confetti({
particleCount: 200, // 默认值:50,要发射的五彩纸屑的数量。
startVelocity: 30, // 默认值:45,五彩纸屑开始移动的速度,以像素为单位
angle: 90, // 发射的角度,0 表示水平向右;90 表示垂直向上;180 表示水平向左;270 表示垂直向下
spread: 120, //默认值:45,五彩纸屑在垂直方向扩散的角度,45 表示五彩纸屑以垂直方向正负 22.5 度角发射
ticks: 300, // 默认值: 200 ,值越小粒子消失得越快,值越大粒子消失得越慢
gravity: 0.5, // 默认值:1,粒子下落的速度。1 是全重力,0.5 是半重力,0 表示无重力;大于 1 表示加速下落,负值表示粒子会向上升起。
origin: { // 彩带起点位置,0.5表示位于页面的中心
x: 0.5,
y: 0.5
}
})
}
评论互动
上面已经提到,评论功能使用的是 Giscus 开源方案,类似的还有很多,它们都是借助 Github 提供的 API 实现。
- giscus - 可借助组件库在 React、Vue 和 Svelte 中使用,支持多种语言
- gitalk - 基于 Github Issue 和 Preact 开发的评论插件
- utterances - 借助 Github issues 实现的轻量的评论组件,giscus 灵感就是来源于它
评论区代码我封装成了一个组件,外层包裹了一个 id
为 Comment
的 DIV,为了上面的评论图标通过锚点点击快速跳转到达底部评论区。
import React from 'react';
import Giscus from "@giscus/react";
import { useColorMode } from '@docusaurus/theme-common';
import styles from './style.module.scss';
export default function GiscusComponent() {
const { colorMode } = useColorMode();
return (
<div className={styles.commentWrapper} id="Comment">
<Giscus
repo="fantingsheng/spacexcode-discus"
repoId="R_kgDOJo****"
category="General"
categoryId="DIC_kwDOJoGL984CWxiW" // E.g. id of "General"
mapping="url" // Important! To map comments to URL
term="Welcome to @giscus/react component!"
strict="0"
reactionsEnabled="1"
emitMetadata="1"
inputPosition="top"
theme={colorMode}
lang="zh-Hans"
loading="lazy"
crossorigin="anonymous"
async
/>
</div>
);
}
社交平台转发分享
社交平台我选了我日常经常维护的微博和 X,这两个平台都可以通过链接直达,通过相关的参数携带分享的文字,链接和图片。
关于博客文章中要分享的信息,我们可以从 Docusaurus 提供了 API 中获取到;
import { useBlogPost } from '@docusaurus/theme-common/internal';
import useBaseUrl from '@docusaurus/useBaseUrl';
export default function BlogToolBar({}) {
const { metadata, isBlogPostPage } = useBlogPost();
const { permalink } = metadata;
const blogUrl = siteConfig.url + '' + useBaseUrl(permalink);
return (
....
)
}
标题和描述可以从 metadata
中拿到,图片我们在撰写文章的时候,选择一个封面图放在 front matter
的信息里。
文章的链接我们并不能直接拿到,需要拿到后缀后和配置信息里的 url
进行拼接。
- 微博
<a
className={styles.shareLink}
href={`https://service.weibo.com/share/share.php?url=${encodeURIComponent(blogUrl)}&title=${encodeURIComponent(metadata.title + "|" + metadata.description)}&pic=${metadata.frontMatter.image}`}
target="_blank"
>分享到微博</a>
- X(原 Twitter)
<a
className={styles.shareLink}
href={`https://twitter.com/share?url=${encodeURIComponent(blogUrl)}&text=${encodeURIComponent(metadata.title + "|" + metadata.description)}&image=${metadata.frontMatter.image}`}
target="_blank"
>Share to X</a>