Changelog Templates
Create beautiful, customized changelogs with ReleaseKit’s powerful templating system.
Overview
ReleaseKit uses the Liquid template engine to give you complete control over your changelog formatting. Whether you need Markdown for GitHub, HTML for your website, formatted text for Slack, or plain text for Word and other documents, templates make it easy.
Template Basics
Understanding Liquid
Liquid is a simple, safe templating language that uses:
- Variables:
{{ variable }} - Tags:
{% tag %} - Filters:
{{ variable | filter }}
Available Variables
ReleaseKit provides these variables in your templates:
Release Variables
{{ release.version }} # e.g., "v1.2.0"
{{ release.title }} # e.g., "October Release"
{{ release.date }} # e.g., "2024-10-01"
{{ release.description }} # Release description
{{ release.project }} # Linear project nameIssue Variables
{% for issue in issues %}
{{ issue.id }} # Linear issue ID
{{ issue.issueId }} # Linear isse ID (short) e.g. REL-1
{{ issue.title }} # Issue title
{{ issue.description }} # Issue description
{{ issue.url }} # Linear issue URL
{{ issue.state }} # Linear state e.g. Todo
{{ issue.priority }} # e.g. 2 (high)
{{ issue.assigneeName }}. # e.g. John Doe
{% endfor %}Default Template
ReleaseKit includes a simple pre-built template.
Markdown Template (Default)
Perfect for GitHub/GitLab releases:
# {{release.name}} {{release.version}}
Released on {{release.date}}
## What's New
{% for issue in issues %}
- **{{ issue.title }}** ([Linear Issue]({{ issue.url }}))
{% endfor %}Output:
# New Test Release 1.0.0
Released on October 31, 2025
## What's New
- **Add dark mode support** ([Linear Issue](https://linear.app/...))
- **Implement user preferences** ([Linear Issue](https://linear.app/...))
- **Fix login issue on Safari** ([Linear Issue](https://linear.app/...))
Custom Templates
Creating a Template
- Go to the Releases page
- Click the three-dot menu (⋮) on any release
- Select Changelog Template
- Write your template
- Click Save
Template Examples
Grouped by Priority
# Release {{ release.version }}
{% assign high_priority = issues | where: "priority", 2 %}
{% assign medium_priority = issues | where: "priority", 3 %}
{% assign low_priority = issues | where: "priority", 4 %}
## 🔥 High Priority
{% for issue in high_priority %}
- **{{ issue.title }}** - {{ issue.identifier }}
{% endfor %}
## 📋 Medium Priority
{% for issue in medium_priority %}
- {{ issue.title }} - {{ issue.identifier }}
{% endfor %}
## 📌 Low Priority
{% for issue in low_priority %}
- {{ issue.title }} - {{ issue.identifier }}
{% endfor %}With Assignee Credits
# {{ release.version }}
{% for issue in issues %}
- {{ issue.title }} ([{{ issue.identifier }}]({{ issue.url }}))
{% if issue.assigneeName %}
_by @{{ issue.assigneeName }}_
{% endif %}
{% endfor %}
## Contributors
{% assign contributors = issues | map: "assigneeName" | uniq %}
{% for contributor in contributors %}
- @{{ contributor }}
{% endfor %}With Issue Descriptions & Lables
# {{ release.version }}
{{ release.description }}
---
{% for issue in issues %}
### {{ issue.identifier }}: {{ issue.title }}
{{ issue.description | truncate: 200 }}
**Labels:** {% for label in issue.labels %}{{ label }}{% unless forloop.last %}, {% endunless %}{% endfor %}
**Status:** {{ issue.state }}
**[View in Linear]({{ issue.url }})**
---
{% endfor %}Advanced Techniques
Conditional Logic
Show/hide sections based on content:
{% if issues.size > 0 %}
## Changes in this release:
{% for issue in issues %}
- {{ issue.title }}
{% endfor %}
{% else %}
_No changes in this release_
{% endif %}Filters
Format and transform data:
{# Capitalize #}
{{ release.title | capitalize }}
{# Uppercase #}
{{ release.version | upcase }}
{# Truncate long text #}
{{ issue.description | truncate: 100 }}
{# Date formatting #}
{{ release.date | date: "%B %d, %Y" }}
{# Count items #}
Total issues: {{ issues.size }}
{# Join arrays #}
Labels: {{ issue.labels | join: ", " }}
{# Default value #}
{{ issue.assigneeName | default: "Unassigned" }}Loops and Iteration
{# Basic loop #}
{% for issue in issues %}
{{ forloop.index }} of {{ forloop.length }}. {{ issue.title }}
{% endfor %}
{# Loop with conditions #}
{% for issue in issues %}
{% if forloop.first %}
## First issue:
{% endif %}
- {{ issue.title }}
{% if forloop.last %}
_End of issues_
{% endif %}
{% endfor %}Custom Variables
Define your own variables:
{% assign total_features = 0 %}
{% assign total_bugs = 0 %}
{% for issue in issues %}
{% if issue.labels contains "feature" %}
{% assign total_features = total_features | plus: 1 %}
{% endif %}
{% if issue.labels contains "bug" %}
{% assign total_bugs = total_bugs | plus: 1 %}
{% endif %}
{% endfor %}
# {{ release.version }}
This release includes **{{ total_features }} new features** and **{{ total_bugs }} bug fixes**.