Convert Any Web Page URL to Markdown
Processing happens 100% in your browser — nothing is uploaded.
Only what an anonymous visitor can see
How to convert a web page URL to Markdown
- Input: paste the full URL, including the https:// scheme, into the field.
- Process: the page is fetched anonymously, Readability isolates the article in your browser, and Turndown renders GitHub-flavoured Markdown locally.
- Copy: send the Markdown to your clipboard or save it as a .md file.
Why Convert URL to Markdown with MD Convert?
Readability extraction, not a full-page dump
Candidate containers are scored on link density, paragraph ratio, and boilerplate class names, so navigation bars, cookie banners, ad slots, share rails, and comment threads lose to the article body. You get prose with its headings, lists, links, and code blocks intact.
Parsing is 100% local to your browser
The DOM is built by your own browser, Readability scores it in your tab, and Turndown renders the Markdown in your tab. No page content is processed, stored, or logged on any MD Convert server.
Stateless same-origin fetch, zero retention
Browsers block cross-origin reads from page JavaScript, so a same-origin Function requests the public page anonymously and streams the HTML straight back. It has no database, no cache, and no request log — there is nothing to retain and no session of yours attached.
Output shaped for LLM and RAG pipelines
Stripping boilerplate cuts token count sharply against raw HTML for the same prose, and the surviving heading hierarchy gives a chunker real semantic split points instead of arbitrary token windows.
URL to Markdown: Before and After
A typical article page. Everything outside the scored article subtree (the nav, the consent banner, the inline script) is discarded before Turndown ever sees the markup.
<body>
<nav class="site-nav"><a href="/">Home</a><a href="/blog/">Blog</a></nav>
<div id="cookie-consent">We value your privacy…<button>Accept</button></div>
<article>
<h1>Streaming Parsers in the Browser</h1>
<p>Parsing a large file in a tab used to mean
<a href="/blog/workers/">freezing the main thread</a>.</p>
<h2>Why workers matter</h2>
<ul><li>Constant peak memory</li><li>Responsive UI</li></ul>
<pre><code class="language-js">await worker.postMessage(file);</code></pre>
</article>
<aside class="promo">Subscribe to our newsletter!</aside>
<script>trackPageview();</script>
</body># Streaming Parsers in the Browser
Parsing a large file in a tab used to mean [freezing the main thread](https://example.com/blog/workers).
## Why workers matter
- Constant peak memory
- Responsive UI
```js
await worker.postMessage(file);
```Understanding the URL Format: WHATWG HTML Living Standard
- Format
- HTML document retrieved over HTTP
- Specification
- WHATWG HTML Living Standard
- Media type
text/html- Parser used
- Mozilla Readability + Turndown
Technical Specifications & Extraction Boundaries
- Client-rendered apps (SPAs): pages that render through client-side JavaScript (React, Vue, Angular) deliver an empty shell. The fetch retrieves raw server HTML only, with no headless browser execution.
- Paywalls and authentication: requests are sent anonymously, without cookies or headers. Paywalled content returns the wall or a teaser, and protected pages return a login form.
- Boilerplate stripping: Mozilla Readability scores DOM containers by link-to-text density and paragraph ratio, and discards navbars, cookie banners, sidebars and ads.
- Image handling: images are referenced as absolute URLs pointing at the origin host. Assets are never downloaded or base64-inlined.
- Interactive elements: video players, iframe widgets and dynamic canvas elements are dropped, because Markdown has no equivalent representation.
Developer Alternative: Python & Node.js Scraping Pipelines
For batch jobs or server-side pipelines, the same extraction stack runs outside the browser. Both snippets fetch the page directly, so they do not share this site's anonymous proxy.
# Fast, production-grade web article extraction in Python
import trafilatura
downloaded = trafilatura.fetch_url("https://example.com/article")
markdown_text = trafilatura.extract(downloaded, output_format="markdown")
print(markdown_text)// Server-side Node.js extraction using JSDOM + Readability + Turndown
import { JSDOM } from "jsdom";
import { Readability } from "@mozilla/readability";
import TurndownService from "turndown";
const response = await fetch("https://example.com/article");
const html = await response.text();
const doc = new JSDOM(html).window.document;
const article = new Readability(doc).parse();
const markdown = new TurndownService().turndown(article.content);
console.log(markdown);URL to Markdown: Comparing the Practical Approaches
| Method | Boilerplate removal | Client-rendered pages | Data retention | Setup | Batch / automation | Cost |
|---|---|---|---|---|---|---|
| This tool (Readability + Turndown) | Strong — article subtree is scored and isolated | Not supported (no script execution) | None — stateless fetch, local parse, no logs | None — paste a URL | One page at a time | Free |
| curl piped into Pandoc | None — you get the whole document, nav included | Not supported | Fully local retrieval and conversion | Local install plus dependencies | Strong — scriptable | Free |
| Headless browser (Playwright, Puppeteer) | Whatever extractor you bolt on yourself | Yes — scripts run before extraction | Yours to define; you own the stack | Heavy — browser binaries and code | Strong, resource-hungry | Infrastructure cost |
| Hosted reader and scraping APIs | Good — extraction is the product | Usually yes | Provider logs the URLs you submit | API key | Strong — built for pipelines | Per-request above a free tier |
| Pasting a page into a chat model | Variable — the model rewrites as it summarises | Not applicable, you supply the text | Prompt is retained under provider policy | None | Poor | Per-token |
How You Can Verify the Privacy Claim
Zero server upload
Conversion runs inside your browser tab. Open DevTools, switch to the Network panel, and convert a file: for every format except URL to Markdown you will see no request carrying your document — because there is no endpoint to send it to.
Parses on the main thread
Parsing stays inside your browser tab — this format’s parser needs DOM APIs. Nothing is uploaded. Everything is plain JavaScript — no native plugin, no WebAssembly toolchain, nothing to install.
Nothing to sign up for
No login, no quota, no paywall, and no tracking tied to your files. Analytics are cookieless and aggregate only. Read the privacy policy for the full data-flow breakdown, including the one proxied exception.
The parsers doing the work
No proprietary black box: each format is handled by a widely audited open-source library, running client-side at the version pinned in our lockfile.
- Mozilla Readability (Article subtree extraction)Article subtree extraction
- Turndown (HTML to Markdown)HTML to Markdown
- DOMPurify (HTML sanitisation)HTML sanitisation
URL to Markdown — FAQ
Why does a JavaScript-rendered page return nothing?
The fetch retrieves the HTML the server sends and never executes scripts. An app that paints its content client-side delivers only a shell, so there is no prose for Readability to score. Check with View Source rather than the element inspector: if your text is missing there, it is generated after delivery.
Is the fetched page content stored or logged anywhere?
No. The same-origin Function streams the HTML to your browser and keeps nothing — no cache, no database, no URL log. All parsing happens in your tab, and the Markdown is never sent anywhere.
Does it work on paywalled or login-protected pages?
No. The request is anonymous and carries none of your cookies or credentials, so you get whatever an unauthenticated visitor gets: a teaser, a subscription wall, or a login form.
Is the output clean enough for a RAG or LLM pipeline?
That is the primary use case. Boilerplate is removed before conversion, so embeddings are not polluted by near-identical cookie-banner and navigation chunks, and the heading hierarchy survives as natural chunk boundaries. Splitting on level-two headings yields self-contained sections.