【经验】静态博客部署 Hexo + Netlify-CMS + Vercel (在线构建)

article/2025/11/3 23:03:26

目录

  • 引入
    • 背景
    • 方案
  • 步骤
    • 生成starter模板
    • 添加Netlify CMS在线管理
    • 添加Netlify身份验证组件
    • 启用git gateway身份验证
    • 换用Vercel作为CDN
      • 重新添加js
      • 添加身份验证器
      • 绑定oauth
    • 定制404页面
  • 模板
  • 已知问题

引入

背景

Hexo等静态博客相对于Wordpress等动态博客,可以白嫖很多免费部署服务,不需要博主自行维护服务器,同时借由CDN的分发,不受服务器地理位置和计算能力的限制,访问更快速。但静态博客需要在本地维护npm环境,进行构建部署流程较动态博客更为繁琐。

Netlify-CMS是一个开源的静态博客编辑组件,可以与多种自动构建部署服务商搭配使用
Netlify是一家自动构建部署服务商,Netlify-CMS在Netlify上结合使用最为简单

Netlify等自动构建部署的免费服务基于Git管理,让静态博客可以免本地环境运行,但基于Git的管理让博客的编辑过程过于繁琐。另外,Netlify在大陆地区经常性无法访问或速度极慢,若同步至Github Pages也面临周期性抽风的问题。Vercel在大陆绝大部分地区的访问速度较快,相比直接在Netlify或Github Page上部署是更好的选择。

Netlify-CMS作为Headless CMS,可以添加在Hexo等静态博客项目中,链接到静态博客的Git源码项目,以提供近似动态博客的在线编辑体验。

然而想要为静态博客添加Netlify-CMS,最简单的方式是直接使用Netlify构建,如果不使用Netlify的构建服务而寻求Vercel等第三方的构建服务,则配置极为繁琐,从零开始熟练操作也需1~2小时,对于初次接触Hexo/Netlify-CMS/Vercel/npm的人来说,完成第一次完美部署至少也需1~2天研究。

本文是为了给自己和有类似需求的人提供从零开始可轻松遵循的教程,每一步的步骤非常详细,并提供有校验避免某一步出错,同时便于将这一过程在Hugo等其他博客上复现。

如果想要遵循本文步骤,在动手实践前请认真阅读几遍。另外本文结尾提供了构建模板,如果不想从零开始,可以使用模板快速部署自己的博客。

本方案为Hexo+Netlify-CMS+Vercel,具体优势为:

  • 完全免费,也无需自行维护服务器
  • 静态博客,访问时无渲染时间,可经CDN加速
  • 就像动态博客一样支持在线编辑
  • 不需要维护本地环境,任何设备都可以随处编辑,并自动构建、部署
  • 免备案
  • Vercel CDN在大陆地区访问速度较快
  • Vercel提供 https://<domain>.vercel.app/格式的免费域名,绑定第三方域名也非常简单,同时默认支持自动申请维护Let’s Encrypt的SSL证书,直接支持https访问
  • 整个教程可以无命令行输入,无环境配置即可完成

另提供Academia学术主题教程,可移步另一篇文章

方案

  1. 博客框架:Hexo
  2. 在线编辑框架:Netlify CMS
  3. 自动构建部署:Vercel
  4. 域名:Namesilo
  5. SSL证书:Vercel提供
  6. 自定义404页面

教程复杂,细节较多,因此校验步骤较多。建议实操前全文阅读数遍,有信心的读者可以略过校验步骤。

步骤

生成starter模板

参考 https://www.netlifycms.org/docs/add-to-your-site/

  1. 进入https://www.staticgen.com/,选择Hexo处的 Deploy to Netlify,登录Netlify,如无帐号则Github授权登录注册,其他方式据称有bug
  2. 登录Netlify后,为Netlify授权Github。Netlify会自动将Hexo模板fork到自己的Github仓库中,并自动授权关联Netlify App自动参与构建。之后在 https://netlify.com/ 主页可以看到已经部署到Netlify的博客主页
    图1

添加Netlify CMS在线管理

首先在Netlify里添加Netlify CMS,测试成功后再迁移至Vercel
参考 https://www.netlifycms.org/docs/add-to-your-site/

