
如果你也动过“个人网站搭建”的念头大概率搜到过 Academic Pages。这个基于 GitHub Pages 的 Jekyll 学术主页模板是我用了两年之后最终固定下来的方案。这篇配置指南不打算泛泛讲建站原理而是把从 Fork 模板、本地预览、信息配置、内容填充到部署上线的完整路径走一遍顺便把我实际踩过、也帮别人排查过的坑都交代清楚。适合刚读研的研究生、青年教师以及任何想把学术成果以独立方式展示出来的研究者。先说一句总结性的话学术主页不是一个“放照片和简历”的地方而是一个让陌生人在 30 秒内确认你研究方向、近期成果和联系方式的工具。Academic Pages 的价值在于它把这件事做到了“免费、可版本管理、更新一次只需要三分钟”的程度。下面我从选型逻辑开始讲再一步步带你把它跑起来。1. 为什么我最终把学术主页放在了 Academic Pages 上1.1 学术主页要承担的隐形任务审稿人搜到你的主页最想确认的是这篇论文的一作到底是不是你、你的研究方向和稿件是否一致。合作方打开你的主页想找的是 PDF、代码仓库和联系邮箱。学生翻到你的页面可能想知道你带什么课、实验室做什么方向。这些需求本质上都是“信息检索”而不是“视觉展示”。Academic Pages 的布局正好把这些信息放在了清晰的位置上论文列表、学术报告、教学页面、博客短文入口都在导航栏里点两下就能找到。它基于 Jekyll 静态站点没有数据库也没有后台所有内容都是 Markdown 文件和 YAML 配置存放在 Git 仓库里。这带来的隐性好处是每句话、每个论文条目、每次修改都有记录git log能完整还原站点演变过程。我曾经靠这份历史记录直接整理出一份材料更新清单那种体验是可视化后台给不了的。1.2 它和主流方案的差异在哪里我用过学校提供的个人主页后台也试过 WordPress、Hexo最后才定在 Academic Pages 上。几个方案的核心差异可以看这张表方案维护成本自定义能力学术场景贴合度适合人群Academic Pages低Markdown Git 即可中高基于 Jekyll 模板改高内置论文/报告/教学集合大多数有稳定更新需求的科研人员WordPress中高需要服务器、数据库、插件更新高但主题和插件质量参差不齐一般需要自己组装论文列表已经买了服务器且有完整博客运营需求Hexo / Hugo中需要自己搭内容结构高适合前端工程化玩法中论文列表等学术模块要自己写喜欢折腾技术栈、愿意写模板的人学校个人主页后台低但受平台功能限制低通常只能填预设字段中存在学校域名迁移风险学校强制要求时作为辅助展示Academic Pages 不是功能最花哨的但它是“学术内容组织方式”上最贴近科研习惯的。它把论文、报告、教学、博客分成独立的 collection每一种内容都有对应的目录和 front matter 规范。相比之下用通用博客框架做学术主页往往需要自己定义分类、标签和列表模板前期工作量会大不少。1.3 先确认你适不适合它如果你需要展示论文列表和 PDF、想在会议或访问后放一页 Talk 介绍、需要给学生放课程资料或者只是想要一个能被搜索引擎稳定收录的个人主页Academic Pages 直接选即可。反过来如果你想做一个流量驱动的图文博客、想用可视化编辑器拖拽排版、或者需要用户注册和评论区它就不合适。静态站加表单服务、评论服务只是勉强能用不如直接选动态站。这个边界想清楚后面所有配置都不会纠结。很多人在配置时反复改主题、加插件最后发现核心需求其实只是“论文列表 CV 联系方式”那 Academic Pages 默认模板就已经全部覆盖了。2. 搭建前的准备动作Fork 模板与本地预览2.1 在 GitHub 上把模板变成自己的仓库第一步是打开浏览器进入 GitHub 上的academicpages/academic-pages模板仓库点击右上角的 Fork。这个操作会把整套模板复制到你的账号下之后你改的每一处都只影响自己的仓库。Fork 之后要立刻做一件事修改仓库名。两种命名方式差别很大仓库名改成username.github.io站点最终会发布在https://username.github.io仓库名保持academic-pages这类项目名访问地址会变成https://username.github.io/academic-pages第一次尝试强烈建议使用username.github.io这种用户名仓库。原因后面详细说它能让所有资源路径都从根路径开始少掉一大半 baseurl 相关的配置问题。仓库可见性建议设为 Public因为 GitHub Pages 免费托管当前只对公开仓库开放。2.2 本地环境三件套Git、Ruby 和 BundlerJekyll 是 Ruby 生态的工具本地环境需要三样东西Git用来 clone 仓库和提交内容RubyJekyll 的运行环境BundlerRuby 的依赖管理工具用来安装项目锁定的 Gem 包Windows 用户直接装 RubyInstaller安装过程中勾选“Add Ruby executables to your PATH”。macOS 用户系统自带的 Ruby 版本往往偏旧建议用版本管理工具安装新版本。Linux 用户用系统包管理器安装ruby-full和bundler即可。装完后打开终端逐个验证git --version ruby -v bundle -v三个命令都能输出版本号环境就算通了。最容易卡住的地方是 Ruby 版本过老和项目Gemfile里锁定的 Jekyll 版本不兼容报错通常长这样incompatible library version或者bundler failed to load。遇到这类问题先别急着改 Gemfile把 Ruby 升到 3.0 以上再试大概率直接解决。2.3 Clone 到本地并安装依赖环境准备好之后把刚才 Fork 的仓库拉到本地git clone https://github.com/你的用户名/你的仓库名.git cd 你的仓库名 bundle installbundle install会读取项目根目录的Gemfile和Gemfile.lock把 Jekyll 以及配套插件全部装好。第一次执行时间会比较长因为要下载不少 RubyGems 包。如果终端提示权限错误不要随手加sudo优先执行bundle config set path vendor/bundle这条命令会把依赖装到项目内部的vendor/bundle目录不需要管理员权限以后换机器迁移也更干净。装完之后不用管这个目录里的东西它已经通过.gitignore被排除在版本管理之外。2.4 启动本地服务先看到基线版本依赖装完运行bundle exec jekyll serveJekyll 会先执行一次完整构建然后启动本地服务器。默认访问地址是http://localhost:4000浏览器打开后你会看到一个完整但还未改动的学术主页模板。这个“基线版本”非常重要。后续每改一处配置都先在本地刷新确认没有破坏页面再推送到线上。我见过太多人改完直接 push结果线上 404 或样式全丢最后才发现本地构建早就报错了。serve命令会监听文件变化并自动重新构建但注意一点_config.yml这类站点级配置文件修改后最好手动按CtrlC重启一次因为它的变更不一定被自动监听机制完整捕获。这是 Jekyll 的固有行为不是你的操作问题。3. 把模板脸改成自己的主页配置项逐个拆3.1 站点级字段url 和 baseurl 是最优先的四个值打开根目录的_config.yml不要急着通读全文先找到并修改这四个字段url站点最终访问地址例如https://username.github.iobaseurl用户名仓库留空项目仓库填/仓库名title显示在浏览器标签页和页面头部的站名description站点描述很多搜索引擎会把这段文字作为摘要这四个字段影响所有生成页面的路径和 SEO优先级最高。我踩过的典型错误是在用户名仓库里仍然把baseurl写成/仓库名结果所有 CSS、图片路径全部变成二级目录页面打开是纯 HTML 裸排版。判断方法很简单打开浏览器的 Network 面板如果样式文件请求返回 404九成是baseurl不对。3.2 作者信息、头像与个人简介继续往下滚动_config.yml会找到author段。这里面通常有name、avatar、bio、location等字段。头像路径建议直接填/images/avatar.png然后把images目录里的默认头像替换成你自己的照片。bio字段会显示在侧边栏控制在两三句话以内别写成长篇自传更详细的经历放到_pages/about.md里。_pages/about.md是多数访客的落地页支持完整的 Markdown 排版可以放研究兴趣、教育经历、招生说明、代表性项目。这里有一点容易被忽略在 Markdown 正文里引用图片时推荐用 Jekyll 的relative_url过滤器统一处理{{ /images/xxx.png | relative_url }}而不是硬编码/images/xxx.png。这样以后切域名、切 baseurl 时图片路径不会第二次踩坑。头像在 YAML 里的写法保持模板示例即可生成页面时模板会自动处理。3.3 导航栏与页面结构顶部导航栏的内容在_data/navigation.yml文件里维护。默认会有 About、Publications、Talks、Blog 等条目每一条的结构是- title: Publications url: /publications/新增一个栏目时先在_pages目录下创建 Markdown 文件用 front matter 声明页面地址--- layout: single title: Projects permalink: /projects/ ---然后在navigation.yml里加一条对应记录。这样整个站点的栏目就是你完全可控的了。默认模板已经内置好了 Publications、Talks、Teaching 的集合页面你不需要从零创建只需要往对应的内容目录里加文件。3.4 社交入口与学术身份标识author段里通常会预留google_scholar、orcid、github、linkedin、twitter这些字段填上对应的 ID 或用户名页面侧边栏就会自动渲染图标链接。学术 ID 的填写优先级我的建议是这样ORCID 最通用投稿系统和基金申请系统都认这个标识Google Scholar 在国际同行访问时很有用可以放但不用作为唯一入口GitHub 只要你有代码仓库就一定要填这是很多人判断工程能力的直接入口如果还没有 ORCID建议先去注册一个。它是终身绑定的学术身份标识比个人域名更不容易漂移即使换学校、换域名也不会丢。3.5 小图标与搜索引擎收录images目录里的 favicon.ico 是浏览器标签页的小图标不换不影响功能但换上自己的图标会让整个站点的完成度高一个档次。搜索引擎收录方面Jekyll 插件jekyll-sitemap会自动生成sitemap.xml模板里已经内置了这个插件的话站点上线后就能自动被抓取。学术主页不需要过度优化 SEO除非你面临比较严重的重名问题需要通过搜索排名把正确主页顶到第一位才需要额外做结构化数据标记。4. 内容填充论文、学术报告、博客三种内容各有各的规矩4.1 论文条目的最小写法在_publications目录下每篇论文对应一个独立 Markdown 文件。文件名我建议用年份-第一作者-简短标题.md的格式比如2024-zhangsan-nerf-analysis.md。这样文件排序天然就是时间倒序在编辑器里也好辨认。文件开头的 front matter 是这个机制的核心--- title: 论文完整标题 date: 2024-03-15 venue: 期刊或会议全称 paperurl: https://doi.org/... citation: 作者列表 (2024). 论文标题. 期刊/会议. ---正文区可以写摘要、PDF 预览说明或者复现代码的使用注意。paperurl、code、slides这些字段会在列表页自动渲染成下载或查看按钮不需要自己排版。日期字段date不只是显示用模板的列表排序也依赖它。格式必须是 ISO 标准的YYYY-MM-DD写成“2024年3月”这种中文格式轻则排序混乱重则条目直接不显示。批量录入历史论文时我一般从 DBLP 或 BibTeX 导出条目再用一个小脚本把title、year、venue映射成 front matter半小时能处理完几十篇。手动复制模板一个个建文件效率太低还容易漏字段。4.2 论文之外的学术内容报告与教学_publications之外模板还内置了_talks和_teaching两个内容集合。_talks下同样是 Markdown 文件front matter 里写title、date、venue如果报告有 slides 或视频回放可以直接加slides、video字段。_teaching适合放课程主页讲义 PDF 可以放在files目录统一引用。这里有一个从结构设计上就值得理解的点学术主页的价值不只是论文列表招生和合作方很看重“这个人有没有在参与学术社区交流”。哪怕只更新一个 seminar 报告也比主页半年不动要可信得多。所以哪怕内容暂时不多也建议把这三类集合的骨架都建好后续有内容直接往里填就行。4.3 博客短文_posts 的命名规范博客目录是_posts文件名必须遵循YYYY-MM-DD-title.md的格式这是 Jekyll 的硬性规范。写好后会在 Blog 页面按日期倒序排列。学术博客不一定要写完整论文。会议见闻、复现笔记、教学答疑、工具评测都合适。我个人很推荐博士生把实验踩坑过程记录下来形式上像是在写备忘实际上是在给自己积累可检索的知识库。很多东西半年后回头看当时的解决方案比自己记忆中的要详细得多。4.4 PDF 等附件放哪、链接怎么写论文 PDF、课程讲义、CV 这些文件统一放在files目录下和images目录同级。链接推荐用相对路径最稳妥的写法还是配合relative_url过滤器[下载 PDF]({{ /files/paper1.pdf | relative_url }})直接写files/paper1.pdf在用户名仓库下也能用但如果未来仓库改成子路径部署链接就断。既然 Jekyll 提供了成熟的过滤器就一次养成好习惯避免未来迁移时返工。文件命名有两条铁律不要用中文不要用空格统一英文小写加连字符。我见过有人上传“论文终稿最终版 final.PDF”本地打开没问题push 到线上直接 404。静态站的链接是大小写敏感且不处理空格的和本地操作系统文件系统不一样这是最容易栽的隐形坑。5. 部署上线与自动化GitHub Pages 的完整链路5.1 第一次 Push 和 Pages 开关本地改好后把内容推送到 GitHubgit add -A git commit -m feat: init academic site git push origin main注意分支名以你仓库实际为准模板可能是main也可能是master。推送完成后进入仓库 Settings - PagesSource 选择 Deploy from a branch分支选main目录选/root保存。稍等一两分钟GitHub 会自动执行 Jekyll 构建把生成的静态页面发布出去。这是 GitHub Pages 的默认工作方式它识别到这是一个 Jekyll 项目后会在云端跑一次完整构建不依赖你本机的 Ruby 版本。所以本地 build 失败时线上也大概率失败反过来本地能正常serve线上基本不会出问题。两者的差异主要来自 GitHub Pages 锁定的依赖版本和本地Gemfile.lock不一致如果出现同步问题优先把两边的依赖对齐。5.2 自定义域名CNAME 文件和 DNS 解析学术圈很流行用自己的名字做域名比如zhangsan.me。部署流程分两步第一步在仓库根目录新建一个纯文本文件CNAME里面只写一行域名例如www.zhangsan.mepush 后 GitHub 会验证这个域名。第二步去 DNS 服务商处添加解析主域名用 A 记录指向 GitHub Pages 的 IP 地址www子域名用 CNAME 记录指向username.github.io。解析生效后回到 Pages 设置里勾选 Enforce HTTPS让浏览器强制走加密链接。这里要重点提醒CNAME文件属于仓库的一部分每次 push 都会带上不要把它加到.gitignore。以后换域名时直接改这个文件内容并 push旧域名会自动解绑。5.3 用 GitHub Actions 固定构建行为如果你希望多人协作时构建行为完全一致或者想脱离本地环境依赖推荐把构建从默认方式切到 GitHub Actions。在仓库里创建.github/workflows/github-pages.yml一个最小可用的 workflow 可以写成name: Deploy Jekyll site to Pages on: push: branches: [main] permissions: contents: read pages: write id-token: write jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/configure-pagesv5 - uses: actions/cachev4 with: path: vendor/bundle key: ${{ runner.os }}-gems-${{ hashFiles(**/Gemfile.lock) }} restore-keys: ${{ runner.os }}-gems- - uses: actions/setup-rubyv1 with: ruby-version: 3.2 - name: Install dependencies run: bundle install - name: Build site run: bundle exec jekyll build - uses: actions/upload-pages-artifactv3 deploy: needs: build runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment uses: actions/deploy-pagesv4这个 workflow 的逻辑并不复杂每次 push 到 main 分支后自动 checkout 代码、安装依赖、执行构建然后把构建产物发布到 Pages。切到 Actions 构建后本地只需要做内容编辑和预览具体构建行为由 CI 固化下来换电脑、多人协作都不会出现“你本地能跑我这不行”的问题。使用 Actions 后记得在 Settings - Pages 的 Source 里选择 GitHub Actions而不是 Deploy from a branch。5.4 更新内容的最小流程日常更新一篇论文或博客最小流程是四步本地新建或修改对应目录下的 Markdown 文件运行bundle exec jekyll serve预览确认git add、git commit、git push等 GitHub 构建完成刷新线上页面确认熟练之后一次内容更新的平均耗时大概三分钟大头反而花在 PDF 扫描和 citation 信息整理上。这也是我坚持用 Academic Pages 的原因静态站没有后台数据库没有插件要升级内容全部是文本文件随时能备份、能迁移、能版本回滚。6. 我反复遇到的坑与排查思路6.1 样式突然变成裸 HTML先查 baseurl最典型的症状是页面能打开但没有任何样式图片全部裂开。根因九成出在_config.yml里的url或baseurl写错。用户名仓库正确的写法是baseurl: 项目仓库是baseurl: /仓库名。改完记得重启本地 serve因为站点级配置文件不总是被热更新机制捕获。还有一个连带场景项目仓库下页面内部导航链接如果写的绝对路径会在站点上线后全部跳到根路径表现就是点击导航回到首页。正确做法是让所有内部链接都经过relative_url处理或者在写_pages的 permalink 时统一带上前缀。6.2 本地正常GitHub Pages 上线却空白如果本地一切正常线上却 404 或白屏优先级依次排查分支没选对Settings - Pages 里配置的分支和实际 push 的分支不一致Source 模式和仓库内容不匹配Source 选了 GitHub Actions但仓库里没有可用的 workflow构建从未触发依赖版本不一致本地跑过bundle update导致 Gemfile.lock 和线上锁定版本不一致线上构建失败排查突破口是仓库的 Actions 标签页构建日志里会有明确报错行。我一直把线上构建日志当作最可靠的排错入口遇到线上问题先看日志而不是反复改配置盲试。6.3 论文列表不显示或顺序不对不显示的情况先看 front matter 是否被正确识别。最容易犯的错误是直接复制别人论文文件的 YAML字段名大小写和模板要求不一致比如把venue写成Venue。Jekyll 的 front matter 字段名是大小写敏感的这个错误不会报构建失败但字段值就是渲染不出来。排序错乱则主要是date格式问题。统一用2024-01-15不要写2024/01/15也不要写January 2024。还有一个隐蔽问题文件名重复。同一个 Markdown 文件如果同时出现在_drafts和_publications里构建结果可能出乎意料。保持一个内容文件只放在一个集合目录不要图省事复用。6