rehype-auto-internal-links
v0.1.0
Published
Rehype plugin that auto-converts keywords to internal links — ideal for content sites, wikis, and documentation
Downloads
85
Maintainers
Readme
rehype-auto-internal-links
A rehype plugin that automatically converts occurrences of registered keywords into internal anchor links across your content pages.
Ideal for content-heavy sites: encyclopedias, wikis, documentation, blogs — anywhere you want terms to link to their definition pages without writing <a> tags by hand.
How it works
At build time you provide a keyword map — an object mapping lowercase keywords to their URLs:
{
"burn rate": { href: "/glossary/burn-rate" },
"product-market fit": { href: "/glossary/pmf" },
"runway": { href: "/glossary/runway" },
}The plugin walks the HTML AST of each page and replaces matching text nodes with <a> elements. It follows a set of sensible rules so the result is clean and non-intrusive.
Rules
- Each keyword is linked at most once per page
- Total links added per page is capped at
maxLinksPerPage(default:3) - Never links inside
<a>,<code>,<pre>,<h1>–<h6>,<script>,<style>,<button> - Never self-links (a page never links to itself)
- Longer keywords match before shorter substrings (e.g.
"product-market fit"wins over"product") - Case-insensitive match; anchor text preserves the original casing from the source
Install
npm install rehype-auto-internal-linksPeer dependency — make sure unist-util-visit is available (it ships with Astro and most unified setups):
npm install unist-util-visitUsage
Option A — Manual keyword map
Provide your own map. Works with any framework that supports rehype plugins.
import { rehypeAutoInternalLinks } from 'rehype-auto-internal-links';
const keywordMap = {
'burn rate': { href: '/glossary/burn-rate' },
'runway': { href: '/glossary/runway' },
'arr': { href: '/glossary/arr' },
};
// In a unified pipeline:
unified()
.use(rehypeParse)
.use(rehypeAutoInternalLinks, { keywordMap, maxLinksPerPage: 3 })
.use(rehypeStringify)
.process(html);Option B — Astro with auto-generated map
Use the included buildKeywordMap helper to automatically scan your Markdown/MDX content files at build time. It reads the primaryKeyword frontmatter field from each file.
// astro.config.mjs
import { defineConfig } from 'astro/config';
import { rehypeAutoInternalLinks } from 'rehype-auto-internal-links';
import { buildKeywordMap } from 'rehype-auto-internal-links/build-keyword-map';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const keywordMap = buildKeywordMap({
contentRoot: resolve(__dirname, 'src/content'),
// sections defaults to ['glossary', 'guides', 'concepts', 'articles']
// locale defaults to 'en'
});
export default defineConfig({
markdown: {
rehypePlugins: [
[rehypeAutoInternalLinks, { keywordMap, maxLinksPerPage: 2 }],
],
},
});Then in your content frontmatter:
---
title: "Burn Rate"
primaryKeyword: "burn rate"
---The helper will register "burn rate" → /glossary/burn-rate automatically.
API
rehypeAutoInternalLinks(options)
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| keywordMap | Record<string, { href: string }> | {} | Map of keywords to their target URLs |
| maxLinksPerPage | number | 3 | Maximum number of links to inject per page |
buildKeywordMap(options) (Astro / filesystem helper)
Import from rehype-auto-internal-links/build-keyword-map.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| contentRoot | string | — | Required. Absolute path to the content root directory |
| sections | string[] | ['glossary', 'guides', 'concepts', 'articles'] | Subdirectory names to scan |
| locale | string | 'en' | Locale subfolder inside each section. Pass '' to disable. |
License
MIT
