Updated October 7, 2026
Short answer: open the conversation in ChatGPT, press Ctrl+A then Ctrl+C (Cmd on a Mac), paste it into a browser-only converter such as Chat to PDF, and press Save as PDF. You get the whole chat with every message labelled, and code blocks, tables and formulas intact. No extension, no account, and the conversation never leaves your browser.
The same works for Claude. Below: why the obvious options fall short, the steps, and how the tool is built so it can't upload anything (it's open source if you'd rather read the code first).
What's wrong with the built-in options?
Ctrl+P on the chat page. You get the sidebar, the message box, and whatever the page layout does to print. Wide code blocks are clipped at the page edge instead of wrapping, and the result looks like a screenshot of an app rather than a document.
ChatGPT's Export data. Under Settings → Data controls → Export data, ChatGPT emails you a ZIP of your entire history. OpenAI's help article says the download link expires 24 hours after you receive it. Inside are conversations.json and chat.html: data files, not a PDF of the one chat you wanted.
Share-link-to-PDF websites. Paste a share link, get a PDF. To do that, their server fetches the conversation for you. OpenAI's Terms of Use don't allow automatically or programmatically extracting data or output from the service, and Anthropic's Consumer Terms forbid crawling or scraping theirs. It also means a third party now has a copy of your chat.
So the approach here is: you copy the conversation yourself, and everything after that happens in your own browser tab.
Step by step
- Open the conversation in ChatGPT (or open its share link).
- Select and copy it. Click inside the conversation, press Ctrl+A, then Ctrl+C.
- Paste it into pressleaf.roledawn.com/tools/chat-to-pdf. The preview shows each message labelled "You" or "ChatGPT". The sidebar, buttons and input box are dropped.
- Check the title. It's filled in from your first message and becomes the file name. Pick Letter or A4 if you care.
- Press Save as PDF, then choose Save as PDF as the destination in the print dialog.
Want Markdown instead? Download Markdown gives you ## You / ## ChatGPT sections with the original TeX for any math.
Already have the official export?
Open conversations.json (or ChatGPT's chat.html) from the ZIP with Open a file. You get a searchable list of every conversation; pick one and save it. For ChatGPT exports, the tool walks the message tree from the conversation's current node back to the root, so you get the branch you were actually looking at, not the regenerated answers you abandoned. Claude's conversations.json works the same way (Anthropic's export instructions).
What comes through intact
- Code blocks keep indentation and the language name. In the PDF, long lines wrap instead of being cut off at the margin.
- Tables keep their columns, and on a table that spans pages the header row repeats on each page.
-
Math. ChatGPT and Claude write formulas as TeX (
$…$,\[…\],$$…$$). Those are rendered as real formulas. Prices like "$5 and $10" are left alone. - Any script. The PDF is made by your browser's print engine with your system fonts, so Chinese, Japanese and Arabic print correctly, and the text stays selectable and searchable.
How "nothing uploaded" is enforced, not just promised
This is the part I care about most, and the part you can verify yourself in DevTools.
1. The page can't make network requests. It ships with this Content-Security-Policy:
default-src 'none'; script-src 'self'; connect-src 'none'; form-action 'none'; ...
connect-src 'none' makes the browser block every fetch, XHR, WebSocket and beacon from the page. Even if the script wanted to send your conversation somewhere, the browser would refuse. Open the Network tab while you paste: nothing goes out.
2. Pasted HTML is sanitized before it's displayed. When you copy from the chat page, the clipboard holds HTML. The tool reads text/html from the paste event, finds the turns (ChatGPT marks them with data-message-author-role), and passes every message through an allowlist sanitizer: known document tags only, no <script>, <iframe> or <svg>, no event handlers, no javascript: links.
3. Math is converted locally. TeX is turned into MathML in the browser with Temml, so there's no call to a rendering service.
4. The PDF is the browser's print engine. No PDF library, no server. The print stylesheet does the work:
@media print {
.doc pre { white-space: pre-wrap; overflow-wrap: anywhere; }
.doc thead { display: table-header-group; }
.doc tr, .doc img, .who { break-inside: avoid; }
.who { break-after: avoid; }
}
pre-wrap is what stops code from being clipped, table-header-group repeats table headers across pages, and break-after: avoid keeps a "ChatGPT" label from being stranded at the bottom of a page away from its answer.
Splitting plain text into turns
If you paste plain text instead (from a notes app, say), there's no DOM to read. The parser looks for the markers ChatGPT and Claude put in copied text and in common Markdown exports: You said: / ChatGPT said:, ## You / ## Claude, and User: / Assistant:. Lines inside fenced code blocks are skipped, so a code sample that happens to contain You said: doesn't split the conversation in half. If there aren't at least one user turn and one assistant turn, it keeps the text as one clean block rather than guessing.
Limitations
- It doesn't open share links. Open the link yourself and copy the page.
- Images in
conversations.jsonexports show as[image], because the JSON only references uploaded files. - Canvas documents and tool output that isn't part of the visible message text aren't included.
- You click once more in the print dialog to save. That's the price of using the browser's own engine.
Run it locally
git clone https://github.com/binbuilds0/chat-to-pdf.git
cd chat-to-pdf
# open index.html in your browser; dist/ is prebuilt
npm install && npm test # if you want to run the tests
It's MIT licensed. If you have a pasted chat that doesn't split correctly, an issue with a trimmed HTML sample is the most useful bug report I can get.
I'm also working on Pressleaf, a Chrome extension that does this in one click on the chat page itself and handles any web page too. But for the occasional chat, the copy-paste page above is all you need.
Top comments (0)