A comprehensive Docusaurus plugin that provides glossary functionality with an auto-generated glossary page, searchable terms, and inline term tooltips.
Compatibility: Fully compatible with Docusaurus v3 (MDX v3). If you were on a v2-era fork, please upgrade to the latest 2.x release of this plugin.
- Auto-generated Glossary Page: Displays all terms alphabetically with letter navigation
- Search Functionality: Real-time search across terms, definitions, abbreviations, and aliases
- GlossaryTerm Component: Inline component for linking terms with tooltip previews
- Automatic Term Detection: Automatically detect and link glossary terms in markdown files with tooltips
- Responsive Design: Mobile-friendly UI with dark mode support
- Related Terms: Link between related glossary terms
- Abbreviation Support: Display full form of abbreviated terms
- Customizable: Configure glossary path and route
-
Install the plugin:
npm install docusaurus-plugin-glossary
-
Use the preset in your
docusaurus.config.js:module.exports = { presets: [ [ 'docusaurus-plugin-glossary/preset', { // Glossary configuration glossary: { glossaryPath: 'glossary/glossary.json', routePath: '/glossary', }, // Standard Docusaurus preset-classic options docs: { sidebarPath: './sidebars.js', }, blog: { showReadingTime: true, }, theme: { customCss: './src/css/custom.css', }, }, ], ], };
That's it! The preset automatically configures the glossary plugin and remark plugin for you.
-
Create your glossary file at
glossary/glossary.json:{ "title": "Glossary", "description": "A collection of technical terms and their definitions", "terms": [ { "term": "API", "abbreviation": "Application Programming Interface", "definition": "A set of rules and protocols that allows different software applications to communicate with each other.", "relatedTerms": ["REST", "GraphQL"] }, { "term": "REST", "abbreviation": "Representational State Transfer", "definition": "An architectural style for designing networked applications.", "relatedTerms": ["API", "HTTP"] } ] } -
Start your dev server:
npm run start
-
That's it!
- Visit
/glossaryto see your glossary page - Write markdown normally - terms will automatically be linked with tooltips
- Use
<GlossaryTerm>component in MDX for manual control
- Visit
npm install docusaurus-plugin-glossaryCreate a JSON file at glossary/glossary.json (or your configured path) in your Docusaurus site root:
{
"title": "Glossary",
"description": "A collection of technical terms and their definitions",
"terms": [
{
"term": "API",
"abbreviation": "Application Programming Interface",
"definition": "A set of rules and protocols that allows different software applications to communicate with each other.",
"documentation": {
"path": "/docs/api",
"label": "Read the API guide"
},
"references": [
{
"label": "OpenAPI specification",
"url": "https://spec.openapis.org/oas/latest.html"
}
],
"relatedTerms": ["REST", "GraphQL"]
},
{
"term": "REST",
"abbreviation": "Representational State Transfer",
"definition": "An architectural style for designing networked applications.",
"relatedTerms": ["API", "HTTP"]
}
]
}Required fields:
term(string): The glossary term namedefinition(string): The term's definition
Optional fields:
-
category(string): A non-empty category label, displayed as a badge beside the term and included in glossary search -
abbreviation(string): The full form if the term is an abbreviation -
relatedTerms(string[]): Array of related term names that link to other glossary entries -
id(string): Custom ID for linking (auto-generated from term name if not provided) -
autoLink(boolean): Set tofalseto opt a term out of automatic linking (default:true) -
aliases(string[]): Additional phrases that should also auto-link to this term. Useful for inflections (e.g.["cleaning", "cleaned"]forclean) or alternate forms. The rendered link and tooltip always use the canonicalterm -
caseSensitive(boolean): Set totrueto match only the exact case oftermand itsaliases(default:false). Useful for acronyms that share spelling with common words (e.g.RESTshould not matchrest) -
documentation(object): The canonical page for the term on your Docusaurus site.pathmust be a site-relative route beginning with/;labeloptionally customizes the glossary page link (default:Read more). Auto-linked occurrences navigate to this page instead of the glossary entry -
references(object[]): External supporting sources. Each reference requires alabeland an absolute HTTP(S)url. References appear on the glossary page and don't change the destination of auto-linked terms
The easiest way to configure the plugin is using the preset:
module.exports = {
presets: [
[
'docusaurus-plugin-glossary/preset',
{
glossary: {
glossaryPath: 'glossary/glossary.json',
routePath: '/glossary',
},
// All standard preset-classic options work here
docs: {
sidebarPath: './sidebars.js',
},
blog: {
showReadingTime: true,
},
theme: {
customCss: './src/css/custom.css',
},
},
],
],
};The preset automatically configures both the glossary plugin and the remark plugin for automatic term detection.
If you need more control or want to use the plugin alongside the classic preset separately:
const glossaryPlugin = require('docusaurus-plugin-glossary');
module.exports = {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
// Add the remark plugin to enable auto-linking in docs
remarkPlugins: [
glossaryPlugin.getRemarkPlugin(
{
glossaryPath: 'glossary/glossary.json',
routePath: '/glossary',
},
{ siteDir: __dirname }
),
],
},
pages: {
// Add the remark plugin to enable auto-linking in pages
remarkPlugins: [
glossaryPlugin.getRemarkPlugin(
{
glossaryPath: 'glossary/glossary.json',
routePath: '/glossary',
},
{ siteDir: __dirname }
),
],
},
},
],
],
plugins: [
[
'docusaurus-plugin-glossary',
{
glossaryPath: 'glossary/glossary.json',
routePath: '/glossary',
},
],
],
};Alternative: Using remarkPlugin directly
You can also use the remarkPlugin export directly if you prefer:
const glossaryPlugin = require('docusaurus-plugin-glossary');
module.exports = {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
remarkPlugins: [
[
glossaryPlugin.remarkPlugin,
{
glossaryPath: 'glossary/glossary.json',
routePath: '/glossary',
siteDir: __dirname,
},
],
],
},
},
],
],
plugins: [
[
'docusaurus-plugin-glossary',
{
glossaryPath: 'glossary/glossary.json',
routePath: '/glossary',
},
],
],
};This plugin uses a hybrid approach combining build-time transformation and runtime enhancements, inspired by docusaurus-plugin-image-zoom:
The remark plugin automatically detects glossary terms in your markdown and:
- Transforms plain text terms into
<GlossaryTerm>JSX components - Automatically injects the necessary import statement (
import GlossaryTerm from '@theme/GlossaryTerm';) - This happens during the MDX compilation, before React renders anything
No manual imports needed! When you write:
Our API uses REST principles.The remark plugin transforms it to:
import GlossaryTerm from '@theme/GlossaryTerm';
Our <GlossaryTerm term="API">API</GlossaryTerm> uses <GlossaryTerm term="REST">REST</GlossaryTerm> principles.The remark plugin finds glossary terms while Docusaurus compiles Markdown. It injects the theme component import only on pages that contain linked terms, so the plugin doesn't need a global client module.
The GlossaryTerm component is provided via the theme system (@theme/GlossaryTerm), making it:
- Available to all MDX files through automatic imports
- Swizzlable for custom styling and behavior
- Accessible to both the remark plugin and manual usage
-
MDX imports: The plugin automatically injects
import GlossaryTerm from '@theme/GlossaryTerm';when it auto-links a term. You can also use it manually in MDX:import GlossaryTerm from '@theme/GlossaryTerm'; Our <GlossaryTerm term="API" /> uses <GlossaryTerm term="REST">RESTful</GlossaryTerm> principles.
-
No tooltips or no auto-linking?
- Confirm you're on
@docusaurus/core@^3andreact@^18. - Ensure the plugin is listed in
pluginsAND the remark plugin is configured in your preset (see Step 2 above). - Visit
/glossary. If the page or route fails to render, verify yourglossaryPathfile exists and contains atermsarray. - Clear your Docusaurus cache with
npm run clearand restart your dev server. - If you previously used an older version (v1.0.x), upgrade to the latest version; the plugin bundles the v3-compatible theme and remark integration.
- Confirm you're on
-
Opting out of auto-linking: Simply don't configure the remark plugin in your preset. You can still use the
<GlossaryTerm />component manually where you want explicit control.
With the remark plugin configured, glossary terms are automatically detected and linked in all your markdown files. Simply write your content normally:
Our API uses REST principles to provide a simple interface.
This project supports webhooks for real-time notifications.Terms like "API", "REST", and "webhooks" will automatically be:
- Detected if they're defined in your glossary
- Styled with a dotted underline
- Display a tooltip with the definition on hover
- Link to the full glossary page entry
Limitations:
- Only whole words are matched (respects word boundaries)
- Terms inside code blocks, links, or existing MDX components are not processed
- Matching is case-insensitive
For more control or when automatic detection isn't sufficient, use the GlossaryTerm component in MDX files:
import GlossaryTerm from '@theme/GlossaryTerm';
This website uses an <GlossaryTerm term="API">API</GlossaryTerm> to fetch data.
// Or with explicit definition (overrides glossary entry):
We use <GlossaryTerm term="REST" definition="Representational State Transfer" /> for our services.
// Or with children content:
Our <GlossaryTerm term="API" definition="Application Programming Interface">RESTful API</GlossaryTerm> is available.Component props:
term(required): The term name (used to look up definition from glossary)definition(optional): Override the definition from the glossary filedocumentationPath(optional): Override the internal documentation destination from the glossary filechildren(optional): Custom text to display (defaults to term name)
The glossary page is automatically available at /glossary (or your configured routePath).
Features:
- Alphabetical grouping with letter navigation
- Real-time search across terms, definitions, abbreviations, and aliases
- Clickable related terms
- Responsive design
- Dark mode support
Add to navigation:
To add the glossary to your navbar, update your docusaurus.config.js:
module.exports = {
themeConfig: {
navbar: {
items: [
{ to: '/glossary', label: 'Glossary', position: 'left' },
// ... other items
],
},
},
};| Option | Type | Default | Description |
|---|---|---|---|
glossaryPath |
string | 'glossary/glossary.json' |
Path to glossary JSON file relative to site directory |
routePath |
string | '/glossary' |
URL path for glossary page |
generatePage |
boolean | true |
Register the standalone glossary page. Set to false when rendering the glossary in a doc. |
id |
string | default |
Docusaurus plugin instance ID for sites with multiple glossaries. |
expandAcronymsOnFirstUse |
boolean | false |
When true, expand the first canonical occurrence of any term that has an abbreviation to "Long Form (Term)" per file |
linkOnlyFirstOccurrence |
boolean | false |
Link each term only once per file. Aliases and plurals share the same first occurrence. Works with acronym expansion. |
When expandAcronymsOnFirstUse is enabled, the remark plugin rewrites the first canonical occurrence of any term that has an abbreviation so that the long form is introduced inline. For example, given a term { "term": "PSP", "abbreviation": "Payment Service Provider", ... }:
- Source:
The PSP charges a fee. Each PSP has its own pricing. - Rendered:
The Payment Service Provider (PSP) charges a fee. Each PSP has its own pricing.
Rules:
- Only the canonical
termtriggers expansion — aliases and plural forms (PSPs) do not. - Expansion only fires when the term has an
abbreviationfield. - If the author already wrote the long form immediately before the term (e.g. they typed
Payment Service Provider (PSP)themselves), expansion is skipped to avoid duplication. - Scope is per file — the first occurrence in each markdown/MDX file is expanded.
- Terms with
autoLink: falseare not expanded.
The plugin uses CSS modules for styling. You can override styles by:
- Creating custom CSS in your site's
src/css/custom.css:
/* Override glossary term styles */
.glossaryTermWrapper .glossaryTerm {
border-bottom-color: #your-color;
}
/* Override tooltip styles */
.glossaryTermWrapper .tooltip {
background: #your-background;
}- For advanced customization, you can swizzle the components:
npm run swizzle docusaurus-plugin-glossary GlossaryPage -- --wrap
npm run swizzle docusaurus-plugin-glossary GlossaryTerm -- --wrapTo add the glossary to your navbar, update your docusaurus.config.js:
themeConfig: {
navbar: {
items: [
{to: '/glossary', label: 'Glossary', position: 'left'},
// ... other items
],
},
}See the Usage Guide section above for complete examples. Here are additional examples:
{
"title": "Glossary",
"description": "Technical terms used in our documentation",
"terms": [
{
"term": "API",
"abbreviation": "Application Programming Interface",
"definition": "A set of rules and protocols that allows different software applications to communicate with each other.",
"relatedTerms": ["REST", "GraphQL", "Webhook"]
},
{
"term": "REST",
"abbreviation": "Representational State Transfer",
"definition": "An architectural style for designing networked applications.",
"relatedTerms": ["API", "HTTP"]
},
{
"term": "Webhook",
"definition": "An HTTP callback that occurs when something happens; a simple event-notification via HTTP POST.",
"relatedTerms": ["API", "HTTP"]
}
]
}---
title: API Documentation
---
# Getting Started with Our API
Our API uses RESTful principles to provide a simple and consistent interface.
Webhooks are supported for real-time event notifications.The terms "API", "RESTful", and "Webhooks" will automatically be detected and linked if they're defined in your glossary.
---
title: API Documentation
---
import GlossaryTerm from '@theme/GlossaryTerm';
# Getting Started with Our API
Our <GlossaryTerm term="API" />
uses <GlossaryTerm term="REST">RESTful</GlossaryTerm>
principles to provide a simple and consistent interface.This project is written in TypeScript and compiles to JavaScript. The source files are in src/ and the compiled output goes to dist/.
docusaurus-plugin-glossary/
├── src/
│ ├── index.ts # Main plugin entry point (TypeScript)
│ ├── components/
│ │ ├── GlossaryPage.tsx # Glossary page component
│ │ ├── GlossaryPage.module.css
│ │ └── GlossaryPage.test.js
│ ├── remark/
│ │ └── glossary-terms.ts # Remark plugin for automatic term detection
│ └── theme/
│ └── GlossaryTerm/
│ ├── index.tsx # Term component
│ ├── styles.module.css
│ └── index.test.js
├── dist/ # Compiled output (generated by build)
│ ├── index.js # Main plugin file (compiled from src/index.ts)
│ ├── components/ # Bundled glossary page
│ ├── remark/ # Bundled remark plugin
│ └── theme/ # Bundled theme component
├── __tests__/
│ └── plugin.test.js # Plugin lifecycle tests
├── examples/
│ └── docusaurus-v3/ # Example Docusaurus site
├── tsup.config.ts # Package build configuration
└── package.json
The source is TypeScript and TSX. To build:
npm run buildThis runs tsup to create ESM, CommonJS, and declaration outputs in dist/.
For development, use:
npm run watchThis watches for changes and automatically rebuilds.
The plugin follows Docusaurus plugin lifecycle hooks:
- loadContent: Reads and validates the configured glossary JSON file
- contentLoaded: Creates component data, adds the glossary route, and exposes plugin data
- getThemePath: Exposes the
GlossaryTermtheme component - getPathsToWatch: Watches the glossary file during development
The remark plugin (remark/glossary-terms.ts) automatically detects glossary terms in markdown files and transforms them at build time. It:
- Scans text nodes for glossary terms (case-insensitive, whole word matching)
- Replaces matching terms with
<GlossaryTerm>MDX components - Automatically injects the necessary import statement (
import GlossaryTerm from '@theme/GlossaryTerm';) - Skips terms inside code blocks, links, or existing MDX components
- Respects word boundaries to avoid partial matches
- Handles plural forms (e.g., "API" matches "APIs")
- Resolves overlapping terms deterministically: when one term's range contains another's, the longer (superset) term wins; when two matches overlap but neither contains the other, the earlier match wins
- Ensure the plugin is properly configured in
docusaurus.config.js - Check that the
routePathdoesn't conflict with existing routes - Run
npm run clearto clear Docusaurus cache
- Verify
glossary/glossary.jsonexists at the correct path - Check JSON syntax is valid
- Ensure
termsarray is properly formatted
- Make sure you're importing from
@theme/GlossaryTerm - Try clearing cache with
npm run clear - Restart dev server
- IMPORTANT: Ensure you have configured the remark plugin in your preset (see Configuration section above)
- Verify your glossary file exists at the configured
glossaryPathand contains terms - Check that terms in your content match the terms in your glossary (matching is case-insensitive but respects word boundaries)
- Try clearing cache with
npm run clearand restarting the dev server - Note that terms inside code blocks, links, or MDX components are not processed
- Make sure you've added the remark plugin to both
docsandpagessections if you want auto-linking in both - If you've manually configured the remark plugin, ensure
siteDirpoints to the correct Docusaurus site directory
- Check for CSS conflicts in your custom CSS
- Ensure CSS modules are loading correctly
- Try clearing cache and rebuilding
MIT
Contributions are welcome! Please see our Contributing Guide for details on how to get started.
See CHANGELOG.md for version history and release notes.
Built for Docusaurus v3.x
- Language: TypeScript and TSX
- Build system: tsup
- Package entry points:
dist/index.jsfor ESM anddist/index.cjsfor CommonJS - Exports: Main plugin, remark plugin via package.json exports field
Import Glossary from docusaurus-plugin-glossary/components/Glossary to render
search, alphabet navigation, and term cards inside your own page. Pass parsed
glossary data as glossaryData; set showTitle={false} when the surrounding doc
already has a title. Set the plugin's generatePage to false and routePath to
the doc URL to avoid duplicate routes.