Post

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.

Setting Up a Developer Blog with Jekyll Chirpy — SEO, Analytics, Comments, and Pageviews

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

ComponentToolCost
Static Site GeneratorJekyllFree
ThemeChirpyFree
HostingGitHub PagesFree
AnalyticsGoogle AnalyticsFree
Search IndexingBing Webmaster ToolsFree
Instant IndexingIndexNowFree
Pageview CounterGoatCounterFree (personal)
CommentsGiscusFree
CI/CDGitHub ActionsFree

Total cost: $0/month


Step 1: Create Your Blog Repository

Use the Chirpy starter template:

  1. Go to chirpy-starter and click “Use this template”
  2. Name the repo <yourusername>.github.io
  3. 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 url field 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 :title permalink.

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 keywords
  • description — keep it under 160 characters for search results
  • image — 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

  1. Go to Google Search Console
  2. Add your property: https://yourusername.github.io
  3. Choose HTML tag verification and copy the content value
  4. 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.

  1. Go to Bing Webmaster Tools
  2. Sign in with your Microsoft account
  3. Add your site: https://yourusername.github.io
  4. Choose the XML file verification method — download BingSiteAuth.xml
  5. Place it in your repo root
  6. 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:

  1. Create a property at analytics.google.com
  2. Get your Measurement ID (starts with G-)
  3. 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.

  1. Create a free account at goatcounter.com
  2. Note your site code (the subdomain, e.g., yoursite)
  3. 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

  1. Your repo must be public
  2. Install the Giscus GitHub App on your repo
  3. 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

#ItemStatus
1_config.yml configured with your details 
2First post published in _posts/ 
3GitHub Actions deploying successfully 
4Google Search Console verified 
5Sitemap submitted to Search Console 
6Google Analytics tracking confirmed 
7GoatCounter pageviews showing 
8Giscus comments working 
9Thin pages excluded from sitemap 
10Avatar 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: false defaults 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_id and category_id are 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

ResourceURL
Chirpy Theme Docschirpy.cotes.page
Chirpy Starter Templategithub.com/cotes2020/chirpy-starter
Jekyll Documentationjekyllrb.com/docs
GitHub Pages Docsdocs.github.com/pages
Google Search Consolesearch.google.com/search-console
Google Analyticsanalytics.google.com
GoatCountergoatcounter.com
Giscusgiscus.app
IndexNowindexnow.org
Bing Webmaster Toolsbing.com/webmasters
unDraw (free SVGs)undraw.co
Jekyll Sitemap Plugingithub.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.


This post is licensed under CC BY 4.0 by the author.