Home/How to Convert a URL to Markdown

How to convert a URL to Markdown

Whether you want clean Markdown for an LLM prompt, a RAG pipeline, a documentation archive, or just to quote a blog post in your notes - here are the four ways to do it, ranked from easiest to "you'll regret this".

When you'd want this


Method 1 - The web tool (recommended)

The fastest path. No signup, no install, no API token. Best when you want to convert a single page or two, right now.

  1. Open the converter

    Go to the homepage. The tool is the first thing you see.

  2. Paste the URL

    Drop any public URL into the input. Articles, docs, blog posts, product pages, single-page apps - all fine. The crawler runs a real headless browser, so JavaScript-rendered content works.

  3. Click "Convert to Markdown"

    You'll see a progress message ("Crawling… 12s"). After 20–90 seconds for most pages, the cleaned-up Markdown appears below.

  4. Copy or download

    Use the Copy button to put the Markdown on your clipboard, or Download .md to save it as a file.

The web tool is rate-limited to 3 free conversions per browser. If you hit the limit, switch to the API or run the URL to Markdown Actor on Apify yourself (free plan: $5/month of free usage).


Method 2 - The REST API

Best when you need to convert URLs from code: a script, a cron job, a backend service, or a RAG indexing pipeline.

bash
curl -X POST \
  "https://api.apify.com/v2/acts/apify~url-to-markdown/run-sync-get-dataset-items?token=$APIFY_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/article",
    "scrapingTool": "raw-http",
    "proxyConfiguration": { "useApifyProxy": true }
  }' | jq -r '.[0].markdown'

For the JavaScript and Python SDKs, async polling, and the recommended input, see the API integration guide.


Method 3 - The MCP server

Best if you live inside Claude Desktop or Claude Code and want the AI itself to call the converter. Install once, then just ask:

Convert https://example.com/article to clean Markdown
using the Apify URL to Markdown Actor.

See the MCP setup guide for the one-line install and config.


Method 4 - Manual: HTML-to-Markdown libraries

You can piece this together yourself with fetch, an HTML parser, and an HTML-to-Markdown converter. It looks deceptively simple:

javascript
// In theory:
import TurndownService from 'turndown';

const html = await fetch('https://example.com/article').then(r => r.text());
const md = new TurndownService().turndown(html);
console.log(md);

In practice, this falls apart fast. Here are the issues you'll hit, in roughly the order you'll hit them:

1. The page is JavaScript-rendered

A fetch() only gets the server-rendered HTML. For React, Vue, Next.js, Angular, and most modern marketing sites, that means an empty <div id="root"></div>. To get real content you need to spin up Playwright or Puppeteer, which means downloading ~300 MB of Chromium, dealing with launch flags, sandboxing on Linux, and waiting for network-idle.

2. Anti-bot blocking

Cloudflare, DataDome, PerimeterX, Akamai Bot Manager, and Google's bot detection will challenge or outright 403 you. You'll need residential proxies, browser fingerprint randomisation, and TLS fingerprint shaping - which by itself is an entire engineering project.

3. Cookie banners and modals

The first ~30% of most pages, after the cookie banner is rendered, is junk: GDPR notices, newsletter modals, app-install nags. These show up in your Markdown unless you write per-site selectors to dismiss them.

4. Boilerplate (nav, footer, sidebars, ads)

A naive HTML-to-Markdown pass will faithfully convert your nav, footer, related-articles widget, ad slots, and 47 social-share buttons. You need a content-extraction step (Readability.js, trafilatura, or a custom selector list) before the conversion.

5. Dynamic loading and pagination

Lazy-loaded images, "Load more" buttons, infinite scroll, accordions that hide half the content - all of those require browser interaction (clicks, scrolls, waits) before the HTML is "complete".

6. Maintenance

Even after you solve all the above, every site changes its DOM eventually. Selectors break, anti-bot vendors update, frameworks ship new SSR strategies. Your "simple" converter becomes a permanent maintenance burden.

Bottom line

Rolling your own URL-to-Markdown converter is straightforward for your own static blog, and brittle for everything else. For arbitrary URLs, a battle-tested tool - like the Apify URL to Markdown Actor (or the Website Content Crawler for whole sites) - saves you weeks of infrastructure work.


Which method should I pick?

Use caseRecommended method
One-off conversionWeb tool
A few dozen URLs from a scriptREST API
From inside an AI chatMCP server
Thousands of URLs / whole-site dumpApify console (bulk run)
A site you fully controlManual (Turndown / Pandoc) - fine here

Next steps