or come out as live HTML. The fix is a separate second step: pipe the parsed output through DOMPurify.sanitize(marked.parse(input)) before it ever touches innerHTML."}},{"@type":"Question","name":"Should I sanitize the Markdown source or the generated HTML?","acceptedAnswer":{"@type":"Answer","text":"The HTML output, always. The dangerous payload only fully materializes after parsing — sanitizing the raw Markdown string misses it because syntax like [click](javascript:alert(1)) hasn't been turned into an href yet. The correct order is two ordered steps: marked.parse() first, then DOMPurify.sanitize() on that result. Reverse them and you've sanitized a layer where the attack isn't visible."}},{"@type":"Question","name":"I'm using marked — isn't there a built-in option to make its output safe?","acceptedAnswer":{"@type":"Answer","text":"Not anymore. marked removed its old sanitize and sanitizer options in v8.0.0, so the {sanitize:true} you'll see in older tutorials no longer does anything. Today's marked options include nothing that strips raw HTML or dangerous link schemes — a [x](javascript:alert(1)) link still emits a live javascript: href, and data:/vbscript: URIs pass too. marked's own docs say to run the output through DOMPurify. (This differs from markdown-it, which defaults to html:false and ships a built-in validateLink that blocks those schemes — but marked has neither, so DOMPurify is mandatory.)"}}]}

Markdown to HTML Converter

Paste Markdown, preview the rendered result, and copy sanitized HTML for docs, CMS publishing, or prototypes.

Runs in your browser No upload required Convert
Markdown is parsed and sanitized locally before preview and copy.

How to use Markdown to HTML

  1. Paste Markdown into the input box.
  2. Select Convert Markdown.
  3. Review the live HTML preview.
  4. Copy sanitized HTML when the output looks correct.

Why this tool exists

A Markdown to HTML converter is useful when content starts in a plain-text editor but needs to move into a CMS, blog template, documentation page, email draft, or prototype. Markdown is easy to write, while HTML is what browsers and many publishing systems ultimately render. CleanWebTools converts the text locally and shows both a preview and copyable HTML output.

The important detail is sanitization. Markdown can produce HTML, and raw HTML inside Markdown can include risky attributes or tags if inserted directly into a page. This tool uses a sanitizer before displaying or copying the rendered HTML, which helps remove script-oriented content and unsafe markup. Sanitization is not a license to trust unknown input blindly, but it is the right default for a browser preview tool.

This converter is meant for clean publishing snippets, not full-site builds. Static site generators, documentation frameworks, and CMS systems may apply their own Markdown plugins, heading IDs, syntax highlighters, and link transforms. Use this page to inspect the core structure and copy simple HTML. For production pipelines, keep the source Markdown under version control and let the publishing system handle final rendering.

Because conversion runs in your browser, drafts do not need to be uploaded. That is useful for unpublished posts, internal docs, customer support macros, and release notes. Avoid pasting confidential content into any third-party page unless the content is cleared for that context.

Common examples

  • Raw HTML passthrough: input `Hello <img src=x onerror=alert(1)>` produces output <p>Hello <img src=x onerror=alert(1)></p> — a live, firing img tag. Running that through DOMPurify yields <p>Hello <img src="x"></p> with the onerror attribute stripped.
  • GFM vs CommonMark divergence: a pipe table plus ~~strike~~ renders as a real <table> and <del>strike</del> only when GFM mode is on; in plain CommonMark mode the same input emerges as literal text with visible pipes and tildes.
  • URL-scheme XSS that marked won't catch: input [click me](javascript:alert(document.cookie)) becomes <a href="javascript:alert(document.cookie)">click me</a>; DOMPurify rewrites it to a harmless <a>click me</a> by dropping the disallowed scheme.

FAQ

Why does my converted HTML still run a <script> tag I put in the Markdown?

Because CommonMark deliberately lets raw inline and block HTML pass straight through to the output — that behavior is in the spec, not a bug. Parsers like marked, markdown-it, and commonmark.js treat sanitization as the caller's job, so <script>alert(1)</script> or <img src=x onerror=alert(1)> come out as live HTML. The fix is a separate second step: pipe the parsed output through DOMPurify.sanitize(marked.parse(input)) before it ever touches innerHTML.

Should I sanitize the Markdown source or the generated HTML?

The HTML output, always. The dangerous payload only fully materializes after parsing — sanitizing the raw Markdown string misses it because syntax like [click](javascript:alert(1)) hasn't been turned into an href yet. The correct order is two ordered steps: marked.parse() first, then DOMPurify.sanitize() on that result. Reverse them and you've sanitized a layer where the attack isn't visible.

I'm using marked — isn't there a built-in option to make its output safe?

Not anymore. marked removed its old sanitize and sanitizer options in v8.0.0, so the {sanitize:true} you'll see in older tutorials no longer does anything. Today's marked options include nothing that strips raw HTML or dangerous link schemes — a [x](javascript:alert(1)) link still emits a live javascript: href, and data:/vbscript: URIs pass too. marked's own docs say to run the output through DOMPurify. (This differs from markdown-it, which defaults to html:false and ships a built-in validateLink that blocks those schemes — but marked has neither, so DOMPurify is mandatory.)