Guide
How to convert HTML to Markdown for LLMs & RAG
Feeding raw HTML to a language model wastes tokens and confuses the model. Clean Markdown fixes both. Here's why it matters, what "clean" actually means, and how to get it — even from JavaScript-heavy pages.
By Roger Campos · Last updated: July 2026
TL;DR
Convert web pages to Markdown before sending them to an LLM: it strips the navigation, ads and markup that waste tokens, and keeps the structure (headings, lists, links, code) that models and retrieval rely on. The catch is JavaScript — you have to render the page in a real browser first, or client-rendered sites come back empty.
Free plan, no credit card. 50 AI + 500 web operations / month.
The problem
Why raw HTML is the wrong input for a model
A web page is written for a browser, not a language model. Most of it is scaffolding — and that scaffolding is expensive.
When you fetch a page, the bytes you get back are mostly not content. Navigation menus, footers, cookie banners, ad slots, inline styles, analytics snippets and framework markup can easily make up 80–90% of an article's HTML. None of it means anything to a model, but all of it costs tokens.
That has two consequences. First, cost and context: you pay for every token and you fill the context window with noise, so fewer real pages fit. Second, quality: boilerplate dilutes the signal, and models can latch onto navigation text or repeated chrome instead of the actual content.
- Token waste — raw HTML is several times larger than the equivalent Markdown.
- Diluted signal — the model has to find the content inside the markup.
- Worse chunks — splitting raw HTML for RAG buries content in tags and breaks structure.
The fix
What a clean Markdown conversion keeps — and drops
The goal is to reduce a page to its main content while preserving the structure that carries meaning. Markdown is the sweet spot: compact, plain-text, and semantic enough for a model to understand headings, lists, emphasis, links and code.
Keep
- Headings (the document's outline)
- Paragraphs, lists and tables
- Links and their anchor text
- Code blocks, inline code and quotes
- The main article or body content
Drop
- Navigation, menus and breadcrumbs
- Headers, footers and sidebars
- Cookie banners and consent modals
- Ads, tracking and analytics scripts
- Inline styles and framework markup
The catch
JavaScript: why a naive fetch comes back empty
Here's the trap that breaks most homemade converters. Fetch the raw HTML of a modern site — a docs page, a news app, anything built with React, Vue or Svelte — and you often get a near-empty shell. The content isn't in the HTML the server sends; it's added by JavaScript after the page loads in a browser.
So the order matters: you have to render the page in a real browser first, let its JavaScript run, and only then extract and convert. Skip that step and you'll silently convert an empty page — the worst kind of bug, because it looks like it worked.
Related
This is the single most common reason web scraping "randomly" fails. The full explanation — how to tell if a site is client-rendered and how to get the real DOM — is in the guide on rendered vs. raw HTML.
How to do it
A reliable pipeline, step by step
- 1Render in a real browser. Load the URL in headless Chrome, follow redirects, and wait for the content to appear — so client-rendered pages produce complete HTML.
- 2Isolate the main content. Strip navigation, headers, footers, sidebars and banners, keeping the article or primary body.
- 3Convert to Markdown. Map headings, lists, links, tables and code to their Markdown equivalents, preserving structure.
- 4Chunk on structure. For RAG, split on headings and paragraphs — not arbitrary character counts — so each chunk is a coherent unit.
- 5Cache aggressively. The same URL rarely changes minute to minute; caching results avoids re-rendering and re-billing the same page.
Watch out
Common pitfalls
- Tables and code are where lazy converters fall apart — verify they survive intact.
- Images usually become links or alt text; decide whether your pipeline needs them.
- Paywalls and logins only expose what's publicly rendered — you can't extract what you can't see.
- Over-summarizing too early — keep a faithful Markdown copy; summarize as a separate step so you don't lose detail your retrieval might need.
FAQ
Frequently asked questions
Why not just send raw HTML to the model?
Does Markdown really save tokens?
How do JavaScript-heavy sites affect the conversion?
Should I chunk before or after converting to Markdown?
Try it yourself
Free tools for this
No signup — run these on a real page right now, then call the same endpoint from your code.
- Turn any URL into clean Markdown
Paste a link and get the page's main content as tidy Markdown — headings, lists, links and code kept, navigation and cookie banners stripped. The format LLMs and RAG pipelines work best with.
Try it free - Summarize any web page with AI
Paste a link and get a concise AI summary of the page's main content — the substance, without the navigation, ads and boilerplate.
Try it free
Put this into practice.
Every URLpipe endpoint has a free, no-signup tool — try the ideas from this guide on a real page, then grab an API key to run them from your code. 50 AI + 500 web operations a month, no card.