docusaurus-plugin-version-diff-sign adds version diff signs to Docusaurus docs content by comparing the current docs version against the immediately previous docs version.
It computes diff metadata at build time and uses that metadata at runtime to decorate:
- page headings
- sidebar doc links
- table of contents entries
Minimal setup:
import type { Config } from '@docusaurus/types';
const config: Config = {
plugins: ['docusaurus-plugin-version-diff-sign'],
};
export default config;With the default renderer:
- page headings render text pills
- sidebar items render dots
- TOC entries render dots
This repository includes a minimal Docusaurus site under
examples/minimal-site so you can verify sign rendering before publishing a
change.
Install the development dependencies once:
pnpm installThen start the local site:
pnpm run dev:siteUseful routes:
/docs/guide/start: automatic heading and TOC diffs/docs/guide/override: frontmatter overrides/docs/guide/new-page: a page that exists only in the latest version
For CI-style verification, you can also build the site:
pnpm run build:siteThe development site loads the compiled plugin from lib, so rebuild the
package after plugin changes before refreshing or restarting the site:
pnpm run build:packageExample with options: This disables TOC signs and changes the built-in sign colors for headings and sidebar items.
import type { Config } from '@docusaurus/types';
const config: Config = {
plugins: [
[
'docusaurus-plugin-version-diff-sign',
{
targets: {
toc: false,
},
sign: {
heading: {
color: '#0f766e',
},
sidebar: {
color: '#f59e0b',
},
},
},
],
],
};
export default config;The plugin options are:
{
targets?: {
sidebar?: boolean;
toc?: boolean;
headings?: boolean;
};
headingLevels?: number[];
ignoreWhitespace?: boolean;
sign?: {
heading?: {
type?: 'dot' | 'pill';
color?: string;
componentPath?: string;
};
sidebar?: {
type?: 'dot' | 'pill';
color?: string;
componentPath?: string;
};
toc?: {
type?: 'dot' | 'pill';
color?: string;
componentPath?: string;
};
};
paths?: {
routeBasePath?: string;
cacheFile?: string;
};
}Options:
targets: turns rendering on or off for headings, sidebar items, and TOC items independently. Defaults toheadings: true,sidebar: true, andtoc: true.headingLevels: controls which heading levels are tracked for both heading pills and TOC dots. Defaults to[1, 2, 3].ignoreWhitespace: ignores whitespace-only content changes whentrue. Defaults totrue.sign: configures per-target sign customization. Usetypeto choose the built-in shape,colorto tweak it, orcomponentPathto replace it completely. Defaults areheading.type: 'pill',sidebar.type: 'dot', andtoc.type: 'dot'.paths: advanced overrides for route base path and cache location. Defaults torouteBasePath: 'docs'andcacheFile: '.docusaurus/docusaurus-plugin-version-diff-sign.cache.json'.
Choose the lightest customization that fits your use case:
- Use
sign.<target>.colorwhen you only want to change the built-in sign color. - Use CSS overrides when you want to keep the built-in sign but adjust its size, spacing, typography, or shape.
- Use
sign.<target>.componentPathwhen you want to replace the built-in sign completely.
If you only want to adjust the built-in sign color, configure sign.<target>.color:
import type { Config } from '@docusaurus/types';
const config: Config = {
plugins: [
[
'docusaurus-plugin-version-diff-sign',
{
targets: {
toc: false,
},
sign: {
heading: {
color: '#0f766e',
},
sidebar: {
color: '#f59e0b',
},
},
},
],
],
};
export default config;This keeps the built-in pill and dot renderers, but changes their colors for the configured targets.
You can also switch the built-in sign shape per target:
sign: {
toc: {
type: 'pill',
},
}The default renderer attaches stable target and state classes so you can restyle signs without changing the diff logic.
.version-diff-sign.in-heading.is-new {
background: #0f766e;
color: white;
}
.version-diff-sign.in-sidebar.is-updated,
.version-diff-sign.in-toc.is-updated {
background: #f59e0b;
}To replace the built-in sign renderer for a specific target, point sign.<target>.componentPath at a component in your site:
import type { Config } from '@docusaurus/types';
const config: Config = {
plugins: [
[
'docusaurus-plugin-version-diff-sign',
{
sign: {
heading: {
color: '#0f766e',
componentPath: './src/components/HeadingVersionDiffBadge.tsx',
},
},
},
],
],
};
export default config;Example custom renderer:
import type { VersionDiffRendererProps } from 'docusaurus-plugin-version-diff-sign';
export default function VersionDiffBadge({
state,
target,
type,
color,
className,
}: VersionDiffRendererProps) {
return (
<span
className={[
className,
'my-sign',
`my-sign--${target}`,
`my-sign--${type}`,
`my-sign--${state}`,
]
.filter(Boolean)
.join(' ')}
style={{
color,
fontSize: type === 'pill' ? '0.75rem' : '0.625rem',
fontWeight: 700,
marginInlineStart: '0.5rem',
}}
>
{state === 'new' ? 'NEW' : 'UPDATED'}
</span>
);
}The renderer receives:
state:'new' | 'updated'target:'heading' | 'sidebar' | 'toc'type:'pill' | 'dot'color: the configured target color when provideddocId: current documentunversionedIdwhen availableheadingId: current headingidfor heading and TOC targets when availableheadingLevel: heading level for heading and TOC targets when availableclassName: the plugin-provided class name for the rendered element
You can override automatic diff states in a document frontmatter block:
---
versionDiff:
headingLevels: [2]
page: updated
headings:
request-connection-interval-change: none
write-operations: updated
---versionDiff.headingLevels accepts an array of heading levels from 1 to 6 and overrides the plugin-level setting for that page.
versionDiff.page and each versionDiff.headings.<headingId> support these values:
autononenewupdated
versionDiff.page overrides both the page state and the title state. versionDiff.headings overrides individual heading states by heading id.
See docs/SPEC.md for the behavior contract and docs/ARCHITECTURE.md for implementation details.
- Cache behavior is not finalized yet and may change in a future update.
- Only the current docs version and the immediately previous version are compared.
- Arbitrary version-pair comparison is not supported.
- Sidebar structure diffing is not supported as a first-class feature.