Setting Up a Developer Blog with Jekyll Chirpy — SEO, Analytics, Comments, and Pageviews
Complete guide to setting up a developer blog using Jekyll Chirpy theme on GitHub Pages. Covers SEO optimization, Google Analytics, GoatCounter pageviews, Giscus comments, sitemap configuration, and deployment — with code snippets and config examples.
Why This Guide?
Starting a tech blog shouldn’t take days of research. I recently set up this blog using Jekyll with the Chirpy theme on GitHub Pages — free hosting, custom domain support, and zero server management.
This post documents the exact steps: from first deploy to having a fully functional blog with SEO, analytics, comments, and pageview counters. Everything you need as a starting point.
The Stack
| Component | Tool | Cost |
|---|---|---|
| Static Site Generator | Jekyll | Free |
| Theme | Chirpy | Free |
| Hosting | GitHub Pages | Free |
| Analytics | Google Analytics | Free |
| Search Indexing | Bing Webmaster Tools | Free |
| Instant Indexing | IndexNow | Free |
| Pageview Counter | GoatCounter | Free (personal) |
| Comments | Giscus | Free |
| CI/CD | GitHub Actions | Free |
Total cost: $0/month
Step 1: Create Your Blog Repository
Use the Chirpy starter template:
- Go to chirpy-starter and click “Use this template”
- Name the repo
<yourusername>.github.io - Clone it locally:
1
2
git clone https://github.com/<yourusername>/<yourusername>.github.io.git
cd <yourusername>.github.io
Install dependencies and run locally:
1
2
bundle install
bundle exec jekyll serve
Your site is now live at http://localhost:4000.
Step 2: Configure _config.yml
This is the heart of your blog. Here’s the essential configuration:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
theme: jekyll-theme-chirpy
lang: en
timezone: Asia/Singapore # Change to your timezone
title: Your Name
tagline: Your tagline here
description: >-
A brief description for SEO purposes. This appears in search results.
url: "https://yourusername.github.io"
baseurl: ""
github:
username: yourusername
social:
name: Your Name
email: your@email.com
links:
- https://github.com/yourusername
- https://linkedin.com/in/yourprofile
avatar: https://avatars.githubusercontent.com/yourusername
toc: true
paginate: 10
Replace all placeholder values with your own details. The
urlfield is critical for SEO and sitemap generation.
Step 3: Write Your First Post
Create a file in _posts/ with the naming format:
1
YYYY-MM-DD-title-of-your-post.md
The date in the filename is mandatory for Jekyll posts. It won’t appear in your URL if you use the
:titlepermalink.
Front matter template:
1
2
3
4
5
6
7
8
9
---
title: "Your Post Title"
date: 2026-08-10
categories: [Category1, Category2]
tags: [tag1, tag2, tag3]
description: "One-line description for SEO and social sharing."
---
Your content here in Markdown...
Tips for front matter:
categories— use max 2 levels (parent, child)tags— use lowercase, hyphenated, relevant keywordsdescription— keep it under 160 characters for search resultsimage— appears as the post thumbnail and social preview
Step 4: Deploy with GitHub Actions
Create .github/workflows/pages-deploy.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
name: "Build and Deploy"
on:
push:
branches:
- main
paths-ignore:
- .gitignore
- README.md
- LICENSE
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3"
bundler-cache: true
- name: Build site
run: bundle exec jekyll build
env:
JEKYLL_ENV: production
- name: Upload site artifact
uses: actions/upload-pages-artifact@v4
with:
path: "_site"
deploy:
environment:
name: github-pages
url: $
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Then in your repo settings:
- Go to Settings → Pages
- Set source to GitHub Actions
Every push to main will now auto-build and deploy.
Step 5: SEO Setup
Google Search Console Verification
- Go to Google Search Console
- Add your property:
https://yourusername.github.io - Choose HTML tag verification and copy the content value
- Add it to
_config.yml:
1
2
webmaster_verifications:
google: "your-verification-code-here"
Sitemap
The jekyll-sitemap gem auto-generates a sitemap at /sitemap.xml. Add it to your Gemfile:
1
2
3
group :jekyll_plugins do
gem "jekyll-sitemap"
end
Submit your sitemap URL in Google Search Console:
1
https://yourusername.github.io/sitemap.xml
Sitemap Optimization — Exclude Thin Pages
New blogs with few posts generate many thin tag/category pages. Exclude them from the sitemap until you have enough content:
1
2
3
4
5
6
7
8
9
10
11
defaults:
- scope:
path: ""
type: tags
values:
sitemap: false
- scope:
path: ""
type: categories
values:
sitemap: false
A lean sitemap with only quality pages helps Google focus its crawl budget on your actual content.
Exclude Non-Content Files
If you have verification HTML files (like google*.html), exclude them from the sitemap by adding front matter:
1
2
3
---
sitemap: false
---
Bing Webmaster Tools
Bing also powers Yahoo and DuckDuckGo results, so submitting here covers 3 search engines at once.
- Go to Bing Webmaster Tools
- Sign in with your Microsoft account
- Add your site:
https://yourusername.github.io - Choose the XML file verification method — download
BingSiteAuth.xml - Place it in your repo root
- Also add the verification code to
_config.yml:
1
2
3
webmaster_verifications:
google: "your-google-verification-code"
bing: "your-bing-verification-code"
After deploying, click Verify in Bing Webmaster Tools, then submit your sitemap:
1
https://yourusername.github.io/sitemap.xml
Bing indexes slower than Google but is worth setting up early — it’s zero effort once configured.
IndexNow — Instant Indexing on Deploy
IndexNow is a protocol that instantly notifies search engines (Google, Bing, Yandex) when your content changes. Instead of waiting days for crawlers to discover new posts, they get notified within seconds of deployment.
Step 1: Generate a key
Create a random 32-character hex string (your unique key):
1
python3 -c "import uuid; print(uuid.uuid4().hex)"
Step 2: Host the key file
Create a file named <your-key>.txt at the root of your repo. The file content should be the key itself:
1
a836b82a06fc4136b58b9ab921e7c697
Step 3: Add an IndexNow job to your GitHub Actions workflow
Add this job after the deploy job in .github/workflows/pages-deploy.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
notify-indexnow:
runs-on: ubuntu-latest
needs: deploy
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Submit changed URLs to IndexNow
run: |
SITE_URL="https://yourusername.github.io"
KEY="your-key-here"
CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD -- '_posts/*.md' 2>/dev/null || echo "")
URLS=""
for file in $CHANGED_FILES; do
slug=$(basename "$file" .md | sed 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-//')
URLS="$URLS\"${SITE_URL}/posts/${slug}/\","
done
URLS="\"${SITE_URL}/\",$URLS"
URLS=$(echo "$URLS" | sed 's/,$//')
curl -s -X POST "https://api.indexnow.org/indexnow" \
-H "Content-Type: application/json" \
-d "{
\"host\": \"yourusername.github.io\",
\"key\": \"${KEY}\",
\"keyLocation\": \"${SITE_URL}/${KEY}.txt\",
\"urlList\": [${URLS}]
}"
How it works:
- After every deploy, the job detects which posts changed
- It sends those URLs to
api.indexnow.org - IndexNow distributes to all participating search engines (Google, Bing, Yandex)
- Your new content gets crawled within minutes, not days
IndexNow notifies all participating search engines with a single API call. No separate setup needed for each engine.
Step 6: Google Analytics
Set up tracking to understand your audience:
- Create a property at analytics.google.com
- Get your Measurement ID (starts with
G-) - Add to
_config.yml:
1
2
3
analytics:
google:
id: G-XXXXXXXXXX
That’s it. Chirpy injects the tracking script automatically. You’ll see data in your GA dashboard within 24–48 hours.
Step 7: GoatCounter Pageviews
Display a view count on each post — lightweight, privacy-friendly, no cookie banner needed.
- Create a free account at goatcounter.com
- Note your site code (the subdomain, e.g.,
yoursite) - Add both the analytics tracking and the pageview display config:
1
2
3
4
5
6
7
8
analytics:
google:
id: G-XXXXXXXXXX
goatcounter:
id: yoursite
pageviews:
provider: goatcounter
GoatCounter serves dual purpose here: it tracks visits AND provides the view count that Chirpy displays on each post.
The view count appears automatically next to the post date — no custom code needed.
Step 8: Giscus Comments
Add a GitHub-powered comment section to every post using Giscus.
Prerequisites
- Your repo must be public
- Install the Giscus GitHub App on your repo
- Enable Discussions in your repo (Settings → Features → Discussions)
Get Your Config
Go to giscus.app, enter your repo name, and select your preferences. It generates the required IDs.
Add to _config.yml
1
2
3
4
5
6
7
8
9
10
11
12
comments:
provider: giscus
giscus:
repo: yourusername/yourusername.github.io
repo_id: R_kgDOxxxxxxx
category: General
category_id: DIC_kwDOxxxxxxx
mapping: pathname
strict: 0
input_position: top
lang: en
reactions_enabled: 1
Comments now appear at the bottom of every post. Readers authenticate with their GitHub account to comment.
Giscus automatically matches your site’s dark/light theme. No extra configuration needed.
Complete _config.yml Reference
Here’s everything together — copy this as your starting template:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
theme: jekyll-theme-chirpy
lang: en
timezone: Asia/Singapore
# Site identity
title: Your Name
tagline: Your tagline
description: >-
Your SEO description here.
url: "https://yourusername.github.io"
baseurl: ""
# Social
github:
username: yourusername
social:
name: Your Name
email: you@email.com
links:
- https://github.com/yourusername
# Verification
webmaster_verifications:
google: "your-google-verification-code"
# Appearance
avatar: https://avatars.githubusercontent.com/yourusername
toc: true
# Analytics
analytics:
google:
id: G-XXXXXXXXXX
goatcounter:
id: yoursite
# Pageviews on posts
pageviews:
provider: goatcounter
# Comments
comments:
provider: giscus
giscus:
repo: yourusername/yourusername.github.io
repo_id: R_kgDOxxxxxxx
category: General
category_id: DIC_kwDOxxxxxxx
mapping: pathname
strict: 0
input_position: top
lang: en
reactions_enabled: 1
# Pagination
paginate: 10
Checklist Before Going Live
| # | Item | Status |
|---|---|---|
| 1 | _config.yml configured with your details | |
| 2 | First post published in _posts/ | |
| 3 | GitHub Actions deploying successfully | |
| 4 | Google Search Console verified | |
| 5 | Sitemap submitted to Search Console | |
| 6 | Google Analytics tracking confirmed | |
| 7 | GoatCounter pageviews showing | |
| 8 | Giscus comments working | |
| 9 | Thin pages excluded from sitemap | |
| 10 | Avatar and social links set |
Common Pitfalls
Posts not showing up?
- Filename must be
YYYY-MM-DD-title.md— no exceptions - Date must not be in the future (relative to your timezone setting)
- File must be in
_posts/directory
Sitemap bloated with tag pages?
- Add
sitemap: falsedefaults for tags/categories as shown above - Wait until you have 3+ posts per tag before including them
Comments not loading?
- Verify the Giscus app is installed on your repo
- Discussions must be enabled in repo settings
- Check
repo_idandcategory_idare correct
Analytics not tracking?
- Wait 24–48 hours for Google Analytics to show data
- Use GA’s Realtime report to verify immediately
- Check browser ad-blockers aren’t blocking the script
Useful Links
| Resource | URL |
|---|---|
| Chirpy Theme Docs | chirpy.cotes.page |
| Chirpy Starter Template | github.com/cotes2020/chirpy-starter |
| Jekyll Documentation | jekyllrb.com/docs |
| GitHub Pages Docs | docs.github.com/pages |
| Google Search Console | search.google.com/search-console |
| Google Analytics | analytics.google.com |
| GoatCounter | goatcounter.com |
| Giscus | giscus.app |
| IndexNow | indexnow.org |
| Bing Webmaster Tools | bing.com/webmasters |
| unDraw (free SVGs) | undraw.co |
| Jekyll Sitemap Plugin | github.com/jekyll/jekyll-sitemap |
What’s Next?
Once your blog is live with all these features, focus on:
- Writing consistently — even one post a month builds SEO authority
- Sharing on LinkedIn/Twitter — drives initial traffic before organic search kicks in
- Requesting indexing in Search Console for each new post
- Monitoring GoatCounter — see which topics resonate with readers
The technical setup is the easy part. The hard part is writing. Start now.
Related Posts
- Java 18 to Java 21 Migration Guide — Features, Code Examples, Checklist — Upgrade to the latest LTS with virtual threads, pattern matching, and sequenced collections.
- Java Collections + Lambda Expressions — Practical Guide with Code Examples — Master streams, filtering, sorting, and grouping with real before/after examples.