Documentation.DocfxRemoteInclude.Cli 0.2.0

dotnet tool install --global Documentation.DocfxRemoteInclude.Cli --version 0.2.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Documentation.DocfxRemoteInclude.Cli --version 0.2.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Documentation.DocfxRemoteInclude.Cli&version=0.2.0
                    
nuke :add-package Documentation.DocfxRemoteInclude.Cli --version 0.2.0
                    

docfx-remote-include

A standalone Markdig extension and CLI tool for DocFX that inlines markdown content fetched from an authenticated HTTP service at build time.

This is not a fork of DocFX. It plugs into DocFX's public BuildOptions.ConfigureMarkdig seam, so it tracks upstream releases as a regular NuGet package.

Directive

In any markdown file processed by DocFX:

Some local content.

[!remoteinclude[Welcome](path/to/snippet.md)]

More local content.

Inline usage also works: today's status is [!remoteinclude[s](status/prod.md)].

At build time the extension performs GET {baseUrl}/{source}, parses the response as markdown, and inlines the result. Nested directives, cycle detection, and missing-source handling are all supported. The directive has two shapes that share the same syntax:

  • Block — the directive is the only thing on its line. The fetched markdown is inlined as block content (headings, lists, paragraphs allowed).
  • Inline — the directive appears mid-paragraph. The fetched markdown must reduce to a single paragraph; only its inline content is spliced in (no <p> wrapper).

Optional AI rewrite

Add a quoted hint after the source to ask an IRewriteService (e.g. Azure OpenAI in the CLI) to rewrite the fetched snippet to match the surrounding page voice:

[!remoteinclude[Install](snippets/install.md "match this page's tone and tense")]

Without a hint, the snippet is inlined verbatim.

Install

Two packages on NuGet:

NuGet Downloads NuGet Downloads

Package Purpose
Documentation.DocfxRemoteInclude Library — for hosts that call Docset.Build(...).
Documentation.DocfxRemoteInclude.Cli dotnet tool — drop-in wrapper around docfx build.

As a CLI

dotnet tool install -g Documentation.DocfxRemoteInclude.Cli

Configure via remoteinclude.json next to docfx.json:

{
  "baseUrl": "https://internal.example.com/",
  "allowMissing": false,
  "urlTemplate": "api/content/GetFile?path={source}",
  "auth": { "mode": "managedIdentity", "scope": "api://my-app-id/.default" },
  "ai": {
    "endpoint": "https://my-aoai.openai.azure.com/",
    "deployment": "gpt-4o-mini",
    "contextStrategy": "section",
    "auth": { "mode": "default" }
  }
}

Then build:

docfx-ri build docs/docfx.json

Both auth blocks accept { "mode": "none" | "default" | "managedIdentity" | "jwt" | "key", "value": "...", "scope": "..." }. value accepts $VAR / ${VAR} to indirect through environment variables. mode: "none" sends no auth header (valid for the content service only). scope overrides the OAuth audience when using default or managedIdentity mode — useful when the API's audience differs from its hostname (e.g. api://my-app-id/.default). Omit the ai section entirely to disable rewriting. Legacy env vars DOCFX_RI_BASE_URL and DOCFX_RI_TOKEN (bearer JWT) still work when no remoteinclude.json is present.

URL template

By default, the directive source (e.g. snippets/intro.md) is appended as a relative path to baseUrl. If your content service uses a query-parameter or non-trivial URL scheme, set urlTemplate with a {source} placeholder:

{
  "baseUrl": "https://api.example.com/",
  "urlTemplate": "content/GetFile?path={source}"
}

The {source} token is replaced with the URL-encoded source value from the directive.

As a library

dotnet add package Documentation.DocfxRemoteInclude
using Docfx;
using Docfx.RemoteInclude;

using var client = new HttpRemoteContentClient(
    baseUri: new Uri("https://internal.example.com/"),
    authHandler: async (request, ct) =>
    {
        request.Headers.Authorization = new("Bearer", await GetJwtAsync(ct));
    });

await Docset.Build("docs/docfx.json", new BuildOptions
{
    ConfigureMarkdig = pipeline => pipeline.UseRemoteInclude(client, new RemoteIncludeOptions
    {
        RewriteService = myRewriter, // optional IRewriteService
    }),
});

Provide your own IRemoteContentClient for non-HTTP sources, custom auth schemes (mTLS, signed URLs), or on-disk caching. Implement IRewriteService to plug in any LLM — the library itself has no Azure dependency.

Behavior

  • Hard fail by default when a source returns 404 or errors. Pass --allow-missing (CLI) or new RemoteIncludeOptions { AllowMissing = true } (library) to render a visible <div class="remote-include-error"> placeholder instead.
  • Cycle detection via an AsyncLocal source stack; max depth defaults to 8.
  • In-process cache in HttpRemoteContentClient: each source is fetched once per build.
  • Concurrency capped at 8 in-flight requests by default.

Security

  • Credentials are read from environment variables / a host-supplied callback. They are never read from docfx.json and never written to disk.
  • Remote markdown is parsed by the same pipeline that processes your own content. If your upstream service is untrusted, disable raw HTML in your DocFX pipeline.

Status

Alpha. Public API may change before 1.0. Issues and PRs welcome.

License

MIT.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.2.0 100 5/29/2026
0.1.0 46 5/28/2026