Overview
lpd-mdx-preview is a VS Code extension that renders .mdx and .md files in a side panel with governed Mintlify built-ins, Livepeer custom component renderers, and Mermaid diagrams. It is the primary local authoring preview tool for this repo, but runtime-dependent surfaces still need verification in a Mintlify dev session.
Keybinding: Cmd+Shift+V (Mac) / Ctrl+Shift+V (Windows/Linux)
Location: tools/editor-extensions/lpd-mdx-preview/
Repo Context
Installation
Works in VS Code, Cursor, and Windsurf (all VS Code forks). The same.vsix file installs in all three.
All editors at once (recommended):
~/.vscode, ~/.cursor, ~/.windsurf) and deploys to each.
The installer verifies that the checked-in .vsix matches source before installing. If the package is stale, the install fails and prints the exact rebuild command.
Manual install:
Extensions sidebar → ... menu → Install from VSIX → select tools/editor-extensions/lpd-mdx-preview/lpd-mdx-preview-0.0.2.vsix.
Rebuild after source changes:
install.sh or reinstall manually.
Usage
Open preview
Open preview
.mdx or .md file, then press Cmd+Shift+V (Mac) or Ctrl+Shift+V (Windows/Linux).The preview opens in a side panel and updates automatically as you type (300ms debounce).Theme
Theme
auto mode). You can override this in settings:auto | light | darkFrontmatter display
Frontmatter display
title, pageType, audience, status, purpose, and lastVerified.Mermaid diagrams
Mermaid diagrams
mermaid are rendered using the bundled Mermaid.js with Livepeer theme colours. Diagrams update live as you edit.Component Rendering Tiers
.jsx files) fall into Tier 3 — they render as labelled placeholders with their children content visible. Most Mintlify built-ins and the Livepeer component library render as styled HTML, but runtime-heavy built-ins such as OpenAPI remain approximate.Component Reference
Tier 1 — Mintlify Built-ins
Note / Tip / Warning / Info
Note / Tip / Warning / Info
Callout
Callout
Card
Card
CardGroup
CardGroup
<Card> components.Tabs / Tab
Tabs / Tab
Accordion / AccordionGroup
Accordion / AccordionGroup
<details>/<summary> in the preview.Steps / Step
Steps / Step
Frame
Frame
Columns
Columns
Expandable
Expandable
CodeBlock
CodeBlock
<pre><code> in the preview without syntax highlighting.Icon
Icon
Update
Update
ResponseField
ResponseField
ParamField
ParamField
Danger
Danger
Badge
Badge
CodeGroup
CodeGroup
Tree / Tree.Folder / Tree.File
Tree / Tree.Folder / Tree.File
OpenAPI
OpenAPI
StyledTable / TableRow / TableCell
StyledTable / TableRow / TableCell
Tier 2 — Livepeer Custom Components
Spacing
CustomDivider
CustomDivider
snippets/components/elements/spacing/Divider.jsxSpacer
Spacer
Divider
Divider
<hr> divider. No props.Containers
CenteredContainer
CenteredContainer
snippets/components/wrappers/containers/Containers.jsxBorderedBox
BorderedBox
FullWidthContainer
FullWidthContainer
FlexContainer
FlexContainer
GridContainer
GridContainer
ScrollBox
ScrollBox
Diagrams
ScrollableDiagram
ScrollableDiagram
snippets/components/displays/diagrams/ScrollableDiagram.jsxLinks
LinkArrow
LinkArrow
→ suffix.Location: snippets/components/elements/links/Links.jsxGotoLink
GotoLink
GotoCard
GotoCard
Text & Headings
Subtitle
Subtitle
Quote / FrameQuote
Quote / FrameQuote
FrameQuote adds an outer border frame. No props.H1 / H2 / H3 / H4 / H5 / H6
H1 / H2 / H3 / H4 / H5 / H6
P
P
CopyText
CopyText
CardTitleTextWithArrow / AccordionTitleWithArrow
CardTitleTextWithArrow / AccordionTitleWithArrow
→ suffix. No props — content as children.PageHeader
PageHeader
Cards
DisplayCard
DisplayCard
WidthCard
WidthCard
InlineImageCard
InlineImageCard
InteractiveCard
InteractiveCard
CardCarousel
CardCarousel
Callout Banners
CustomCallout
CustomCallout
TipWithArrow
TipWithArrow
💡 icon. No props — content as children.ComingSoonCallout / PreviewCallout / ReviewCallout
ComingSoonCallout / PreviewCallout / ReviewCallout
Media
Image
Image
LinkImage
LinkImage
YouTubeVideo
YouTubeVideo
TitledVideo
TitledVideo
Steps
StyledSteps / StyledStep
StyledSteps / StyledStep
ListSteps
ListSteps
StyledSteps. Same rendering, same props.Grids & Layouts
QuadGrid
QuadGrid
AccordionLayout / AccordionGroupList
AccordionLayout / AccordionGroupList
Tables
DynamicTable
DynamicTable
SearchTable
SearchTable
useState). Renders as a static mock in the preview: non-functional search bar + category dropdown chrome + full table body. An ⚡ interactive — static in preview badge is shown to set expectations.Hero & Portal Scaffolding
HeroSectionContainer / HeroContentContainer / PortalHeroContent / PortalContentContainer
HeroSectionContainer / HeroContentContainer / PortalHeroContent / PortalContentContainer
Icons & Indicators
LivepeerIcon
LivepeerIcon
BlinkingIcon
BlinkingIcon
Embeds & Social
MarkdownEmbed
MarkdownEmbed
ExternalContent
ExternalContent
Math
MathInline / MathBlock
MathInline / MathBlock
<code> in preview (not LaTeX-rendered).Tier 3 — Placeholder Rendering
Any component not in Tier 1 or Tier 2 renders as:lib/component-map.js under the livepeerComponents object.
Interactive components
Some Tier 2 components use React hooks (useState, useEffect) and are fully interactive in deployed Mintlify but cannot run in the VS Code webview (Node.js environment, no React runtime). These render as static mocks — they show the correct UI chrome but do not respond to input.
Currently affected: SearchTable, SocialLinks, MarkdownEmbed, and OpenAPI.
These components display an ⚡ interactive — static in preview badge so authors know to verify their behaviour in a Mintlify dev session, not just the local preview.
Data-feed integrators (ShowcaseCards, CoinGeckoExchanges, LumaEvents, DiscordAnnouncements, TwitterTimeline) fall to Tier 3 placeholders for the same reason — they fetch live data and cannot be meaningfully mocked offline.
Configuration
Architecture
extension.js — Entry point
extension.js — Entry point
livepeer.openMdxPreview, livepeer.openMdxPreviewToSide), the Cmd+Shift+V keybinding, and two event listeners (document change → debounced re-render; theme change → full re-render). Manages a Map of open panels keyed by document URI.lib/mdx-parser.js — Segment parser
lib/mdx-parser.js — Segment parser
frontmatter, import, markdown, mermaid, codeblock, jsx, jsx-expression. Regex-based extraction — not a full MDX compiler, for robustness with non-standard MDX.lib/mintlify-components.js — Tier 1 renderers
lib/mintlify-components.js — Tier 1 renderers
Tree.Folder / Tree.File rendering and descriptive placeholders where full runtime parity is not practical in the preview. Each function signature: (props, childrenHtml) => htmlString.lib/component-map.js — Tier 2 renderers + dispatch
lib/component-map.js — Tier 2 renderers + dispatch
COMPONENT_MAP. Exports renderSegments() which dispatches each segment to its renderer or falls through to renderPlaceholder().lib/webview-template.js — HTML shell
lib/webview-template.js — HTML shell
fa 6.5.1), local CSS/JS vscode-resource: URIs, and the rendered body.media/preview.js — Client-side logic
media/preview.js — Client-side logic
.lpd-md-raw blocks with markdown-it, and handles tab switching interactions.media/preview.css — Theme & component styles
media/preview.css — Theme & component styles
style.css. Styles for all Tier 1 and Tier 2 component classes.Future Features
Lazy-load Mermaid.js ✓ Implemented
Lazy-load Mermaid.js ✓ Implemented
renderSegments() returns { html, hasMermaid }. The webview template conditionally injects <script src="${mermaidUri}"> only when hasMermaid is true. Pages without Mermaid diagrams skip the 2.45 MB bundle entirely.Promote Tier 3 components on demand
Promote Tier 3 components on demand
lib/component-map.js under livepeerComponents. The function signature is (props, childrenHtml) => htmlString.Priority candidates based on usage frequency in the repo:Snippet(used in composable page patterns)- data-feed integrators that could be represented by stable static mocks
- additional low-use repo components that currently fall through to generic placeholders
Syntax highlighting for code blocks
Syntax highlighting for code blocks
<pre><code> without syntax colouring. Adding highlight.js (vendored, ~50 KB minified) as a third media asset and calling hljs.highlightAll() in preview.js would add language-aware colouring for all fenced blocks.Live scroll sync
Live scroll sync
editor/scroll messages via the webview messaging API. The same pattern can be applied here: on onDidChangeTextEditorVisibleRanges, post a message to the webview to scroll to the corresponding rendered element.Custom component hot-reload ✓ Implemented
Custom component hot-reload ✓ Implemented
onDidSaveTextDocument watches for any .jsx save in the workspace and re-renders all open preview panels. Component source changes are reflected immediately without touching the .mdx file.Collapsible JSX comment blocks ✓ Implemented (v0.0.2)
Collapsible JSX comment blocks ✓ Implemented (v0.0.2)
{/* ... */} comment blocks — typically template instructions or reviewer flags — are rendered as collapsed <details> elements instead of leaking into the preview as visible text. Single-line {/* ... */} comments are still silently stripped. The collapsible uses a dashed border and muted palette to distinguish it from content.Parser: lib/mdx-parser.js detects {/* without a same-line */} and collects lines until the closing */}, emitting a jsx-comment segment.Renderer: lib/component-map.js handles jsx-comment as <details class="lpd-comment"> with a 💬 comment summary and pre-formatted body.