网上有很多种搭建博客的方法,有前后台一把梭的,有静态网页的,也有大佬喜欢直接在Github的Issues上写文章。
今天给大家分享一种很方便的方法来搭建博客,无需服务器,前端可以是任意的技术栈。
可以实现的功能:
- 前端页面自定义
- 带评论系统
- 文章可以带标签分类
- 数据、图片保存在Github,长期储存
- CDN加速
- 自定义域名
当然,这种方式还是需要自己动手,并不是现成的一套技术。
如何实现
其实原理说出来很简单,因为Github有提供API接口的,可以访问Issues,而我们只需要通过Issues的接口来请求文章数据,每一篇文章对应一个Issue,每一个Issue的评论功能对应该文章的评论系统。
图片可以存储在当前仓库的另一个分支,用免费的jsdelivr来作CDN。
Github Page和一些Serverless
提供商如vercel都可以修改自定义域名。
创建仓库和Token
需要在Github上新建一个仓库,然后申请一个Github Token,申请方式见官方文档。
这个Token需要保存好,不能传到仓库的,可以用.env.local
这种方式来储存和读取。
读取博文列表
博文列表也就是Github Issues,官方提供了2种方式来获取,分别是REST API和GraphQL API,需要使用官方的请求库core.js。我是使用的GraphQL API,因为它可以提前过滤不要的数据。
比如我想要请求的Issues列表是仓库zhangyu1818/blog
,拥有者为zhangyu1818
,仓库名为blog
,它对应的GrpahQL请求如下:
{
repository(owner: "zhangyu1818", name: "blog") {
issues(
states: CLOSED
first: 100
orderBy: { field: CREATED_AT, direction: DESC }
filterBy: { createdBy: "zhangyu1818" }
) {
nodes {
number
title
createdAt
updatedAt
labels(first: 5) {
nodes {
color
name
}
}
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}
}
这一串数据请求了由zhangyu1818创建前100个关闭的Issue,每一个Issue请求前5个label标签,每一个Issue包含number、title、craetedAt等数据。
对应的REST API请求的方式和示例见文档。
请求文章详情
每一个Issue都是一个数字,用数字请求指定的Issue可以得到里面的详情。
query queryIssueByNumber($number: Int!) {
repository(owner: "zhangyu1818", name: "blog") {
issue(number: $number) {
number
title
url
createdAt
bodyHTML
labels(first:5) {
nodes{
color
name
}
}
}
}
}
Github API不仅可以请求Markdown的内容,也可以直接请求由Github渲染好的的内容HTML,这样我们连本地的Markdown渲染都可以省去。
对应的REST API请求的方式和示例见文档。
评论系统
评论系统是有很多现成的轮子,这里推荐使用gitalk
,使用方式见文档。
需要先在Github创建一个应用,我的应用信息如下。
使用方式
const gitalk = new Gitalk({
clientID: "GITHUB_CLIENT_ID", // 你的应用id
clientSecret: "GITHUB_CLIENT_SECRET", // 你的应用secret
repo: "blog", // 你的仓库
owner: "zhangyu1818", // 你的github名字
admin: ["zhangyu1818"], // 你的github名字
number: 1, // 需要issueNumber相同
})
gitalk.render('gitalk-container') // 渲染的元素
图片储存在Github
这个也是现有工具就能实现的功能,图形化工具PicGO,它也有命令行工具PicGo-Core,它同样需要使用Github Token,可以是之前申请的Token,也可以重新申请一个。
具体配置可以看参考教程。
我配置的是将图片存在仓库的另一个分支。
这样配置的话如果需要使用jsdelivr
作CDN加速,配置的地址应该是
https://cdn.jsdelivr.net/gh/zhangyu1818/blog@files
页面的部署方式
部署方式推荐使用vercel
,它可以很简单的配置在Github的主分支更新后自动的拉取和部署,同时支持很多种不同的前端技术栈,Vue和Angular都支持的,可以看这里。
所以前端可以用任意的技术栈,我选择的是Next.js
,然后再通过vercel
来部署。
vercel
部署的还有一个好处是可以在页面上配置一些环境变量,比如我们的Github Token,聊天的Client ID,同时也可以修改自定义的域名。
配置好后代码里可以直接这样写。
const gitalk = new Gitalk({
clientID: process.env.NEXT_PUBLIC_GITHUB_CLIENT_ID,
clientSecret: process.env.NEXT_PUBLIC_GITHUB_CLIENT_SECRET,
// ...
})
sitemap如何实现
如果是静态页面,可以需要在build
之前先请求列表,再写一个sitemap.xml
到本地,如果是服务端渲染,可以直接写一个API接口。
总结
这个博客我也用了挺久了,总的来说非常方便,是我折腾博客多年来说最好的一个方式,不需要本地储存数据,也不需要后台,也不需要买服务器来部署,Github上和网页就是一个镜像,需要改文章内容或者是标签,只需要在Github上改一下就行了。
唯一的缺点就是需要自己折腾折腾,对于爱动手的小伙伴来说,我觉得这种方式的自由度是很高的了。