Product Requirements Document (PRD) Generator

Product Requirements Document (PRD) Generator

Define your product's purpose, features, and functionality.

${data.releasePlan || 'Not specified.'}

`; html += `

5.2 Future Considerations

${data.futureConsiderations || 'Not specified.'}

`; document.getElementById('generated-prd-content').innerHTML = html; }; // --- PDF Generation --- downloadPdfBtn.addEventListener('click', () => { const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' }); const data = getPrdData(); const pageW = doc.internal.pageSize.getWidth(); const margin = 15; const maxW = pageW - margin * 2; let y = 0; const primaryColor = '#2563eb'; const textColor = '#334155'; // Helper to add header/footer const addHeaderFooter = () => { const pageCount = doc.internal.getNumberOfPages(); for (let i = 1; i <= pageCount; i++) { doc.setPage(i); // Header doc.setFontSize(9); doc.setTextColor(primaryColor); doc.text(data.productName, margin, 10); // Footer doc.setTextColor('#94a3b8'); doc.text(`Page ${i} of ${pageCount}`, pageW / 2, doc.internal.pageSize.getHeight() - 10, { align: 'center' }); } }; // --- Title Page --- doc.setFontSize(32); doc.setFont(undefined, 'bold'); doc.setTextColor(textColor); doc.text(data.productName, pageW / 2, 80, { align: 'center' }); doc.setFontSize(18); doc.setFont(undefined, 'normal'); doc.text('Product Requirements Document', pageW / 2, 95, { align: 'center' }); doc.setFontSize(12); const date = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); doc.text(`Date: ${date}`, pageW / 2, 120, { align: 'center' }); doc.text('Version: 1.0', pageW / 2, 128, { align: 'center' }); // --- Content Pages --- doc.addPage(); y = 20; const addH1 = (text) => { if (y > 250) { doc.addPage(); y = 20; } doc.setFontSize(16); doc.setFont(undefined, 'bold'); doc.setTextColor(primaryColor); doc.text(text, margin, y); y += 8; }; const addH2 = (text) => { if (y > 260) { doc.addPage(); y = 20; } doc.setFontSize(12); doc.setFont(undefined, 'bold'); doc.setTextColor(textColor); doc.text(text, margin, y); y += 6; }; const addBody = (text) => { if (y > 260) { doc.addPage(); y = 20; } doc.setFontSize(10); doc.setFont(undefined, 'normal'); doc.setTextColor(textColor); const lines = doc.splitTextToSize(text, maxW); doc.text(lines, margin, y); y += (lines.length * 4) + 4; }; // Content addH1('1. Overview'); addH2('1.1 Product Goals'); addBody(data.productGoals || 'Not specified.'); addH2('1.2 Success Metrics'); addBody(data.successMetrics || 'Not specified.'); addH1('2. Target Audience'); addBody(data.targetAudience || 'Not specified.'); addH1('3. User Stories'); y += 2; if (data.userStories.length > 0) { doc.autoTable({ body: data.userStories.map(s => [s]), startY: y, theme: 'grid', headStyles: { fillColor: primaryColor }, didDrawPage: (data) => y = data.cursor.y + 4, }); } else { addBody('No user stories added.'); } addH1('4. Features'); if (data.features.length > 0) { doc.autoTable({ head: [['Priority', 'Feature', 'Description']], body: data.features.map(f => [f.priority, f.name, f.desc]), startY: y, theme: 'striped', headStyles: { fillColor: primaryColor }, didDrawPage: (data) => y = data.cursor.y, }); } else { addBody('No features specified.'); } y += 10; addH2('4.x Out of Scope'); addBody(data.outOfScope || 'Not specified.'); addH1('5. Plan'); addH2('5.1 Release Plan'); addBody(data.releasePlan || 'Not specified.'); addH2('5.2 Future Considerations'); addBody(data.futureConsiderations || 'Not specified.'); addHeaderFooter(); doc.save(`${data.productName.replace(/\s+/g, '-')}-PRD.pdf`); }); // Initialize updateTabUI(0); addUserStory(); addFeature(); lucide.createIcons(); });
Scroll to Top