Email Sequence Splitter – No-Code ZIP Export
📤 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
Numbering
HTML Structure
Content Processing
👁️ Preview
No file parsed yet. Upload a file and click "Parse & Preview" in the Options tab.
| # |
Email Title |
Strategy |
Size |
${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");