A browser extension that turns the main content of any web page into clean Markdown for your notes, docs, or AI.
Install • Getting Started • Features • Supported sites • Examples • How it works
Markdown may be 22 years old, but the explosion of AI, agents, Obsidian, and other tools has made it more important than ever.
Page Content to Markdown aims to make this fast and easy.
Click the extension icon, pick what you want to capture, and you get clean optimized Markdown back. That's it.
By default it skips nav, ads, footers, comments, and the rest of a page's chrome so what you save is the actual content.
For X, Claude, Grok, and ChatGPT, dedicated extractors do better than the general path. They handle threading, reasoning blocks, code panels, citations, and conversation roles correctly so what you save reads like what you'd actually want, not a screen-scrape.
Everything happens in your browser. No servers, no telemetry, no third parties, no bullshit.
- Firefox / Zen / LibreWolf: install from Firefox Add-ons.
- Chrome / Edge / Brave / Arc: install from the Chrome Web Store.
git clone https://github.com/jaredatch/page-content-to-markdown.git
cd page-content-to-markdown
npm install
npm run buildThen load the built dist/ directory:
- Firefox:
about:debugging→ "This Firefox" → "Load Temporary Add-on" → selectdist/manifest.json - Chrome:
chrome://extensions→ enable Developer Mode → "Load unpacked" → selectdist/
Open the popup, then pick what you want to capture: Page content for the main content, or, on supported sites, a Tweet, Thread, Conversation. Hit Copy or Save. The popup remembers your last pick per site.
- Pick specific elements: use the "select elements on page" link → hover and click → Copy or Save from the floating action bar (the selection persists, so you can fire both on the same set)
- Selected text: right-click → "Copy selection as Markdown"
- Default action: Copy or Save — whichever you set as default in the extension options page becomes the filled primary button
- Settings: click the gear icon in the popup header to configure output, formatting, the page-info format, and more
Selector mode, grab just what you want.
- Smart content extraction. Skips nav, ads, newsletter sign up forms, footers, comments, and other page chrome by default. Read more on how it works
- Intuitive content selector. Jump into selection mode, click the page elements or content you want, and you're done.
- Fine-tuned site actions for X, Claude, Grok, and ChatGPT. Dedicated extractors that handle each site's quirks directly. E.g. on X, we detect what's actually on the page and only show the options that fit — single tweet, thread, or article. Check out supported sites.
- Modern Markdown. Full GFM — tables, strikethrough, task lists, etc.
- Clipboard or file. Copy to clipboard or save as
.md. You decide. - Page info as inline metadata or YAML frontmatter. Title, URL, and date/time at the top of every save — as bold key-value lines, or as YAML for Obsidian, Logseq, Hugo, Jekyll, and similar tools.
- Image and link handling. Keep them, replace with alt text, strip them, or collect image URLs at the end of the doc. Useful when feeding output to LLMs that don't need the noise.
- Removes tracking parameters.
utm_*,fbclid,gclid, and other analytics noise removed from URLs by default. - Customizable filenames. Template-based with tokens (
{title},{date},{domain},{slug}, etc.) and a choice of preserve / kebab-case / snake_case. - Formatting preferences. Heading style, bullet markers, code blocks, link style.
- Keyboard shortcuts and context menus.
Cmd+Shift+M/Ctrl+Shift+Mtoggles selection mode. A second shortcut (no default — bind it yourself in your browser's extension shortcut settings) runs your default Copy/Save action with the smart-detected content type, no popup needed. Right-click to convert selected text or pick an element.
For these sites, dedicated extractors produce cleaner output than the general path:
| Site | Content types | Where it works |
|---|---|---|
| X / Twitter | Tweet, Thread, Article | x.com, twitter.com |
| Claude | Conversation | Share pages and active chats |
| Grok | Conversation | Share pages and active chats |
| ChatGPT | Conversation | Share pages and active chats |
See docs/supported-sites.md for the full breakdown of what each site action captures, and docs/building-site-extractors.md if you want to add another.
Saving a single tweet with the default inline page info:
**Title:** X Post by @naval
**URL:** https://x.com/naval/status/2011358865187848389
**Date:** May 6, 2026 at 3:34 PM
---
## @naval (Naval ✓)
*Posted: January 14, 2026 at 2:44 AM*
If you aren't getting happier as you get older, you're doing it wrong.
💬 988 🔁 4.4K ❤️ 36.5K 🔖 4.3K 👁 1.2MSaving a Claude active chat with YAML frontmatter instead — the format Obsidian, Logseq, Hugo, and Jekyll all parse:
---
title: "Why is array === array always false in JavaScript?"
url: https://claude.ai/chat/abc123
date: 2026-05-06 14:32
---
# Why is array === array always false in JavaScript?
---
**Human:**
I have two arrays with identical contents and `a === b` returns false. What's going on?
---
**Claude:**
This is one of the most common JavaScript gotchas. Arrays are **reference types** — when you compare them with `===`, you're comparing whether both variables point to the *same array in memory*, not whether their contents match.
```js
const a = [1, 2, 3];
const b = [1, 2, 3];
const c = a;
a === b // false — different arrays, same contents
a === c // true — same array (c just references a)
```
To compare contents, use `JSON.stringify(a) === JSON.stringify(b)` for simple cases, or Lodash's `isEqual` for anything more complex.
---
ALL THE OPTIONS! Granular control of your generated markdown.
Everything stays on your machine. The extension makes no network calls and contacts no third-party services. Your preferences live in browser storage.
See the Privacy Policy for the full breakdown of permissions and what they're used for.
- How content extraction works — capture/strip strategy and FAQ
- Supported sites — what each site action captures
- Building site extractors — workflow for adding new sites
- Contributing — setup, tests, and PR guide
- Firefox: MV3 with
background.scripts(also works great with Zen Browser) - Chrome: MV3 with
service_worker - Keyboard shortcuts:
Cmd+Shift+M/Ctrl+Shift+Mtoggles selection mode (avoids Firefox'sCmd+Shift+Sscreenshot conflict). Quick-extract has no default key; bind your own.
Originally forked from elad12390/browser-extension-copy-page-as-markdown. The project has been substantially rewritten since; the fallback text extractor (simple-universal-extractor.js) is the main piece of the original that remains. Thanks to Elad for the initial scaffold.
MIT because of course. see LICENSE for full text. Brand icons in the site-action display are from Font Awesome and Lobe Icons; see ATTRIBUTIONS.md for credits.
