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

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(/, '<').replace(/>/g, '>');
    }

    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(`${code}