generate a changelog page automatically in Jekyll

Why does documentation need a changelog?

In software projects, changelogs track versioned releases. But in content-driven Jekyll sites—like documentation hubs or knowledge bases—changelogs help users and contributors stay informed about what’s new, changed, or deprecated in the docs.

Having a structured changelog also increases transparency, boosts trust, and can even reduce support tickets by showing users that their issues are being addressed.

Approach 1: Use a dedicated Jekyll collection for changelogs

Create a _changelog/ folder in your repo:


_changelog/
  2025-07-01-initial-release.md
  2025-07-10-auth-updated.md
  2025-07-27-v1-1-fixes.md

Each changelog entry should have rich front matter:


---
title: "Auth Guide Updated"
date: 2025-07-10
version: "v1.1"
type: update
related_docs:
  - /guides/setup-auth/
author: devina
source: "https://github.com/org/repo/pull/42"
---

This allows you to filter, sort, and link everything programmatically.

Approach 2: Generate a changelog index page dynamically

Create a page like changelog.md and use Liquid to iterate over the _changelog collection:


---
layout: default
title: "Documentation Changelog"
permalink: /changelog/
---

{% raw %}
<ul class="changelog-list">
  {% assign entries = site.changelog | sort: "date" | reverse %}
  {% for entry in entries %}
    <li>
      <strong>{{ entry.date }} – {{ entry.title }}</strong>
      {% if entry.version %}<span class="tag">{{ entry.version }}</span>{% endif %}
      {% if entry.type %}<em>({{ entry.type }})</em>{% endif %}
      {% if entry.related_docs %}
        <br/><small>Updated:</small>
        <ul>
          {% for path in entry.related_docs %}
            <li><a href="{{ path }}">{{ path }}</a></li>
          {% endfor %}
        </ul>
      {% endif %}
      {% if entry.source %}
        <p><a href="{{ entry.source }}">View PR</a></p>
      {% endif %}
    </li>
  {% endfor %}
</ul>
{% endraw %}

Now you have a full changelog that renders dynamically as entries are added.

Approach 3: Automatically generate changelog entries from Pull Requests

For advanced use, integrate with GitHub Actions to generate changelog entries from PR metadata:

  1. Tag PRs with labels like docs:update or docs:new
  2. Use a GitHub Action to extract PR title, author, and linked docs
  3. Write to a new file in _changelog/ based on commit data

Example action step:


- name: Generate changelog entry
  run: node scripts/generate-changelog.js

This script could write a Markdown file using a template and PR metadata.

Optional: Include changelog excerpts in homepage or sidebar


{% raw %}
<h3>Latest Updates</h3>
{% assign latest = site.changelog | sort: "date" | reverse | slice: 0, 3 %}
<ul>
  {% for item in latest %}
    <li><a href="{{ item.url }}">{{ item.title }}</a> ({{ item.date }})</li>
  {% endfor %}
</ul>
{% endraw %}

This adds visibility to the most recent changes and encourages repeat visits.

Optional: Create per-version changelog pages

If your docs are versioned, group entries accordingly:


{% raw %}
{% assign grouped = site.changelog | group_by: "version" %}
{% for group in grouped %}
  <h3>Version {{ group.name }}</h3>
  <ul>
    {% for entry in group.items %}
      <li><a href="{{ entry.url }}">{{ entry.title }}</a></li>
    {% endfor %}
  </ul>
{% endfor %}
{% endraw %}

Best practices for managing changelog entries

  • Include meaningful version and type fields
  • Link to PRs or Issues for traceability
  • Standardize fields in a template for each entry
  • Consider using a script to scaffold new entries

Conclusion: Automate visibility, not just publishing

A changelog isn't just a nice-to-have—it's a record of progress, decisions, and improvements. In Jekyll, building one doesn’t require a database or backend—just consistent structure and thoughtful Liquid logic.

As your site grows, an automated changelog keeps contributors aligned, gives users confidence, and documents the evolution of your product or knowledge base transparently.