Skip to content
Email Sequence Splitter – No-Code ZIP Export

Email Sequence Splitter

Transform your email sequence into individual HTML files and download as ZIP

📤 Upload Your HTML File

📄 Click to choose or drag & drop
your email sequence HTML file
No file selected

💡 The splitter automatically finds each email by locating <h2>Day N - ... headers and content until the next <hr> or <h2>.

✨ Quick Start

1. Download the HTML version of your completed email sequence from the Sequence Genie tool

2. Upload the file using the upload area on the left

3. Configure options in the Options tab

4. Preview your split emails

5. Download as a ZIP file

✅ All processing is local in your browser. No external uploads.

⚙️ Configuration Options

Filename Settings

Use {{num}} for the sequence number and Email Sequence Splitter for the email title

Numbering

Pad width determines zero-padding (e.g., 01, 02, 03)

HTML Structure

Content Processing

👁️ Preview

No file parsed yet. Upload a file and click "Parse & Preview" in the Options tab.
${h1}${container.innerHTML} `; emails.push({ index:i+1, fullTitle, title, strategy, html:docHtml, size: utf8Encode(docHtml).length }); } return emails; } function escapeHtml(s){ return s.replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); } /* ======================= UI Logic ======================= */ let loadedFile = null; let parsed = []; function setStatus(msg, cls=""){ const el = byId("status"); el.className = cls ? `status ${cls}` : "muted"; el.textContent = msg; } function setFileInfo(name, size){ byId("fileInfo").textContent = name ? `✅ ${name} – ${(size/1024).toFixed(1)} KB` : "No file selected"; } // Tab switching document.querySelectorAll(".tab-btn").forEach(btn => { btn.addEventListener("click", () => { const tab = btn.dataset.tab; document.querySelectorAll(".tab-btn").forEach(b => b.classList.remove("active")); document.querySelectorAll(".tab-content").forEach(c => c.classList.remove("active")); btn.classList.add("active"); byId(tab).classList.add("active"); }); }); // File input change byId("fileInput").addEventListener("change", (e) => { const f = e.target.files[0]; if(f) { loadedFile = f; setFileInfo(f.name, f.size); byId("parseBtn").disabled = false; console.log("File selected via input:", f.name); } }); // Dropzone click to open file picker byId("dropzone").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); byId("fileInput").click(); }); // Drag and drop handlers byId("dropzone").addEventListener("dragover", (e) => { e.preventDefault(); e.stopPropagation(); byId("dropzone").style.backgroundColor = "rgba(99, 102, 241, 0.2)"; byId("dropzone").style.borderColor = "rgb(79, 70, 229)"; }); byId("dropzone").addEventListener("dragleave", (e) => { e.preventDefault(); e.stopPropagation(); byId("dropzone").style.backgroundColor = ""; byId("dropzone").style.borderColor = ""; }); byId("dropzone").addEventListener("drop", (e) => { e.preventDefault(); e.stopPropagation(); byId("dropzone").style.backgroundColor = ""; byId("dropzone").style.borderColor = ""; const files = e.dataTransfer.files; if(files && files.length > 0) { const f = files[0]; loadedFile = f; setFileInfo(f.name, f.size); byId("parseBtn").disabled = false; console.log("File dropped:", f.name); } }); // Reset button byId("resetBtn").addEventListener("click", () => { byId("pattern").value = "Day {{num}} - Email Sequence Splitter.html"; byId("startNum").value = "1"; byId("pad").value = "2"; byId("includeTitle").value = "yes"; byId("includeH1").value = "yes"; byId("keepSubjects").value = "strip"; }); // Navigation buttons byId("nextToOptions").addEventListener("click", () => { document.querySelector('[data-tab="options"]').click(); }); byId("prevToUpload").addEventListener("click", () => { document.querySelector('[data-tab="upload"]').click(); }); // Parse button byId("parseBtn").addEventListener("click", async () => { if(!loadedFile) { setStatus("❌ No file loaded", "error"); return; } setStatus("⏳ Parsing your file...", "info"); try { const html = await loadedFile.text(); const opts = { pattern: byId("pattern").value || "Day {{num}} - Email Sequence Splitter.html", start: Math.max(1, parseInt(byId("startNum").value || "1", 10)), pad: Math.max(1, parseInt(byId("pad").value || "2", 10)), includeTitle: byId("includeTitle").value, includeH1: byId("includeH1").value, keepSubjects: byId("keepSubjects").value }; parsed = parseSequence(html, opts); const tbl = byId("previewTable"); const tb = tbl.querySelector("tbody"); tb.innerHTML = ""; parsed.forEach((em, i) => { const tr = document.createElement("tr"); const num = padNum(i + opts.start, opts.pad); tr.innerHTML = `#${num} ${escapeHtml(em.title)} ${em.strategy ? escapeHtml(em.strategy) : ''} ${(em.size / 1024).toFixed(1)} KB`; tb.appendChild(tr); }); tbl.style.display = ""; setStatus(`✅ Successfully parsed ${parsed.length} email(s)!`, "success"); byId("downloadBtn").disabled = parsed.length === 0; document.querySelector('[data-tab="preview"]').click(); } catch(err) { console.error("Parse error:", err); setStatus(`❌ Error: ${err.message}`, "error"); } }); // Download button byId("downloadBtn").addEventListener("click", () => { if(!parsed.length) { setStatus("❌ No emails to download", "error"); return; } const files = parsed.map((em, i) => { const start = Math.max(1, parseInt(byId("startNum").value || "1", 10)); const pad = Math.max(1, parseInt(byId("pad").value || "2", 10)); const pattern = byId("pattern").value || "Day {{num}} - Email Sequence Splitter.html"; const num = padNum(start + i, pad); const name = sanitizeFilename(pattern.replace(/{{\s*num\s*}}/g, num).replace(/{{\s*title\s*}}/g, em.title)); return {name, data: utf8Encode(em.html)}; }); const blob = buildZip(files); const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = "emails_split.zip"; a.click(); setTimeout(() => URL.revokeObjectURL(a.href), 4000); setStatus(`✅ ZIP downloaded with ${files.length} file(s)`, "success"); }); // Sample download button byId("dlSample").addEventListener("click", () => { const blob = buildZip([{name: "README.txt", data: utf8Encode("Your ZIP will appear here after parsing your HTML file.")}]); const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = "sample.zip"; a.click(); setTimeout(() => URL.revokeObjectURL(a.href), 4000); setStatus("✅ Sample ZIP downloaded", "success"); }); console.log("Email Sequence Splitter loaded successfully");

Back To Top
Pin
Tweet
Share
Share
Reddit
WhatsApp