SuperAPI AI Directory

tutorial-writer-github-pages

Frontend & websites

View repository

Updated 10-15 23:43

About this skill

Tutorial Writer — 🚀 GitHub Pages Deployment v1.0.0

Parent Skill: tutorial-writer Standalone Available: ✅ Can be triggered directly via /github-pages (L1 direct) Architecture: Self-contained single-file skill — includes a complete GitHub Pages deployment guide Usage Frequency: 🟢 Low frequency — usually invoked after the build is complete (2-3 times per project)


🎯 Scope of Responsibility

Scope of Responsibility: Only responsible for deploying the build artifacts of the web package to GitHub Pages

Not responsible for:

  • Website build → /web sub-skill
  • PDF/EPUB generation → /book sub-skill
  • Content management → /content sub-skill
✅ Responsible for ❌ Not responsible for
GitHub Pages-specific configuration and deployment Astro project build → /web
GitHub Actions workflow setup Starlight theme configuration → /web
base path / trailingSlash configuration Content Collections → /web
Custom domain / DNS / SSL Component development → /web
CI/CD pipelines and automation Performance optimization (at build time) → /web
Deployment monitoring, rollback, notifications Local development environment → /web
PDF/EPUB generation → /book

Design Philosophy: This skill is alow-frequency operationin the Tutorial Writer workflow, but its content is complete and detailed. The Agent obtains all the information it needs at once when deployment is required.


Prerequisites

Before starting configuration, confirm that the following build-phase deliverables are ready:

✅ Build Artifact Verification (Basics)

  • Completed the /web phase (Astro project build complete)
  • bun run --filter @repo/web build succeeded, with no error output
  • apps/web/dist/ directory structure is correct
  • Local bun run dev page displays correctly

⚠️ This skill only handles website deployment to GitHub Pages. For PDF/EPUB generation, use the /book sub-skill.

⚠️ If the above conditions are not met, please first run /web to complete the website build.


🚀 Quick Publish: 4 Steps to Deploy to GitHub Pages

Step 1: Key Deployment Configuration

astro.config.mjs(the 3 key items that must be set correctly):

import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';

export default defineConfig({
  // ⭐ 关键 1:完整站点 URL(影响 SEO、sitemap、OG 图片路径)
  site: 'https://username.github.io',

  // ⭐ 关键 2:项目路径前缀(GitHub Pages 项目站点必填!)
  // 用户站点(username.github.io)可不填或设为 '/'
  base: '/repo-name/',

  // ⭐ 关键 3:避免 GitHub Pages 404 问题
  trailingSlash: 'always',    // 输出 /about/index.html 而非 /about.html

  integrations: [
    starlight({
      title: '教程标题',
      description: '教程描述',

      social: {
        github: 'https://github.com/username/repo',
      },

      sidebar: [
        { label: '首页', slug: 'index' },
        {
          label: '章节',
          autogenerate: { directory: 'chapters' },
        },
      ],

      editLink: {
        baseUrl: 'https://github.com/username/repo/edit/main/',
      },
      lastUpdated: true,
      pagination: true,
      search: { mode: 'auto' },
    }),
  ],
});

Key Configuration Items:

Configuration Item Value Description
site Full URL Affects SEO, sitemap, OG image paths
base '/repo-name/' Required for GitHub Pages project sites
trailingSlash 'always' Avoids GitHub Pages 404

Configuration Differences Between the Two Scenarios:

Scenario site Value base Value Final URL Example
User/Organization Site https://username.github.io Leave blank or '/' https://username.github.io/
Project Site(recommended) https://username.github.io '/repo-name' https://username.github.io/repo/

⚠️ Common Mistake: Forgetting to set base causes all static assets (CSS/JS/images) to 404!

Step 2: Create a GitHub Actions Workflow

File Location: .github/workflows/deploy.yml

Option A: Official withastro/action (recommended, simplest)

name: Deploy to GitHub Pages

on:
  # 推送到 main 分支时自动触发
  push:
    branches: ['main']
  # 支持手动触发(可选)
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deploy.outputs.page_url }}
    steps:
      - name: Checkout code
        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: Build site
        run: npm run build

      - name: Deploy to GitHub Pages
        id: deploy
        uses: withastro/action@v3

