从 Next.js 到 GitHub Pages:个人作品集网站的静态部署、自定义域名与搜索收录实践
Next.js 静态导出与 GitHub Pages 自动部署:自定义域名、HTTPS 和百度验证实战
前言
对于个人作品展示、项目文档、技术博客等以内容展示为主的网站,如果暂时不需要数据库、用户登录、文件上传和服务端接口,可以将 Next.js 项目导出为静态文件,并部署到 GitHub Pages。
这种部署方式不需要单独维护服务器,同时还能实现:
- GitHub Actions 自动构建与发布;
- 自定义域名访问;
- 自动配置 HTTPS;
- 多页面静态路由;
- JavaScript 动画和前端交互;
- 百度搜索资源平台验证;
robots.txt和sitemap.xml配置。
本文以一个实际的 Next.js 静态网站为例,记录从项目配置到公开上线的完整过程,并重点分析部署中容易遇到的 DNS、404 和搜索验证问题。
一、整体部署架构
本次使用的部署流程如下:
本地 Next.js 项目
↓
提交到 GitHub 仓库
↓
触发 GitHub Actions
↓
安装依赖并执行构建
↓
生成 out 静态目录
↓
上传 GitHub Pages 部署产物
↓
通过自定义域名访问
这种方案适合:
- 个人作品集;
- 企业展示页;
- 产品介绍页;
- 项目文档;
- 静态博客;
- 活动专题页面。
不适合直接运行以下功能:
- Node.js 服务端接口;
- 数据库实时读写;
- 用户登录和注册;
- 后台内容管理;
- 服务端文件上传;
- 依赖运行时服务器的动态渲染;
- 无法在构建阶段确定参数的动态页面。
因此,在改造之前,应先确认项目是否可以静态化。
二、配置 Next.js 静态导出
在 Next.js 配置文件中启用静态导出。
如果项目使用 next.config.js,可以参考:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "export",
trailingSlash: true,
images: {
unoptimized: true,
},
};
module.exports = nextConfig;
如果项目使用 next.config.mjs:
const nextConfig = {
output: "export",
trailingSlash: true,
images: {
unoptimized: true,
},
};
export default nextConfig;
1. output: "export"
该配置会让 Next.js 在构建完成后生成静态 HTML、CSS 和 JavaScript 文件。
构建产物默认位于:
out/
2. trailingSlash: true
启用后,页面会输出为目录形式。
例如:
/about/
对应的文件为:
out/about/index.html
这种路径形式在 GitHub Pages 等静态托管平台中通常更加稳定。
3. images.unoptimized: true
Next.js 默认图片优化功能需要服务端参与。
GitHub Pages 只能托管静态资源,因此需要关闭服务端图片优化,或者改用普通 <img> 标签及提前压缩好的图片。
三、处理动态路由
如果项目存在动态路由,例如:
app/projects/[slug]/page.tsx
静态导出时,需要提前告诉 Next.js 应当生成哪些页面。
可以通过 generateStaticParams 提供参数:
const projects = [
{
slug: "project-a",
title: "项目 A",
},
{
slug: "project-b",
title: "项目 B",
},
];
export function generateStaticParams() {
return projects.map((project) => ({
slug: project.slug,
}));
}
最终会生成:
out/projects/project-a/index.html
out/projects/project-b/index.html
如果动态参数只能在用户访问时从服务器获取,就不适合直接导出到 GitHub Pages。
四、本地执行构建测试
完成配置后,先不要立即推送。
在本地执行:
npm install
npm run build
如果使用锁文件并希望严格按照锁定版本安装,可以使用:
npm ci
npm run build
构建成功后,应出现:
out/
典型目录结构:
out/
├── index.html
├── 404.html
├── about/
│ └── index.html
├── projects/
│ ├── project-a/
│ │ └── index.html
│ └── project-b/
│ └── index.html
├── _next/
├── images/
├── robots.txt
└── sitemap.xml
部署前建议重点检查:
out/index.html是否存在;- 所有项目详情页是否生成;
- 图片路径是否正确;
- CSS 和 JavaScript 是否正常;
- 刷新二级页面是否出现 404;
- 页面是否仍然依赖服务端接口;
- 页面是否包含错误的绝对路径;
public中的文件是否复制到out根目录。
五、创建 GitHub Pages 自动部署工作流
在项目中创建文件:
.github/workflows/deploy.yml
写入:
name: Deploy Next.js site to GitHub Pages
on:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: github-pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Configure GitHub Pages
uses: actions/configure-pages@v5
- name: Build Next.js project
run: npm run build
- name: Upload static site
uses: actions/upload-pages-artifact@v4
with:
path: ./out
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
工作流的核心过程是:
拉取代码
→ 安装 Node.js
→ 安装依赖
→ 执行 npm run build
→ 上传 out 目录
→ 发布到 GitHub Pages
需要特别注意:
path: ./out
这里必须指向真正的静态构建产物。
如果错误上传 .next、项目根目录或其他文件夹,线上网站可能出现空白页、404 或资源加载失败。
六、在 GitHub 中启用 Pages
进入仓库:
设置
→ GitHub Pages
在“构建和部署”的来源中选择:
GitHub Actions
然后将代码推送到 main 分支:
git add .
git commit -m "configure GitHub Pages deployment"
git push origin main
进入仓库中的:
操作
查看工作流状态。
绿色表示部署成功,红色表示失败。
如果失败,可以点开具体步骤查看日志。
常见错误包括:
npm ci找不到锁文件;- Node.js 版本不兼容;
- TypeScript 编译失败;
- ESLint 检查失败;
- 动态路由没有生成静态参数;
- 图片优化功能与静态导出冲突;
- 构建完成但没有生成
out目录。
七、配置自定义域名
GitHub Pages 默认地址通常类似:
https://username.github.io
如果已经购买独立域名,可以在:
仓库
→ 设置
→ GitHub Pages
→ 自定义域
填写:
www.example.com
然后到域名服务商的 DNS 控制台添加 CNAME 记录:
记录类型:CNAME
主机记录:www
记录值:username.github.io
注意:
- 记录值不要填写
https://; - 不要在结尾添加
/; - 同一个
www记录不能同时存在冲突的 A 记录; - DNS 生效需要一定时间;
- GitHub 会自动检查域名配置。
正确关系如下:
www.example.com
↓
username.github.io
八、配置不带 www 的根域名
如果还希望下面这个地址能够访问:
example.com
需要为根域名添加解析。
根域名的主机记录通常填写:
@
然后添加 GitHub Pages 的 A 记录地址。
结构如下:
记录类型:A
主机记录:@
记录值:GitHub Pages 官方提供的 IP
最终建议统一到一个正式域名,例如:
https://www.example.com
这样可以避免:
https://example.com
https://www.example.com
被搜索引擎识别为两个不同的网站版本。
网站中的以下内容也应保持一致:
- canonical;
- sitemap;
- Open Graph;
- JSON-LD;
- 站内链接;
- robots.txt。
九、开启强制 HTTPS
DNS 检查成功后,GitHub Pages 会为自定义域名签发 HTTPS 证书。
证书生成后,可以在 Pages 设置中勾选:
强制 HTTPS
启用后:
http://www.example.com
会自动跳转到:
https://www.example.com
如果“强制 HTTPS”暂时无法勾选,通常是以下原因:
- DNS 尚未完全生效;
- CNAME 配置错误;
- 根域名存在冲突记录;
- GitHub 仍在签发证书;
- 自定义域名刚刚变更。
此时不要频繁删除和重新添加域名,否则可能延长证书签发时间。
十、配置百度搜索资源平台文件验证
网站部署完成后,可以添加到百度搜索资源平台。
文件验证通常会提供一个 HTML 文件,例如:
baidu_verify_codeva-xxxxxxxx.html
对于 Next.js 静态导出项目,应将文件放入:
public/
目录结构示例:
project/
├── public/
│ ├── images/
│ ├── robots.txt
│ └── baidu_verify_codeva-xxxxxxxx.html
├── app/
├── package.json
└── next.config.js
执行构建后,文件应出现在:
out/baidu_verify_codeva-xxxxxxxx.html
部署成功后,可以通过以下地址访问:
https://www.example.com/baidu_verify_codeva-xxxxxxxx.html
只有该地址能够直接打开,百度才能完成验证。
验证成功后,不要删除这个文件。
十一、百度验证文件出现 404 的原因
在实际部署中,经常会出现:
本地 public 中存在验证文件
但是线上访问返回 404
这通常不是百度的问题,而是文件没有进入最终部署产物。
1. 检查构建产物
执行:
npm run build
然后检查:
out/baidu_verify_codeva-xxxxxxxx.html
是否存在。
如果 public 中有文件,但 out 中没有,说明构建配置存在问题。
2. 检查文件名
文件名必须完全一致,包括:
- 字母大小写;
- 连字符;
- 下划线;
- 扩展名。
GitHub Pages 使用 Linux 文件系统,文件名大小写敏感。
例如:
Verify.html
verify.html
会被视为两个不同文件。
3. 检查最新提交是否推送
执行:
git status
git log -1
git remote -v
确认验证文件已经提交:
git add public/baidu_verify_codeva-xxxxxxxx.html
git commit -m "add Baidu verification file"
git push origin main
4. 检查 GitHub Actions 状态
进入:
仓库
→ 操作
确认最新工作流已经成功。
本地文件存在,并不代表远程仓库和线上网站已经更新。
5. 检查上传目录
工作流必须上传:
path: ./out
如果上传目录错误,即使构建成功,验证文件也不会出现在网站根目录。
6. 等待部署节点更新
GitHub Actions 显示成功后,线上节点仍可能存在短暂延迟。
可以等待几分钟,再使用无痕窗口访问:
https://www.example.com/baidu_verify_codeva-xxxxxxxx.html
也可以临时增加查询参数排除浏览器缓存:
https://www.example.com/baidu_verify_codeva-xxxxxxxx.html?v=2
十二、配置 robots.txt
在 public 目录创建:
robots.txt
内容示例:
User-agent: *
Allow: /
Sitemap: https://www.example.com/sitemap.xml
构建后应能够访问:
https://www.example.com/robots.txt
需要避免出现:
Disallow: /
该配置会阻止搜索引擎抓取整个网站。
还需要检查正式页面中是否存在:
<meta name="robots" content="noindex" />
如果线上页面包含 noindex,搜索引擎可能不会将页面加入索引。
十三、创建 sitemap.xml
网站地图用于列出网站中的重要页面。
示例:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://www.example.com/</loc>
</url>
<url>
<loc>https://www.example.com/about/</loc>
</url>
<url>
<loc>https://www.example.com/projects/project-a/</loc>
</url>
<url>
<loc>https://www.example.com/projects/project-b/</loc>
</url>
</urlset>
将文件放入:
public/sitemap.xml
线上地址:
https://www.example.com/sitemap.xml
然后可以在百度搜索资源平台的普通收录功能中提交该地址。
网站地图的作用是帮助搜索引擎发现页面,不代表提交后一定立即收录。
十四、添加部署前检查脚本
为了避免后续修改时误删验证文件、Sitemap 或 robots 文件,可以在构建完成后增加自动检查。
创建:
scripts/check-static-files.mjs
内容:
import fs from "node:fs";
import path from "node:path";
const outputDirectory = path.join(process.cwd(), "out");
const requiredFiles = [
"index.html",
"robots.txt",
"sitemap.xml",
"baidu_verify_codeva-xxxxxxxx.html",
];
const missingFiles = [];
for (const file of requiredFiles) {
const filePath = path.join(outputDirectory, file);
if (!fs.existsSync(filePath)) {
missingFiles.push(file);
}
}
if (missingFiles.length > 0) {
console.error("静态构建检查失败,缺少以下文件:");
for (const file of missingFiles) {
console.error(`- ${file}`);
}
process.exit(1);
}
console.log("静态构建检查通过");
然后在 package.json 中增加:
{
"scripts": {
"build": "next build",
"check:static": "node scripts/check-static-files.mjs"
}
}
GitHub Actions 中增加:
- name: Build Next.js project
run: npm run build
- name: Validate static files
run: npm run check:static
这样,如果后续构建缺少必要文件,工作流会停止部署,避免错误版本上线。
十五、常见问题总结
1. 静态网站还能使用动画吗?
可以。
静态部署仍然能够运行浏览器端 JavaScript,因此滚动动画、轮播、弹窗、菜单、卡片交互等功能都可以保留。
2. 为什么二级页面刷新后出现 404?
应检查:
- 是否启用了
trailingSlash; - 页面是否真正生成到
out; - 动态路由是否配置了静态参数;
- 内部链接是否指向正确路径。
3. 为什么图片部署后不显示?
常见原因包括:
- 使用了错误的绝对路径;
- 文件名大小写不一致;
- 图片没有放在
public; next/image仍然依赖服务端优化;- 构建后路径发生变化。
4. 为什么 DNS 检查一直失败?
应检查:
- CNAME 是否指向正确地址;
- 记录值是否误加
https://; - 是否存在同名 A 或 AAAA 记录;
- DNS 是否尚未完全生效;
- 自定义域名是否填写正确。
5. 为什么验证文件本地存在但线上 404?
重点检查:
public 文件
→ out 构建产物
→ Git 提交
→ 远程 main 分支
→ GitHub Actions
→ Pages 部署结果
任何一个环节没有完成,线上都可能访问不到。
十六、总结
将 Next.js 网站部署到 GitHub Pages,涉及的不只是执行一次构建。
完整流程包括:
- 静态导出配置;
- 动态路由处理;
- 本地构建检查;
- GitHub Actions 自动部署;
- 自定义域名 DNS 配置;
- HTTPS 证书签发;
- 百度文件验证;
- robots.txt 和 sitemap.xml;
- 404 与构建产物排查;
- 部署前自动检查。
对于内容展示型网站,这套方案可以在不维护独立服务器的情况下,获得稳定的自动部署和独立域名访问能力。
真正需要重点关注的是构建产物。
无论本地源代码看起来是否正确,最终线上网站实际发布的都是:
out/
因此,排查问题时应始终围绕:
源文件是否存在
→ 构建产物是否存在
→ 远程提交是否存在
→ 工作流是否成功
→ 线上文件是否可访问
建立清晰的检查链路后,大部分 GitHub Pages 部署问题都可以快速定位。
更多推荐

所有评论(0)