Exporting Comments in Chrome

We don't support exporting comments at this time but you can use this workaround in the meantime.

Instructions

    Open the Slite doc that contains the comments you want to extract.
    Click the Speech Balloon icon in the top right to open the comments panel.
    Open the Chrome Developer Tools (Cmd-Opt-I on Mac, Ctrl+Shift+I on Windows).
    Go to the "Console" tab.
    Copy the script below and paste it into the console.
    Press Enter to run.
    Right click and choose "Copy console".
    Manage clipboard content accordingly.
You might need to type allow pasting in the console before you can paste the script.
(async () => {
// --- Configuration: CSS Selectors ---
// NOTE: These selectors are based on Slite's structure as of late 2024.
// If the script fails, these may need to be updated by inspecting the page's HTML.
const THREAD_CONTAINER_SELECTOR = 'div[data-sidebar-thread-id]';
const COMMENT_ROW_SELECTOR = 'div[data-test-id="commentRow"]';
const QUOTED_TEXT_SELECTOR = 'div.border-left-medium';
const AUTHOR_SELECTOR = 'span.font-weight-semibold.ellipsis.shade-00';
const TIMESTAMP_SELECTOR = 'span.font-size-normal.ellipsis.shade-30';
const COMMENT_BODY_SELECTOR = 'div[data-test-id="editCommentContent"]';
// A helper function to find the "Show more comments" element within a thread.
const findShowMoreElement = (threadElement) => {
const spans = threadElement.querySelectorAll('span.padding-left-40');
for (const span of spans) {
if (span.textContent.match(/Show \d+ more comment/)) {
return span;
}
}
return null;
};
// --- Script Execution ---
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const EXPAND_DELAY_MS = 700; // Wait time after clicking "show more" for content to load.
console.clear();
console.log("šŸš€ Starting Slite Comment Extractor (Sequential Mode)...");
// 1. Find all comment thread containers in the sidebar.
const threadContainers = document.querySelectorAll(THREAD_CONTAINER_SELECTOR);
if (threadContainers.length === 0) {
console.warn("🚫 No comment threads found. Please ensure:\n1. The comments sidebar is open on the Slite page.\n2. The script's CSS selectors are up-to-date with Slite's current website structure.");
return;
}
console.log(`šŸ” Found ${threadContainers.length} comment thread(s). Processing one by one.`);
// 2. Iterate through each thread container sequentially.
for (const [index, thread] of threadContainers.entries()) {
const threadNumber = index + 1;
console.log(`\n\n\n--- [ ${threadNumber}/${threadContainers.length} ] --- PROCESSING THREAD ---`);
// Scroll the thread into view to ensure it's interactable
thread.scrollIntoView({ behavior: 'smooth', block: 'center' });
await sleep(500); // Wait for scroll to finish
// --- EXPANSION PHASE for the current thread ---
let showMoreElement;
let expansionAttempts = 0; // Safety break to prevent infinite loops
const MAX_ATTEMPTS = 20;
while ((showMoreElement = findShowMoreElement(thread)) && expansionAttempts < MAX_ATTEMPTS) {
console.log(` [Thread ${threadNumber}] Expanding hidden replies...`);
showMoreElement.click();
await sleep(EXPAND_DELAY_MS);
expansionAttempts++;
}
console.log(` [Thread ${threadNumber}] āœ… Expansion complete.`);
// --- EXTRACTION AND PRINTING PHASE for the current thread ---
const commentRows = thread.querySelectorAll(COMMENT_ROW_SELECTOR);
let threadOutput = `<!-- ========== THREAD ${threadNumber} ========== -->\n\n`;
commentRows.forEach((row, rowIndex) => {
const authorEl = row.querySelector(AUTHOR_SELECTOR);
const timestampEl = row.querySelector(TIMESTAMP_SELECTOR);
const bodyEl = row.querySelector(COMMENT_BODY_SELECTOR);
const quotedEl = row.querySelector(QUOTED_TEXT_SELECTOR);
const author = authorEl ? authorEl.textContent.trim() : 'Unknown Author';
const timestamp = timestampEl ? timestampEl.textContent.trim() : 'Unknown Timestamp';
// .textContent gets all text, including from @mentions which are in separate elements
const body = bodyEl ? bodyEl.textContent.trim() : '[No content]';
threadOutput += `šŸ‘¤ **${author}** (${timestamp})\n`;
if (quotedEl) {
// Clean up quoted text, which may have extra whitespace
const quotedText = quotedEl.textContent.trim().replace(/\s+/g, ' ');
threadOutput += `> šŸ’¬ _Replying to: "${quotedText}"_\n`;
}
threadOutput += `${body}\n`;
if (rowIndex < commentRows.length - 1) {
threadOutput += `\n----\n\n`;
}
});
threadOutput += `\n<!-- ========== END THREAD ${threadNumber} ========== -->`;
// Print the fully extracted and formatted thread to the console
console.log(threadOutput);
}
console.log("\n\n\nšŸŽ‰ --- All threads have been processed and printed above! --- ✨ ");
})();