The default changelog renderer for nx release generates a changelog entry for each released project similar to the following:
## 7.9.0 (2024-05-13)
### 🚀 Features
- **rule-tester:** check for missing placeholder data in the message ([#9039](https://github.com/typescript-eslint/typescript-eslint/pull/9039))
### ❤️ Thank You
- Kirk Waiblinger- Sheetal Nandi- Vinccool96Include all metadata
Section titled “Include all metadata”There are a few options available to modify the default changelog renderer output. They can be applied to both workspaceChangelog and projectChangelogs in exactly the same way. All four options are true by default:
{ "release": { "changelog": { "projectChangelogs": { "renderOptions": { "authors": true, "applyUsernameToAuthors": true, "commitReferences": true, "versionTitleDate": true } } } }}authors
Section titled “authors”Whether the commit authors should be added to the bottom of the changelog in a "Thank You" section. Defaults to true.
applyUsernameToAuthors
Section titled “applyUsernameToAuthors”If authors is enabled, controls whether or not to try to map the authors to their GitHub usernames using https://ungh.cc (from https://github.com/unjs/ungh) and the email addresses found in the commits. Defaults to true.
You should disable this option if you don't want to make any external requests to https://ungh.cc
NOTE: Prior to Nx v21, this option was named mapAuthorsToGitHubUsernames.
commitReferences
Section titled “commitReferences”Whether the commit references (such as commit and/or PR links) should be included in the changelog. Defaults to true.
versionTitleDate
Section titled “versionTitleDate”Whether to include the date in the version title. It can be set to false to disable it, or true to enable with the default of (YYYY-MM-DD). Defaults to true.
Remove all metadata
Section titled “Remove all metadata”If you prefer a more minimalist changelog, you can set all the options to false, like this:
{ "release": { "changelog": { "projectChangelogs": { "renderOptions": { "authors": false, "applyUsernameToAuthors": false, "commitReferences": false, "versionTitleDate": false } } } }}Which will generate a changelog that looks similar to the following:
## 7.9.0
### 🚀 Features
- **rule-tester:** check for missing placeholder data in the messageCustom changelog renderer Nx 22+
Section titled “Custom changelog renderer Nx 22+”For complete control over changelog formatting, provide a workspace path or package specifier for a JavaScript or TypeScript module that exports a class extending DefaultChangelogRenderer. Use module.exports from a CommonJS module or a default export from an ECMAScript module (ESM).
The examples use CommonJS JavaScript because it works without additional TypeScript tooling or ESM configuration. You can use ESM or TypeScript instead when your workspace is configured to load it. For workspace files, start the path with {workspaceRoot} because plain relative paths such as ./tools/custom-changelog-renderer.js don't resolve from the workspace root.
{ "release": { "changelog": { "projectChangelogs": { "renderer": "{workspaceRoot}/tools/custom-changelog-renderer.js", }, }, },}Override render() when you want to replace or wrap the complete changelog output. For a targeted change, override one of the protected rendering or formatting methods instead. The inherited render() method continues to assemble every section you don't customize. Common extension points include renderVersionTitle(), renderChangesByType(), renderBreakingChanges(), renderDependencyBumps(), renderAuthors(), and helpers such as formatChange().
Customize one rendering stage
Section titled “Customize one rendering stage”Override a protected method to change one part of the changelog while keeping the rest of the default output:
const DefaultChangelogRenderer = require('nx/release/changelog-renderer').default;
module.exports = class CustomRenderer extends DefaultChangelogRenderer { renderVersionTitle() { return `# Release ${this.changelogEntryVersion}`; }};Replace the complete output
Section titled “Replace the complete output”Override render() without calling super.render() when you want to generate the complete entry:
const DefaultChangelogRenderer = require('nx/release/changelog-renderer').default;
module.exports = class CustomRenderer extends DefaultChangelogRenderer { async render() { return `# ${this.changelogEntryVersion}\n\nGenerated by our release workflow`; }};Adjust the complete output
Section titled “Adjust the complete output”Suppose your release process publishes extended notes to a separate internal site. This hypothetical renderer calls super.render() to keep the default changelog, then appends a link:
const DefaultChangelogRenderer = require('nx/release/changelog-renderer').default;
module.exports = class CustomRenderer extends DefaultChangelogRenderer { async render() { const changelog = await super.render(); if (!changelog) return changelog;
const releaseUrl = `https://releases.example.com/releases/v${this.changelogEntryVersion}`;
return `${changelog}\n\nSee the [extended release notes](${releaseUrl}).`; }};The release URL uses the default v{version} tag pattern for fixed releases. Adjust it when you use independent releases or a custom release tag pattern.
Some extension points run only when their corresponding gate returns true. For example, Nx calls renderBreakingChanges(), renderDependencyBumps(), and renderAuthors() only when hasBreakingChanges(), hasDependencyBumps(), or shouldRenderAuthors() returns true.
The typescript-eslint custom changelog renderer is a real-world JavaScript example that follows this pattern.