Plugins

Netdocs has a first-class C# plugin system. Plugins are enabled and configured in the plugins array of appsettings.json, and run in the order listed.

"plugins": [
  { "name": "search", "options": { "lang": "en" } },
  { "name": "tags", "options": { "export": true } },
  { "name": "blog", "options": { "blog_dir": "blog/" } }
]

Plugins are opt-in

Unlike the theme and Markdown extensions, no plugin runs unless you list it in the plugins array. There is no implicit default set — this keeps builds predictable and fast, and means a plugin can never surprise you by activating on its own. The trade-off is that a fresh appsettings.json starts minimal; use the recommended set below as a starting point.

Most sites want the majority of plugins enabled — they are inexpensive and only act on the content that uses them (for example table-reader is a no-op on pages with no read_csv directive). A good general-purpose starting point:

"plugins": [
  { "name": "search", "options": { "lang": "en" } },
  { "name": "meta" },
  { "name": "tags", "options": { "export": true } },
  { "name": "snippets" },
  { "name": "abbreviations" },
  { "name": "macros" },
  { "name": "table-reader" },
  { "name": "glightbox" },
  { "name": "git-revision-date", "options": { "enabled": true } },
  { "name": "redirects" },
  { "name": "rss" },
  { "name": "social" }
]

Add blog if you publish posts, file-filter for environment-driven content gating, and link-notes if you want to annotate outbound links (e.g. affiliate disclosures). A few plugins are intentionally left out of the "enable everything" default:

Plugin Why it's opt-in
blog Only meaningful for sites with a blog/ posts directory.
social Generates images (slower); best gated behind netdocs build --prod.
file-filter Needs a .file-filter.yml and env vars to do anything.
link-notes Requires you to declare your affiliate programs / link rules.
arithmatex / b64 Enable when you actually use math or inline-image embedding.

Ordering only matters for Markdown preprocessors (they transform source text in sequence); see each plugin page for its order. Plugins that emit assets or pages are order-independent.

Disabling a plugin per page

Every configured plugin runs on every page by default. To turn one off (or back on) for a single page, use its front matter. Two forms are supported — the map form wins, so it can re-enable a plugin that a list disabled:

---
title: Raw template snippet
plugins:
  macros: false        # don't run the macros preprocessor on this page
disable_plugins:
  - table-reader       # list form: turn these off
---

This is handy for pages that contain literal {{ … }} (which the macros plugin would otherwise try to expand), or to skip table-reader/snippets on a page that shouldn't be transformed. Only per-page hooks are gated: Markdown preprocessors and per-page build hooks (e.g. search indexing). Global contributions — Markdig extensions and content generators — are not page-scoped and always apply.

Built-in plugins

Plugin Purpose
search Material-compatible search_index.json (page + per-section docs).
social 1200×630 Open Graph social cards.
blog Posts, paginated index, categories, archive, post metadata.
tags Hierarchical tag index, shadow tags, tags.json export.
meta Per-directory .meta.yml front-matter defaults.
snippets --8<-- file includes.
abbreviations Shared <abbr> definition files.
git-revision-date Real created/updated dates from git.
redirects Client-side redirect map.
glightbox Image lightbox.
rss RSS feed of blog posts.
file-filter Env-driven label include/exclude.
macros fileuri() / button() Markdown macros (mkdocs-macros subset).
table-reader Expand read_csv() / read_table() into Markdown tables.
link-notes Auto tooltip + footer disclosure for affiliate links.
b64 Embed local images as inline data: URIs (pymdownx.b64).
arithmatex LaTeX math typeset with MathJax (pymdownx.arithmatex).
typeset Smart typography (curly quotes, en/em dashes, ellipses) via SmartyPants.

How plugins hook into the build

A plugin implements IPlugin (with Configure) plus any of the opt-in hook interfaces (IMarkdownPreprocessor, IMarkdigContributor, IContentGenerator, IBuildHook, INavigationFilter, …). Rather than duplicate that here, see:

  • Build lifecycle — a visual diagram of where each hook runs in the pipeline, so you know which interface to implement for a given job.
  • Events & callbacks — the full reference for every hook interface, its method signatures, ordering, and when it fires.
  • External plugins — how to ship a plugin as a separate DLL and load it via config.

See the source under src/Netdocs.Plugins/ for reference implementations.