Markdown Preview
Write Markdown on the left and see a live-rendered HTML preview on the right.

Utilities

Markdown Preview

Write Markdown and see a live-rendered HTML preview.

Markdown Preview gives you a split workspace: type Markdown into "Markdown Input" on the left (placeholder starts "# Hello World / Write your **markdown** here...") and watch "HTML Preview" re-render on the right after every change. The StepIndicator shows Write → Preview, but rendering is genuinely live — an effect parses with marked whenever the markdown changes and dispatches the HTML into Redux for the preview pane, which is styled with prose prose-sm dark:prose-invert so it looks at home in either theme.

GitHub-flavored Markdown is on: tables, strikethrough, and hard line breaks (gfm: true, breaks: true) all render as you would expect on GitHub. The copy icon (title "Copy HTML") grabs the rendered HTML string — not the Markdown source — with the toast "HTML copied to clipboard!", and the full-width Clear button resets both panes ("Cleared!"). Parse failures degrade to <p>Error parsing markdown</p> instead of crashing. Everything runs in-browser via marked; nothing is uploaded.

How it works

lib/markdownPreview.ts configures marked with { breaks: true, gfm: true } and exports parseMarkdown as marked.parse(text), catching any throw and returning the placeholder "<p>Error parsing markdown</p>". The page effect calls parseMarkdown on every markdown change and dispatches htmlSet, so the preview pane — a dangerouslySetInnerHTML injection inside the prose container — stays in sync without a submit button.

The markdownPreviewSlice holds markdown and html; Clear dispatches clearAll with the "Cleared!" toast. Because marked runs entirely in the browser there is no network round-trip, but the preview is a real DOM injection: only render Markdown you trust (or strip dangerous fragments first) if the content came from someone else. Dark mode works through the dark:prose-invert utility, not a separate renderer.

How to use

  1. On Step "Write", type Markdown into "Markdown Input" (placeholder "# Hello World\n\nWrite your **markdown** here...").
  2. Watch "HTML Preview" update live on every change (effect + marked.parse).
  3. Confirm GFM features — tables, strikethrough, and hard line breaks — render thanks to gfm: true, breaks: true.
  4. Click the copy icon (title "Copy HTML") to copy the rendered HTML string (toast "HTML copied to clipboard!").
  5. Toggle dark mode — the preview follows dark:prose-invert for readable styles.
  6. Click the full-width "Clear" button to reset both panes (toast "Cleared!").

Tips

  • The copy button copies the HTML string, not the Markdown source — grab the textarea yourself if you need the original .md text.
  • Parse errors surface as <p>Error parsing markdown</p> in the preview rather than crashing the page.
  • The preview is a real DOM injection (dangerouslySetInnerHTML) — render only Markdown you trust from external sources.
  • Hard breaks are enabled (breaks: true), so single newlines in the source become <br> like on Discord/Slack, not GitHub's paragraph rules.

Markdown Preview FAQ

Which Markdown engine is used?

marked, configured with GFM and breaks enabled in lib/markdownPreview.ts (parseMarkdown = marked.parse).

Does it support tables?

Yes — gfm: true turns on GitHub-flavored Markdown, including tables and strikethrough.

What gets copied by the copy button?

The rendered HTML string — navigator.clipboard.writeText(html) with the toast "HTML copied to clipboard!".

Is anything uploaded?

No — parsing happens in the browser with marked; both markdown and HTML stay local.

Credits

  • marked — Markdown → HTML parsing in lib/markdownPreview.ts
ShareTweet
More Utilities

Command Palette

Search for a command to run...