Option B: Standard Actions workflow (more controllable)

name: Deploy to GitHub Pages

on:
  push:
    branches: ['main']
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: pages
  cancel-in-progress: false

jobs:
  # Job 1: 构建
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        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: Build
        run: npm run build
        env:
          NODE_OPTIONS: --max-old-space-size=4096  # 大型项目防 OOM

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./dist

  # Job 2: 部署(依赖构建完成)
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

Option comparison:

Dimension Option A (withastro/action) Option B (standard workflow)
Configuration complexity ⭐ Simple (~30 lines) ⭐⭐ Medium (~60 lines)
Controllability Medium High (each step can be customized)
Use cases Standard tutorial sites Large projects requiring additional build steps
Officially recommended ✅ Yes ✅ Also a standard practice

Step 3: Configure GitHub repository Settings

  1. Go to the target repository → Settings(Settings)
  2. In the left menu, find Pages(Pages)
  3. Source(Source) select GitHub Actions
    • ⚠️ Do not select "Deploy from a branch" (old method, not recommended)
  4. Wait for the first Actions run to complete (about 2-5 minutes)
  5. Visit the displayed URL to verify the deployment succeeded:
    https://username.github.io/repo-name/
    

Step 4: Post-deployment verification

Must-check items:

  • The homepage opens normally and styles load correctly
  • All navigation links are clickable with no 404s
  • Image, CSS, and JS file paths are correct (no red errors in the browser console)
  • Search works (Pagefind index is normal)
  • Dark mode toggle works normally
  • Mobile responsive layout works normally
  • Lighthouse score ≥ 90 (Performance + Accessibility)

Quick verification command(simulate the GitHub Pages environment locally):

# 模拟 base 路径环境
GH_PAGES_BASE=/repo-name npm run build

# 使用 serve 模拟静态服务器
npx serve dist -l 3000

# 访问测试地址
# http://localhost:3000/repo-name/

🔧 Detailed configuration guide

In-depth analysis of the base path

Why must base be set?

URL structure of a GitHub Pages project site:

https://username.github.io/<repository-name>/

Astro assumes by default that the site is at the root path /, but it is actually under /<repo>/ . This causes:

  • ❌ CSS/JS requests /_astro/style.css → should actually be /<repo>/_astro/style.css
  • ❌ Image requests /images/bg.png → 404
  • ❌ Navigation links jump to the wrong address

What base does: adds a prefix to all relative paths.

Dynamic base configuration(compatible with local development + production environment):

// astro.config.mjs
export default defineConfig({
  base: process.env.GH_PAGES_BASE || '/',
  // 开发环境:base = '/'(默认)
  // 生产环境:GH_PAGES_BASE='/repo-name/' npm run build
});

package.json scripts:

{
  "scripts": {
    "dev": "astro dev",
    "build": "astro build",
    "build:gh": "GH_PAGES_BASE=/repo-name astro build",
    "preview": "astro preview"
  }
}

trailingSlash must be set to 'always'

Reason: GitHub Pages behavior mechanism

Request path GitHub Pages lookup Astro default output Result
/about /about/index.html /about.html 404 ❌
/about/ /about/index.html /about/index.html 200 ✅

Configuration method:

trailingSlash: 'always',  // ✅ 正确
// trailingSlash: 'ignore',  // ❌ 错误:导致 GitHub Pages 404

outDir configuration options

Option A: Use the default dist/ directory (recommended)

// 不设置 outDir(默认值即可)
// GitHub Actions 使用 actions/upload-pages-artifact 上传 dist/

Advantages:

  • ✅ Follows Astro conventions
  • ✅ Best support from the official Action
  • ✅ No need for .nojekyll file

Option B: Output to docs/ directory (traditional method)

outDir: './docs',

Use cases:

  • Not using GitHub Actions (manual deployment)
  • Select "Deploy from branch" in Settings → gh-pages branch or /docs folder

⚠️ must be in the docs/ directory, create .nojekyll file:

# 方式一:构建后自动创建
echo "" > docs/.nojekyll

# 方式二:在 public/ 中放置(每次构建自动复制)
echo "" > public/.nojekyll

