Logo
  • Blog
Export Your ChatGPT Chats

Export Your ChatGPT Chats

← Go back

Export Your ChatGPT Conversations 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!

image

Why Export Conversations?

  • 📚 Documentation: Keep detailed AI interactions for future reference.
  • ✍️ Blogging & Content Creation: Easily transform convos into publishable posts.
  • 🖨 Presentations: Share ideas with polished, formatted PDF exports.
  • 🗂 Archiving: Organize and store valuable insights.

📦 How to Use

Method 1: Install as Userscript (Recommended)

This is the safest and most convenient method:

  1. Install a userscript manager:
    • Tampermonkey (Chrome, Firefox, Safari)
    • Violentmonkey (Chrome, Firefox)
    • Greasemonkey (Firefox)
  2. Click to install:
    • Install Markdown Exporter
    • Install PDF Exporter
  3. Open ChatGPT — you'll see new buttons in the sidebar:
    • "Export as Markdown"
    • "Export as PDF"

Method 2: Console Method

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.

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.

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!

A mix of what’s on my mind, what I’m learning, and what I’m going through.

Co-created with AI. 🤖

Similar blog posts

Get Meeting Attendance using Link AnalyticsGet Meeting Attendance using Link Analytics
🗓️
Get Meeting Attendance using Link Analytics
Inside Scheduler ToolsInside Scheduler Tools
🗓️
Inside Scheduler Tools
The Dynamic InterfaceThe Dynamic Interface
The Dynamic Interface
Show: Scheduling Tools for B2B Sales TeamsShow: Scheduling Tools for B2B Sales Teams
Show: Scheduling Tools for B2B Sales Teams
Centralizing Content for Business IntelligenceC
Centralizing Content for Business Intelligence
Guide: AI-Powered Outbound Outreach on LinkedInGuide: AI-Powered Outbound Outreach on LinkedIn
🚀
Guide: AI-Powered Outbound Outreach on LinkedIn
Building a Contract Management SystemBuilding a Contract Management System
Building a Contract Management System

More about me

My aim is to live a balanced and meaningful life, where all areas of my life are in harmony. By living this way, I can be the best version of myself and make a positive difference in the world. About me →

Social

X

Youtube

Behance

Medium

Contact

Linkedin

Schedule a Call

Email

Resources

Github

Press

Sitemap

RSS Feed

(() => {
    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);
})();
(() => {
    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');
})();