Table of Contents
Overview
In the previous post Layout and Component Architecture, we covered the blog’s structure. In this post, we’ll explain the process of deploying the completed blog to GitHub Pages.
With Jekyll, pushing code would trigger automatic build/deployment on GitHub’s servers, but with Astro, you need to build locally and deploy the output yourself. While this adds one more step, it provides the advantage of having full control over the build environment and the freedom to use any plugin.
Understanding the Build Pipeline
It helps to understand how the build process works before deployment. Running a single npm run deploy command triggers multiple stages automatically in sequence.
npm run deploy
↓
1. predeploy: npm run share:sync
↓
2. preshare:sync: npm run build
↓
3. build: astro build && npx pagefind --site dist
↓
4. share:sync: node scripts/share.mjs sync
↓
5. deploy: gh-pages -d dist -r ...
This flow leverages npm’s pre script feature. When you run deploy, predeploy automatically runs first, and when share:sync runs, preshare:sync automatically runs first, and so on. Thanks to this, a single npm run deploy command chains through the entire process: build, search index generation, share synchronization, and deployment.
Step-by-Step Explanation
Here’s a summary of what each step does:
| Step | Script | Role |
|---|---|---|
| 1 | astro build | Builds the Astro project into static HTML/CSS/JS in the dist/ directory |
| 2 | npx pagefind --site dist | Generates search index from the built HTML |
| 3 | share:sync | Synchronizes social share status based on RSS feeds |
| 4 | gh-pages -d dist | Deploys the dist/ directory to GitHub Pages |
Deploying with gh-pages
Installation
gh-pages is a package that automatically pushes built static files to the GitHub Pages branch (gh-pages). Since it’s only used during builds, install it as a dev dependency.
npm install -D gh-pages
Deploy Script
Set up the deploy script in package.json as follows:
{
"scripts": {
"deploy": "gh-pages -d dist -r [email protected]:posstree/deku.posstree.com.git -t"
}
}
Option Descriptions
Here’s what each option means:
| Option | Value | Description |
|---|---|---|
-d dist | dist | Directory to deploy. The build output directory for Astro |
-r | git@personal:... | Target remote repository. Uses an SSH key alias (personal) |
-t | - | Include hidden files (like .nojekyll) in the deployment |
The -t option is particularly important. Without it, files starting with a dot (.) like .nojekyll won’t be included in the deployment, causing the site to malfunction.
Running the Deployment
Once configured, a single command runs the entire process from build to deployment automatically.
npm run deploy
Custom Domain Setup
CNAME File
To use a custom domain instead of username.github.io on GitHub Pages, you need a CNAME file. Write the domain you want to use as a single line in a public/CNAME file.
deku.posstree.com
Files in the public/ directory are copied directly to the dist/ directory during the build, so they are automatically included in the deployment without any additional configuration.
DNS Configuration
Set up a CNAME record in your domain manager (e.g., Cloudflare, Route53) to point your custom domain to GitHub Pages.
CNAME deku.posstree.com → username.github.io
The Role of the .nojekyll File
This is a file you must know about when using Astro on GitHub Pages.
public/.nojekyll
GitHub Pages processes uploaded files with Jekyll by default. However, when you build with Astro, it creates a directory called _astro/, and Jekyll ignores directories starting with _. As a result, CSS and JavaScript files fail to load, causing the site to appear broken.
Placing a .nojekyll file at the root tells GitHub Pages to skip Jekyll processing and serve the uploaded files as-is. Although it’s an empty file, the site won’t function properly without it, so it must be included.
Comparison with Jekyll Deployment
Here’s a comparison of how the deployment approach changed when moving from Jekyll to Astro.
| Item | Jekyll | Astro |
|---|---|---|
| Build location | Built on GitHub Pages server | Build locally, deploy the output |
| Build time | ~209 seconds (server) | ~30 seconds (local) |
| Plugin limitation | Only plugins allowed by GitHub Pages | Free to use any plugin |
| Build control | Dependent on GitHub | Full local control |
| .nojekyll | Not needed | Required |
| Deploy tool | Automatic deployment with just git push | Uses gh-pages package |
Jekyll was convenient initially since all you had to do was git push, but the inability to control the build environment meant limited plugin options. Astro adds the extra step of local building, but it enables the free use of advanced features like custom rehype plugins and Sharp image transformations.
For information on the previous Jekyll deployment method, see the GitHub Pages Deployment post.
Wrap-up
In this post, we covered how to deploy an Astro blog to GitHub Pages.
- Automated build pipeline using npm’s
prescripts (build, search index, share sync, deploy) - Simple deployment with the
gh-pagespackage (including hidden files with the-toption) - Custom domain setup with
public/CNAME - Disabling
Jekyllprocessing with the.nojekyllfile (preventing_astro/directory from being ignored)
In the next post Social Share Automation Script, we’ll cover the script that automatically shares posts to social media during deployment.
Series Guide
This post is part of the Jekyll to Astro migration series.
- Why I Migrated from Jekyll to Astro
- Astro Installation and Project Setup
- Content Collections and Markdown Migration
- Multilingual (i18n) Implementation
- SEO Implementation
- Image Optimization — Custom rehype Plugin
- Comment System (Utterances)
- Ad Integration (Google AdSense)
- Search Implementation with Pagefind
- Layout and Component Architecture
- GitHub Pages Deployment
- Social Share Automation Script
- Troubleshooting and Tips
Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!
App promotion
Deku.Deku created the applications with Flutter.If you have interested, please try to download them for free.