Reason: GitHub Pages uses Jekyll by default, which ignores directories starting with _ (such as _astro/), causing all JS/CSS to be lost!


🌐 Custom Domain Configuration

Method 1: Via GitHub Settings (recommended)

  1. Settings → Pages → Custom domain
  2. Enter the domain (such as www.example.com or example.com)
  3. Wait for GitHub to automatically create the DNS record prompt
  4. Add the DNS record at your domain registrar:

Apex Domain Configuration(example.com):

Type Name Value TTL
A @ 185.199.108.153 3600
A @ 185.199.109.153 3600
A @ 185.199.110.153 3600
A @ 185.199.111.153 3600
CNAME www username.github.io 3600

Subdomain Configuration(www.example.com / blog.example.com):

Type Name Value TTL
CNAME www/blog username.github.io 3600
  1. Wait for DNS to take effect (usually a few minutes, up to 48 hours)
  2. Enable Enforce HTTPS(force HTTPS, improve security)

Method 2: CNAME file

In public/CNAME add:

www.example.com

Or Apex domain:

example.com

Update astro.config.mjs

site: 'https://www.example.com',  // 更新为自定义域名
base: '/',                        // 自定义域名通常不需要 base(根路径)
trailingSlash: 'always',

SSL/TLS Certificate

✅ GitHub Pages automatically provides a Let's Encrypt certificate:

  • Free, automatic renewal
  • Supports HTTP/2
  • Enable forced redirect in Settings → Pages → Enforce HTTPS

🔄 Advanced CI/CD Configuration

Multi-environment Deployment (Staging / Production)

Branch Strategy:

main          → Production 部署(正式站点)
staging       → Staging 部署(预发布测试)
develop       → 开发环境(开发者日常验证)

.github/workflows/deploy-staging.yml:

name: Deploy to Staging

on:
  push:
    branches: ['staging']

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    environment:
      name: github-pages-staging  # 单独的环境名称
      url: ${{ steps.deploy.outputs.page_url }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: npm
      - run: npm ci
      - run: npm run build
      - uses: withastro/action@v3

⚠️ Note: GitHub Free only supports 1 GitHub Pages environment. Staging and Production share the same URL. If you need fully isolated environments, consider using Cloudflare Pages or Vercel (which support multiple environments for free).

Preview Deployments (PR preview deployments)

Automatically create a preview deployment for each Pull Request:

# .github/workflows/preview.yml
name: Preview Deployment

on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  preview:
    runs-on: ubuntu-latest
    environment:
      name: github-pages-preview-${{ github.event.pull_request.number }}
      url: ${{ steps.deploy.outputs.page_url }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: npm
      - run: npm ci
      - run: npm run build
      - uses: withastro/action@v3

Deployment Notifications (Slack / Discord / Email)

In deploy.yml add a notification step at the end:

      - name: Notify Success
        if: success()
        run: |
          curl -X POST -H 'Content-type: application/json' \
          --data '{
            "text": "✅ 教程站点部署成功!\n仓库: ${{ github.repository }}\n提交: ${{ github.sha }}\n作者: ${{ github.actor }}\nURL: ${{ steps.deploy.outputs.page_url }}"
          }' \
          ${{ secrets.SLACK_WEBHOOK_URL }}

      - name: Notify Failure
        if: failure()
        run: |
          curl -X POST -H 'Content-type: application/json' \
          --data '{
            "text": "❌ 部署失败!\n仓库: ${{ github.repository }}\n查看: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
          }' \
          ${{ secrets.SLACK_WEBHOOK_URL }}

Automatic Rollback Mechanism (advanced)

Automatic rollback based on health checks (add after the deploy job):

  health-check:
    runs-on: ubuntu-latest
    needs: [build-and-deploy]  # 依赖部署完成
    if: always()               # 即使部署成功也执行检查
    steps:
      - name: Wait for Deployment
        run: sleep 30  # 等待 CDN 生效

      - name: Health Check
        id: health
        run: |
          STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
            "${{ needs.build-and-deploy.outputs.page_url }}")

          if [ "$STATUS" != "200" ]; then
            echo "❌ Health check failed! Status: $STATUS"
            echo "rollback_needed=true" >> $GITHUB_OUTPUT
            exit 1
          fi
          echo "✅ Site healthy"
          echo "rollback_needed=false" >> $GITHUB_OUTPUT

      - name: Create Rollback Issue
        if: failure()
        run: |
          gh issue create \
            --title "🚨 部署失败 - 需要回滚" \
            --body "部署未通过健康检查。\n\n**操作建议**:\n1. \`git revert HEAD\`\n2. 推送到 main 触发重新部署\n3. 或手动回滚到上一个稳定版本" \
            --repo ${{ github.repository }}
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