在Github仓库的source目录下创建admin目录:

admin├ index.html└ config.yml

index.html内容:

<!doctype html>
<html>
<head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Content Manager</title>
</head>
<body><!-- Include the script that builds the page and powers Netlify CMS --><script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
</body>
</html>

config.yml内容,注意这里可能会根据你的模板所改变

backend:name: git-gatewaybranch: master # Branch to update (master by default)# These lines should *not* be indented
media_folder: 'source/images' # Media files will be stored in the repo under source/images
public_folder: 'images' # The src attribute for uploaded media will begin with images# This line should *not* be indented
publish_mode: editorial_workflowcollections:- name: 'Post' # Used in routes, e.g., /admin/collections/bloglabel: 'Post' # Used in the UIfolder: 'source/_posts' # The path to the folder where the documents are storedcreate: true # Allow users to create new documents in this collectionslug: '{{slug}}' # Filename template, e.g., YYYY-MM-DD-title.mdfields: # The fields for each document, usually in front matter- {label: 'Title', name: 'title', widget: 'string'}- {label: 'Publish Date', name: 'date', widget: 'datetime'}- {label: 'Body', name: 'body', widget: 'markdown'}

并修改仓库根目录的_config.yml,跳过对source/admin的渲染,否则source/admin/config.yml会于发布时丢失。在_config.yml中修改为:

skip_render: admin/**

等待netlify自动构建完成后,这时打开https://<domain>.netlify.app/admin/
应为密码输入界面。
在这里插入图片描述

添加Netlify身份验证组件

参考 https://www.netlifycms.org/docs/add-to-your-site/#add-the-netlify-identity-widget

依次进入app.netlify.com >> 选择自己的网站 >> Site settings >> Build & Deploy >> Post processing >> Snippet Injection section >> Add Snippet

Before</head>填写

<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>

Before</body>填写

<script>if (window.netlifyIdentity) {window.netlifyIdentity.on("init", user => {if (!user) {window.netlifyIdentity.on("login", () => {document.location.href = "/admin/";});}});}
</script>

Github仓库提交一次无谓的修改(如加一行空格)触发自动构建

之后进入https://<domain>.netlify.app/admin/,之前的用户名密码就会变成登录按钮,点击按钮会向https://<domain>.netlify.app/.netlify/发送一条请求并报错,这是因为还没有开启netlify的身份验证功能。
在这里插入图片描述

启用git gateway身份验证

参考 https://www.netlifycms.org/docs/git-gateway-backend/

依次进入

  1. app.netlify.com >> 自己的网站 >> Identity >> Enable Identity

  2. Site Settings >> Identity >> Registration >>Open

  3. External providers >> 添加Github

  4. Site settings >> Identity >> Services >> Git Gateway >> Enable Git Gateway >> 选择对应的Github仓库

在这里插入图片描述

即可使用Github身份登录了,尝试编辑下文章并点击右上角的publish,等待部署完毕后刷新,可以查看到修改的内容。
在这里插入图片描述

换用Vercel作为CDN

参考:
https://zhuanlan.zhihu.com/p/56319868
https://github.com/ublabs/netlify-cms-oauth
https://www.netlifycms.org/docs/add-to-your-site/#add-the-netlify-identity-widget

重新添加js

这里建议下载Github仓库并新建上传,从而避免仓库中有太多contributers,也可设为私人仓库。注意如果新建仓库将主分支由master切换到了main,则source/admin/config.yml的分支配置也要对应修改。

前往https://vercel.com/new让Vercel进行自动构建。

会得到新的发布链接https://<domain>.vercel.app/

此时访问https://<domain>.vercel.app/admin/(对于Vercel部署的网站,网址这里必须有最后一个/,否则会跳转错误无法访问),又显示为用户名密码登录。

这是因为换为Vercel,无法使用Netlify才有的Snippet Injection功能,需要手动向源代码模板中添加上述代码,

source/admin/index.html里的</head>前添加:

<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>

经测试,针对网站首页的js无需添加。

之后去admin尝试登录一下,界面仍然是一个登录按钮,且按下登录按钮,开发者工具网络拦截到https://<domain>.vercel.app/.netlify的404请求说明正常

在这里插入图片描述

添加身份验证器

现在修改为Vercel部署。使用下面的代码作为serverless身份验证器:

https://github.com/ublabs/netlify-cms-oauth

首先按照readme,修改source/admin/config.yml为对应的内容,如我的则是

backend:name: githubrepo: hangvane/hexo-netlify-cms-vercel # Path to your Github/Gitlab repositorybranch: main # Branch to updatebase_url: https://hexo-netlify-cms-vercel.vercel.app

上传后测试一下,此时admin点登录后会弹出https://<domain>.vercel.app/auth的404页面,说明配置已经正确,只是还未上传身份验证器,所以无法访问serverless函数帮助完成登录过程

在这里插入图片描述

上传身份验证器:

合并package.json:将验证器仓库中的package.json和自己的Github仓库中的依赖进行合并,即添加simple-oauth2添加至dependencies,将@types/node@types/simple-oauth2添加至devDependencies

同时复制vercel.jsonapi文件夹,lib文件夹,将这三个文件上传到自己的Github仓库中,等待自动构建完成后再进行验证:

此时点击登录,会弹出一个Github的404错误界面https://github.com/login/oauth/xxx,且url中含有一个空的id=参数,说明当前步骤正确,只差最后一步绑定Github oauth的ID和Secret
在这里插入图片描述

绑定oauth

从 https://github.com/settings/developers 创建一个oauth,其他项任填,重点是Authorization callback URL 必须为http://<domain>.vercel.app/callback

之后点击生成一个secret,在 Vercel >> 你的项目 >> Project Settings >> Environment Variables创建两个Plaintext类型的环境变量

分析lib/config.ts可以发现,需要为oauth设置两个环境变量分别为OAUTH_GITHUB_CLIENT_IDOAUTH_GITHUB_CLIENT_SECRET,他们的值分别为刚创建的Github oauth中的ID和secret

环境变量创建完成后,在Github上提交一次无谓的修改(如加一行空格)触发自动构建

之后可以访问https://<domain>.vercel.app/admin/,登录成功。

在这里插入图片描述

登录后测试功能是否正常,判断标准:

  • 可以看到已有的文章.md
  • 点开修改后可以成功保存

此时的优点是可以自动创建分支,自动构建分支,供自己预览:
在这里插入图片描述

定制404页面

在Github仓库中添加source/404.html,源代码:

<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5"><title>404 Not Found</title><style>html, body {height: 100%;}body, a {margin: 0;padding: 0;width: 100%;color: #B0BEC5;display: table;font-weight: 100;font-family: 'Lato', sans-serif;}.container {text-align: center;display: table-cell;vertical-align: middle;}.content {text-align: center;display: inline-block;}.title {font-size: 72px;margin-bottom: 40px;}</style>
</head>
<body><div class="container"><div class="content"><div class="title">404</div><a href="/">> > Go back to the homepage > ></a></div></div>
</body>
</html>

并在/_config.yml中跳过对其渲染

skip_render:- admin/**- 404.html

模板

https://github.com/hangvane/hexo-netlify-cms-vercel

该模板已实现vercel上部署Hexo结合Netlify-CMS。

该模板为Hexo默认主题,已结合Netlify-CMS和身份验证器,基于此模板只需遵循如下步骤即可搭建完成:

  1. 点击 Use this template 将此模板fork为自己的仓库(可私有)

  2. 修改 /source/admin/config.yml. 将 backend.repobackend.base_url 修改为自己的对应值

  3. 前往 Github Developer applications 创建一个新的验证应用。其他项任填,重点是Authorization callback URL 必须为http://<domain>.vercel.app/callback

  4. 前往 https://vercel.com/new 导入仓库并新建项目。在导入流程中点 Deploy,添加环境变量 OAUTH_GITHUB_CLIENT_IDOAUTH_GITHUB_CLIENT_SECRET ,将它们的值设为上一步生成的值

  5. 点击 Deploy 等待部署完成

  6. 如果你想更改 Vercel 提供的域名或绑定第三方域名, Settings > Domains.

  7. 打开 https://<domain>/admin/ 并登录 Netlify-CMS 后台,注意URL中最后一个 / 符号不能省略

  8. 测试一下 Netlify-CMS 是否正常工作

  9. 如果需要Netlify-CMS提供的草稿预览功能,也就是在单击 save 后提供一个文章的预览链接,则还需要链接到 Netlify 服务。这个过程和绑定Vercel很类似,但是不需要设置环境变量,因为不从Netlify这一侧进行文章的更新,只是利用它的预览功能

  10. 部署成功!

已知问题

  • Vercel部署下,输入https://<domain>.vercel.app/admin会跳转错误从而报错,URL末尾必须加 /
  • Netlify-CMS的markdown编辑器有一些bug,使用---分隔符和#标时尽量上下各空一行,避免.md文件生成错误

http://chatgpt.dhexx.cn/article/ebNP47U5.shtml

相关文章

.net framework 官方下载地址

.net framework 官方下载地址 https://dotnet.microsoft.com/zh-cn/download/dotnet-framework

使用Netlify部署静态网站

之前写了一篇文章是关于在树莓派上部署Hexo的博客&#xff0c;但树莓派难免会出故障&#xff0c;所以将网站放在另一个地方会更安全一点。 前一篇&#xff1a;https://fitswcblog.com/%E6%A0%91%E8%8E%93%E6%B4%BE%E6%90%AD%E5%BB%BAhexo%E5%8D%9A%E5%AE%A2/ 我在csdn上的所有…

123.HTML5+CSS3完结_使用Netlify收取表单

Netlify也可以做表单接受&#xff1a; 我们启动一下 修改下表单 ● 接着在我们的网站输入并提交表单 ● 之后会有一个提示&#xff0c;提示我们提交成功 然后就能在Netlify接受到用户的表单 ● 当然这个表单只能接受100个&#xff0c;但是作为实验也够用了 到此&a…

第七章:使用Netlify零成本部署组件文档

第七章&#xff1a;使用Netlify无成本发布组件文档 为什么使用Netlify&#xff1f; 一开始一共有三个方案&#xff1a; 1、Github Page 2、Netlify 3、Vercel Github Page只支持一个repo发布一个网站&#xff0c;而我们的项目是一个mononrepo项目&#xff0c;后续可能还有其他…

React项目全球新闻发布管理系统 - 新版问题解决方式整理及部署网站至 Netlify

整理了一下新版的变化以及遇到的坑的解决办法&#xff0c;最后也会分享将网站及接口部署的方式。 千锋前端-React全家桶_React项目全球新闻发布管理系统 https://www.bilibili.com/video/BV1fw411d7R5 文章目录 P4P5P6P11P15P17P18P22P29P30P34P38P41P43P45P50P67进阶: 多语系网…

Coolify系列01- 从0到1超详细手把手教你上手Heroku 和 Netlify 的开源替代方案

什么是Coolify 一款超强大的开源自托管 Heroku / Netlify 替代方案coolLabs是开源、自托管和以隐私为中心的应用程序和服务的统称 为什么使用Coolify 只需单击几下即可托管你的应用、数据库或其他开源服务&#xff0c;等。它是 Heroku 和 Netlify 的一个替代方案。通过 Cool…

.NET Framework 框架

20世纪90年代以来出现的3种典型的组件技术&#xff1a; 1&#xff09;OMC&#xff08;对象组件模型&#xff09;的CORBA 2&#xff09;Microsoft的COM/DCOM 3&#xff09;Sun公司的JavaBeans 在2002年&#xff0c;微软发布了.NET框架的第一个版本&#xff0c;声称其解决了旧问…

vercel和netlify部署代码并解决接口代理转发的问题(和Nginx功能一样)

前言 部署过程就不说了,部署完成后是这样子的 然后访问链接,无法访问 解决 依次点击 Settings–>Domains&#xff0c;在输入框中输入你的域名并点击 Add 按钮。 以此域名为例子demo.gshopfront.dreamlove.top为例,点击添加 我们前往域名管理系统,记录下绿色的值以腾讯云的…

部署Netlify站点博客

Netlify站点部署静态博客 今天尝试把站点部署在Netlify上&#xff0c;因为部署在GitHub Pages上&#xff0c;国内访问速度太慢了&#xff0c;所以就尝试一下别的站点&#xff0c;部署成功之后发现速度还是不太行&#xff0c;后边继续找找原因 Netlify 部署的地址在这里 下图…

使用Hexo+github+netlify快速搭建个人博客网站

1 写在开头 倒腾了好几天&#xff0c;算是做出了一个有点样子的个人博客网站。便学各位大佬也写一个搭建教程&#xff0c;总结一下个人踩坑经验&#xff0c;也希望能对他人略有作用。 博客演示&#xff08;欢迎来留言交流&#xff09; 为什么选择Hexo&#xff1f;答&#xff1…

使用 netlify 部署你的前端应用

我前几天写了一篇文章&#xff0c; 如果你想搭建一个博客 &#xff0c;其中提到了使用 netlify 做博客托管服务。 netlify 可以为你的静态资源做托管&#xff0c;就是说它可以托管你的前端应用&#xff0c;就像 github page 那样。不过&#xff0c;它不又只像 github page 那么…

netlify国内快吗

Netlify国内快吗? Netlify vs 21云盒子 Netlify 是一家提供 JamStack(静态网站)托管的平台&#xff0c;支持自动从Github等仓库拉取代码, 按自定义构建方式进行构建&#xff0c;最后把生成的静态网站进行发布; 在这基础上同时也支持自定义域名&#xff0c;自动申请SSL证书等…

Netlify前端自动化部署工具

一、使用github或者gitlab登陆netlify 首先&#xff0c;打开netlify网站(https://app.netlify.com/) 然后使用github或者gitlab账号登录。 二、根据github/gitlab仓库创建网站 点击New site from Git按钮&#xff1a; 根据你的仓库所在平台选择&#xff0c;以下三选一&#x…

使用netlify实现自动化部署前端项目(无服务器版本)

介绍 本文以 github仓库进行介绍关联netlify的无服务前端自动化部署。用途&#xff1a;个人网站设计、小游戏等当然这只是让你入门~具体细节等待你自己去探索 实现 打开官方网站 如果没有注册过的账户&#xff0c;你需要使用 github 去进行登录。注册完成后会自动给你提示填…

Netlify静态资源托管之部署自动化

关注「WeiyiGeek」公众号 将我设为「特别关注」&#xff0c;每天带你玩转网络安全运维、应用开发、物联网IOT学习&#xff01; 0x00 基础介绍 0x01 Netlify 使用 0x00 基础介绍 Q: Netlify 是什么? Netlify 是一个提供静态资源网络托管的综合平台&#xff0c;一个直观的基于…

如何使用netlify部署vue应用程序

什么是Netlify&#xff1f; Netlify是一个现代网站自动化系统&#xff0c;其JAM架构代表了现代网站的发展趋势。所谓JAM&#xff0c;就是指基于客户端JavaScript、可重用API和预构建Markup标记语言的三者结合。 有了Netlify&#xff0c;我们只要在本机Git中写前端代码&#xff…

C语言:strlen() --- 计算字符串长度

C语言 基础开发----目录 一、strlen() 简介 1. 函数原型 unsigned int strlen(char *str);2. 参数 str - - 要计算长度字符串的地址指针 3. 功能 计算给定字符串的字节长度&#xff0c;直到空字符结束&#xff0c;但不包括空字符。 4. 头文件 #include <string.h>…

C语言 计算字符串的长度

方法一&#xff1a; #include<stdio.h> int length(char *s){char *ps;while(*p!\0){ //等同于 *pp;}return p-s; } void main(){char s[32];printf("请输入一个字符串&#xff1a;");scanf("%s",&s);printf("长度为&#xff1a;%d",l…

计算字符串长度的五种方法

方法一&#xff1b; ------------------------------------------------------------ 方法二; ------------------------------------------------------------ 方法三&#xff1b; ------------------------------------------------------------ 方法四利用sizeof()&#x…

计算字符串长度

用三种方法计算字符串的长度&#xff1a; 字符串&#xff1a;“abcd”&#xff0c;在储存的时候&#xff0c;字符串的最后一位会以一个终止符 \0&#xff0c;所以求取的就是终止符前的字符数。 1.计数器方式 通过设置一个计数器&#xff0c;然后用指针字符串从头扫描&#xf…