GitHub Pages中子文件夹绝对链接不遵循BaseURL设置问题
我帮你搞定这个GitHub Pages链接的坑——之前我自己部署文档时也踩过同样的雷:当项目部署在<USERNAME>.github.io/<PROJECT_NAME>/路径下时,直接用/test/page.md这种根绝对链接,浏览器会自动解析成https://<USERNAME>.github.io/test/page.html,漏掉了项目名前缀,自然跳转失败,尤其是子文件夹里的页面,这个问题会更突出。
下面给你几个最实用的解决方案:
1. 用Jekyll的baseurl配置(推荐,GitHub Pages原生支持)
GitHub Pages默认用Jekyll编译文档,这是最省心的处理方式:
- 第一步:在项目根目录的
_config.yml文件中添加一行配置:
注意:开头要带斜杠,结尾不要加斜杠,比如baseurl: "/<你的项目名称>"baseurl: "/my-notes" - 第二步:把所有绝对链接替换成带
site.baseurl变量的格式:
原来的[测试页面](/test/page.md)改成:
(直接写[测试页面]({{ site.baseurl }}/test/page.html).html是因为Markdown会被编译成HTML文件,写.mdGitHub也会自动跳转,但指向编译后的文件更稳妥) - 第三步:本地预览时,运行
bundle exec jekyll serve,访问http://localhost:4000/<你的项目名称>/就能看到链接正常工作了。
部署到GitHub Pages后,Jekyll会自动把{{ site.baseurl }}替换成你的项目名前缀,不管是根目录还是子文件夹里的页面,链接都会正确指向/<PROJECT_NAME>/test/page.html。
2. 纯静态页面(不用Jekyll)的处理方法
如果你的项目不用Jekyll,纯静态Markdown的话,可以试试这两种方式:
- 方法A:手动添加项目名前缀
直接把所有绝对链接改成/<PROJECT_NAME>/test/page.html,比如[测试页面](/my-notes/test/page.html)。缺点是如果项目名修改,需要批量修改所有链接,比较繁琐。 - 方法B:用HTML的
<base>标签
在每个页面的<head>部分添加:
这样所有根相对的绝对链接都会自动加上这个前缀。但要注意,<base href="/<PROJECT_NAME>/"><base>会影响页面里所有的相对资源(比如图片、CSS文件),这些资源的路径也要适配这个base路径。
3. 批量替换链接的脚本(应急方案)
如果不想逐个修改链接,可以写个简单的shell脚本,在部署前批量替换所有Markdown文件里的绝对链接:
#!/bin/bash PROJECT_NAME="your-project-name" sed -i '' "s/\/\([a-zA-Z0-9_-]*\)/\/$PROJECT_NAME\/\1/g" **/*.md
这个脚本会把所有/xxx格式的链接替换成/your-project-name/xxx,注意macOS的sed和Linux的sed参数略有不同,上面是macOS版本,Linux可以去掉''参数。
为什么子文件夹的链接会出错?
举个例子:你的子文件夹页面是docs/install.html,部署后路径是/<PROJECT_NAME>/docs/install.html,如果页面里的链接是/test/page.html,浏览器会默认从域名根目录开始查找,也就是https://<USERNAME>.github.io/test/page.html,而非项目名目录下的路径,所以必须加上项目名前缀才能正确跳转。
内容的提问来源于stack exchange,提问作者K. Barresi