🐛 Common Troubleshooting Guide

Issue 1: All static assets return 404

Symptoms:

  • The page HTML loads successfully, but styles are lost and images do not display
  • Console error:GET https://username.github.io/_astro/style.css 404

Cause: base is not set or the base value is incorrect

Solution:

// astro.config.mjs
base: '/your-repo-name/',  // 必须与仓库名完全一致

Verification Method:

# 检查生成的 HTML 中的资源路径
cat dist/index.html | grep '_astro'
# 应该看到:/_astro/style.abc123.css
# 如果是 /your-repo-name/_astro/style.abc123.css 则正确

Issue 2: 404 after clicking a navigation link

Symptoms:

  • The homepage works, but clicking a sidebar or internal link returns 404
  • Directly refreshing the page also returns 404

Cause: trailingSlash: 'always'

Solution:

trailingSlash: 'always',

Issue 3: _astro/ directory is ignored (all JS/CSS missing)

Symptoms:

  • The build succeeds, but the website has no styles or interactive functionality at all
  • The browser Network panel shows all /_astro/* requests return 404

Cause: GitHub Pages uses Jekyll processing, which ignores directories starting with _ Directory at the beginning

Solution(in order of priority):

  1. Using GitHub Actions(Recommended): Automatically bypass Jekyll
  2. Add .nojekyll file:
    touch public/.nojekyll  # 或 touch docs/.nojekyll
    

Issue 4: Out of memory during build (OOM)

Symptoms:

  • GitHub Actions error:FATAL ERROR: Ineffective mark-compacts near heap limit
  • Large tutorial sites (100+ chapters) easily trigger this

Solution:

# deploy.yml 的 build step 中添加环境变量
- name: Build
  run: npm run build
  env:
    NODE_OPTIONS: --max-old-space-size=4096  # 增加到 4GB

Long-term optimization:

  • Reduce the amount of content per build (build in batches)
  • Enable Astro 6.0+ experimental Queued Rendering (2x rendering speed improvement)
  • Clean up unused dependencies and plugins

Issue 5: Slow deployment (>10 minutes)

Optimization strategies:

  1. ✅ Enable dependency caching(already configured in the template)
  2. ✅ Reduce the number of Content Collections: If there are hundreds of pieces of content, consider batching
  3. ✅ Enable experimental Queued Rendering(Astro 6.0+):
    experimental: {
      queuedRendering: { enabled: true },
    },
    
  4. ✅ Optimize images: Use WebP format, reduce the number and size of images
  5. ✅ Streamline plugins: Remove unnecessary Starlight plugins

📋 Complete deployment checklist

Before deployment (build-stage deliverable verification)

  • npm run build No errors (exit 0)
  • astro.config.mjs in site and base correctly set
  • trailingSlash: 'always' configured
  • local npm run preview displays correctly
  • No 404/500 errors in the browser console
  • All images, CSS, and JS resources load successfully
  • All internal links are clickable and do not 404
  • Responsive layout verification passed (375px / 768px / 1280px)
  • Dark mode toggle works correctly
  • Search function is available
  • Lighthouse Performance ≥ 90, Accessibility ≥ 90

Configuration verification

  • .github/workflows/deploy.yml exists and has correct syntax
  • Actions permissions are configured correctly (contents: read, pages: write, id-token: write)
  • Node.js version ≥ 18 (20 recommended)
  • If using a custom domain, DNS records are configured

After deployment (production environment verification)

  • GitHub Actions workflow runs successfully (green ✓)
  • Accessing the GitHub Pages URL opens normally
  • Homepage styles, layout, and images display correctly
  • Navigation menu is clickable, and all chapters are reachable
  • In-page search is available
  • Mobile display works correctly
  • No sensitive information leakage (API keys, passwords, etc.)
  • Custom domain HTTPS works correctly (if configured)
  • Lighthouse score meets the standard (online version)

📊 Monitoring and maintenance

Uptime monitoring (free options)

Service Features Price
UptimeRobot Checks every 5 minutes, email/Slack notifications Free
Better Uptime Includes status page, phone/SMS alerts Free basic version
GitHub Status Limited monitoring (only view deployment history) Free

UptimeRobot configuration example:

  • Monitoring URL: https://username.github.io/repo/
  • Check frequency: 5 minutes
  • Keyword detection: <title> site name in the tag
  • Notifications: Slack Webhook / Email

Core Web Vitals monitoring (optional)

Add in the layout component:

---
// src/layouts/BaseLayout.astro(如果自定义布局)
---

<script>
  import { onCLS, onFID, onINP, onLCP } from 'web-vitals';

  function sendToAnalytics(metric) {
    const body = JSON.stringify(metric);
    navigator.sendBeacon('/api/vitals', body);
  }

  onCLS(sendToAnalytics);
  onFID(sendToAnalytics);
  onINP(sendToAnalytics);
  onLCP(sendToAnalytics);
</script>

Sentry error tracking (recommended for production)

# 安装 SDK
npm install @sentry/astro
// astro.config.mjs
import sentry from '@sentry/astro';

export default defineConfig({
  integrations: [
    sentry({
      dsn: import.meta.env.SENTRY_DSN,
      tracesSampleRate: 0.1,
    }),
  ],
});

🔗 Integration with the build phase

Trigger conditions

When the following conditionsare all met, invoke this skill to enter the deployment process:

# ✅ 构建成功
npm run build && echo "Exit code: $?"

# ✅ 本地预览正常
npm run preview &
# 浏览器访问 http://localhost:4321 确认无误

# 准备就绪,调用部署技能
→ /github-pages         # 进入 GitHub Pages 部署流程

Common integration issues

Issue Cause Solution
URL path 404 base Configuration does not match the repository name Ensure base: '/repo-name/' matches the GitHub repository name
Build artifacts missing /web phase not completed First run /web to complete the build
Static assets missing Jekyll processing issue Use GitHub Actions or add .nojekyll
Deployment timeout Build time too long Increase Node memory or optimize build performance

📂 Structure of this skill

skills/tutorial-writer-github-pages/
├── SKILL.md                              ← 本文件(自含型 ~650行)
└── references/
    ├── web-publishing.md                 ← Web 发布基础参考
    ├── decision-record-rules.md          ← 决策细则
    └── github-pages-guide.md             ← 高级部署场景详解

📚 Reference documentation index

Document Content When to read
web-publishing.md Web publishing basic configuration + Astro/Starlight reference When build details are needed
github-pages-guide.md Multi-environment deployment, rollback strategies, security hardening, migration guide When advanced deployment scenarios are needed

💡 Loading timing: Read only when additional details are needed; this file already covers the main deployment process


🔗 Related resources

Resource Path/Link Purpose
Parent skill ../SKILL.md Tutorial Writer main router
Web build sub-skill ../skills/tutorial-writer-web/SKILL.md Astro build process
Book generation sub-skill ../skills/tutorial-writer-book/SKILL.md PDF/EPUB generation
Astro official deployment documentation https://docs.astro.build/guides/deploy/github/ Official authoritative guide
withastro/action https://github.com/withastro/action Official Action repository
GitHub Pages documentation https://docs.github.com/en/pages Complete GitHub Pages documentation

Version history

Version Date Changes
v1.0.0 2026-05-31 🔄 Monorepo architecture refactor: Renamed from publish to github-pages; removed multi-format publishing support (PDF/EPUB/Releases → /book sub-skill); focused on pure GitHub Pages deployment; added scope of responsibility statement; prerequisites simplified to only checking the web package build artifacts; metadata added focus/target fields; version number reset to v1.0.0
v7.0.0 2026-05-31 Content-First v2 alignment upgrade (previous version, deprecated)
v6.1.0 2026-05-30 Flattening refactor: upgraded from 1-Sub Router to a self-contained single-file skill
v6.0.0 2026-05-30 1-Sub Router (publish → website-deploy) (previous version)