Blog Meta Description Generator
Create compelling, SEO-friendly meta descriptions for your articles.
Please provide a title and summary to generate descriptions.
'; return; } // Variation 1: Keyword-driven if(keywords.length > 0) { let desc1 = `Looking for ${keywords[0]} tips? Our guide on "${truncate(title, 50)}" covers everything from ${keywords.slice(1).join(', ')} to advanced strategies. ${cta || 'Learn more!'}`; generatedDescriptions.push(truncate(desc1, 160)); } // Variation 2: Question-based let desc2 = `Want to master ${keywords[0] || 'your topic'}? This post breaks down ${truncate(title, 70)}. Get actionable insights and expert advice. ${cta || 'Read now!'}`; generatedDescriptions.push(truncate(desc2, 160)); // Variation 3: Benefit-driven let desc3 = `${summary.split('.')[0]}. Dive into our comprehensive guide on "${truncate(title, 60)}" to unlock secrets and improve your skills. ${cta || 'Discover the guide!'}`; generatedDescriptions.push(truncate(desc3, 160)); // Variation 4: Direct approach let desc4 = `Explore "${truncate(title, 80)}". This article provides an in-depth look at ${keywords.join(', ')} and more. A must-read for anyone interested in the topic.`; generatedDescriptions.push(truncate(desc4, 160)); displayResults(); }; const displayResults = () => { if(generatedDescriptions.length === 0) { resultsContainer.innerHTML = ''; downloadSection.classList.add('hidden'); return; }; let html = 'Generated Options
';
generatedDescriptions.forEach((desc, index) => {
const len = desc.length;
const charCountClass = len <= 160 ? 'char-count-good' : 'char-count-warn';
html += `
`;
});
html += '
';
resultsContainer.innerHTML = html;
downloadSection.classList.remove('hidden');
// Add event listeners to new copy buttons
document.querySelectorAll('.copy-btn').forEach(button => {
button.addEventListener('click', (e) => copyToClipboard(e.target));
});
};
const copyToClipboard = (button) => {
const targetId = button.dataset.target;
const textToCopy = document.getElementById(targetId)?.innerText;
if(textToCopy) {
// Using document.execCommand for broader compatibility within iFrames
const textArea = document.createElement("textarea");
textArea.value = textToCopy;
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand('copy');
button.textContent = 'Copied!';
setTimeout(() => { button.textContent = 'Copy'; }, 2000);
} catch (err) {
console.error('Failed to copy text: ', err);
button.textContent = 'Error';
}
document.body.removeChild(textArea);
}
};
const downloadPDF = () => {
if (generatedDescriptions.length === 0) return;
const { jsPDF } = window;
const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' });
const postTitle = getInput('postTitle');
const PAGE_WIDTH = pdf.internal.pageSize.getWidth();
const MARGIN = 50;
let y = MARGIN;
// Header
pdf.setFontSize(22);
pdf.setFont('helvetica', 'bold');
pdf.text('Blog Meta Description Options', PAGE_WIDTH / 2, y, { align: 'center' });
y += 20;
pdf.setFontSize(12);
pdf.setFont('helvetica', 'normal');
pdf.setTextColor(100, 100, 100);
const titleLines = pdf.splitTextToSize(`For Blog Post: "${postTitle}"`, PAGE_WIDTH - MARGIN*2);
pdf.text(titleLines, PAGE_WIDTH / 2, y, { align: 'center' });
y += titleLines.length * 14 + 40;
// Descriptions
generatedDescriptions.forEach((desc, index) => {
const textBlockHeight = pdf.splitTextToSize(desc, PAGE_WIDTH - MARGIN*2 - 20).length * 12 + 40;
if (y + textBlockHeight > pdf.internal.pageSize.getHeight() - MARGIN) {
pdf.addPage();
y = MARGIN;
}
pdf.setFontSize(14);
pdf.setFont('helvetica', 'bold');
pdf.setTextColor(0, 0, 0);
pdf.text(`Option ${index + 1}`, MARGIN, y);
y += 20;
pdf.setFontSize(11);
pdf.setFont('helvetica', 'normal');
pdf.setTextColor(50, 50, 50);
const descLines = pdf.splitTextToSize(desc, PAGE_WIDTH - MARGIN*2 - 20);
pdf.text(descLines, MARGIN + 10, y);
y += descLines.length * 12 + 5;
pdf.setFontSize(9);
pdf.setFont('helvetica', 'italic');
pdf.setTextColor(150, 150, 150);
pdf.text(`Character count: ${desc.length}`, MARGIN + 10, y);
y += 30;
});
pdf.save(`Meta_Descriptions_${postTitle.replace(/ /g, '_').substring(0,20)}.pdf`);
};
// --- EVENT LISTENERS ---
generateBtn.addEventListener('click', generateDescriptions);
downloadPdfBtn.addEventListener('click', downloadPDF);
});
${desc}
${len} characters
