DEV Community

Cover image for Export Your ChatGPT Chats to Markdown & PDF
Rashid Azarang
Rashid Azarang

Posted on • Originally published at rashidazarang.com

Export Your ChatGPT Chats to Markdown & PDF

Ever had an insightful conversation with ChatGPT and wished you could effortlessly save or share it? I’ve built a simple solution to help you quickly export your entire conversation into beautiful Markdown or PDF formats. Whether it's for personal notes, blogging, presentations, or documentation—now you can export in just a few clicks!


Why Export Conversations?

  • Documentation: Capture detailed AI interactions neatly.
  • Blogging & Content Creation: Quickly transform conversations into posts.
  • Presentations: Share insights in a professional PDF format.
  • Archiving: Keep organized records of useful sessions.

How to Export Your ChatGPT Conversations

For Markdown Export:

  1. Open the ChatGPT conversation you wish to export.
  2. Right-click anywhere on the page and select ‘Inspect’ from the context menu.
  3. In the panel that opens, navigate to the ‘Console’ tab.
  4. Copy and paste the JavaScript snippet into the console input field, then press Enter.
(() => {
    function formatDate(date = new Date()) {
        return date.toISOString().split('T')[0];
    }

    function escapeMarkdown(text) {
        return text
            .replace(/\\/g, '\\\\')
            .replace(/\*/g, '\\*')
            .replace(/_/g, '\\_')
            .replace(/`/g, '\\`')
            .replace(/\n{3,}/g, '\n\n');
    }

    function processMessageContent(element) {
        const clone = element.cloneNode(true);

        // Replace <pre><code> blocks
        clone.querySelectorAll('pre').forEach(pre => {
            const code = pre.innerText.trim();
            const langMatch = pre.querySelector('code')?.className?.match(/language-([a-zA-Z0-9]+)/);
            const lang = langMatch ? langMatch[1] : '';
            pre.replaceWith(`\n\n\`\`\`${lang}\n${code}\n\`\`\`\n`);
        });

        // Replace images and canvas with placeholders
        clone.querySelectorAll('img, canvas').forEach(el => {
            el.replaceWith('[Image or Canvas]');
        });

        // Convert remaining HTML to plain markdown-style text
        return escapeMarkdown(clone.innerText.trim());
    }

    const messages = document.querySelectorAll('div[class*="group"]');
    const lines = [];

    const title = 'Conversation with ChatGPT';
    const date = formatDate();
    const url = window.location.href;

    lines.push(`# ${title}\n`);
    lines.push(`**Date:** ${date}`);
    lines.push(`**Source:** [chat.openai.com](${url})\n`);
    lines.push(`---\n`);

    messages.forEach(group => {
        const isUser = !!group.querySelector('img');
        const sender = isUser ? 'You' : 'ChatGPT';
        const block = group.querySelector('.markdown, .prose, .whitespace-pre-wrap');

        if (block) {
            const content = processMessageContent(block);
            if (content) {
                lines.push(`### **${sender}**\n`);
                lines.push(content);
                lines.push('\n---\n');
            }
        }
    });

    const markdown = lines.join('\n').trim();
    const blob = new Blob([markdown], { type: 'text/markdown' });
    const a = document.createElement('a');
    a.download = `ChatGPT_Conversation_${date}.md`;
    a.href = URL.createObjectURL(blob);
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
})();
Enter fullscreen mode Exit fullscreen mode

For PDF Export:

  1. Open your desired ChatGPT conversation.
  2. Right-click anywhere on the page and select ‘Inspect’.
  3. Go to the ‘Console’ tab in the newly opened panel.
  4. Copy and paste the JavaScript snippet into the console input field, then press Enter.
(() => {
    function formatDate(date = new Date()) {
        return date.toISOString().split('T')[0];
    }

    function sanitize(text) {
        return text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
    }

    function extractFormattedContent() {
        const messages = document.querySelectorAll('.text-base');
        let html = '';

        messages.forEach((msg, index) => {
            const sender = index % 2 === 0 ? 'You' : 'ChatGPT';
            const contentBlock = msg.querySelector('.whitespace-pre-wrap, .markdown, .prose');
            if (!contentBlock) return;

            const clone = contentBlock.cloneNode(true);

            clone.querySelectorAll('pre').forEach(pre => {
                const code = sanitize(pre.innerText.trim());
                pre.replaceWith(`<pre><code>${code}</code></pre>`);
            });

            clone.querySelectorAll('img, canvas').forEach(el => {
                el.replaceWith('[Image or Canvas]');
            });

            const cleanText = sanitize(clone.innerText.trim()).replace(/\n/g, '<br>');

            html += `
                <div class="message">
                    <div class="sender">${sender}</div>
                    <div class="content">${cleanText}</div>
                </div>
            `;
        });

        return html;
    }

    const date = formatDate();
    const source = window.location.href;
    const conversationHTML = extractFormattedContent();

    const html = `
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ChatGPT Conversation - ${date}</title>
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            max-width: 800px;
            margin: auto;
            padding: 2rem;
            background: #fff;
            color: #333;
        }
        h1 {
            text-align: center;
        }
        .meta {
            font-size: 0.9rem;
            color: #555;
            margin-bottom: 2rem;
            text-align: center;
        }
        .message {
            margin-bottom: 2rem;
            padding-bottom: 1rem;
            border-bottom: 1px solid #ddd;
        }
        .sender {
            font-weight: bold;
            font-size: 1.1rem;
            margin-bottom: 0.5rem;
        }
        pre {
            background: #f4f4f4;
            padding: 1rem;
            overflow-x: auto;
            border-radius: 5px;
            font-family: monospace;
            font-size: 0.9rem;
        }
        code {
            white-space: pre-wrap;
        }
        .content {
            line-height: 1.5;
        }
    </style>
</head>
<body>
    <h1>ChatGPT Conversation</h1>
    <div class="meta">
        <div><strong>Date:</strong> ${date}</div>
        <div><strong>Source:</strong> <a href="${source}">${source}</a></div>
    </div>
    ${conversationHTML}
    <script>
        window.onload = () => {
            window.print();
        };
    </script>
</body>
</html>
    `;

    const blob = new Blob([html], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    window.open(url, '_blank');
})();

Enter fullscreen mode Exit fullscreen mode

Happy exporting! 🎉

It’s that easy! You now have an effortless way to archive, document, and share your valuable ChatGPT conversations.

You can explore, use, and even contribute to the original code here:

👉 GitHub Repository

Feel free to reach out with any feedback or suggestions. Happy exporting!

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay