Simple App Builder — exports a ZIP with a TTS-enabled app

Fill the fields below, then click Generate ZIP. The generated ZIP contains a ready-to-run HTML app with Text-to-Speech built-in.


Status: waiting

Generated app preview (index.html)



  
`; } genBtn.addEventListener('click', async ()=>{ const name = document.getElementById('appName').value || 'My TTS App'; const desc = document.getElementById('appDesc').value || ''; const color = document.getElementById('appColor').value || '#06b6d4'; const notes = document.getElementById('featNotes').checked; const recorder = document.getElementById('featRecorder').checked; const stt = document.getElementById('featSTT').checked; const zipName = document.getElementById('zipName').value || 'my-tts-app.zip'; status.textContent = 'Building zip...'; const zip = new JSZip(); const opts = {name, desc, color, notes, recorder, stt}; const index = makeIndexHTML(opts); zip.file('index.html', index); // add manifest const manifest = { name: name, short_name: name.slice(0,12), start_url: '.', display: 'standalone', background_color: '#061021', theme_color: color, icons: [{src:'icon.svg', sizes:'192x192', type:'image/svg+xml'}] }; zip.file('manifest.json', JSON.stringify(manifest, null, 2)); // add a simple icon const iconSvg = `${name.charAt(0)||'A'}`; zip.file('icon.svg', iconSvg); // create zip and offer download const content = await zip.generateAsync({type:'blob'}); const url = URL.createObjectURL(content); downloadArea.innerHTML = ''; const a = document.createElement('a'); a.href = url; a.download = zipName; a.textContent = 'Download ZIP — ' + zipName; a.style.display = 'inline-block'; a.style.marginTop = '8px'; downloadArea.appendChild(a); preview.textContent = index.slice(0, 2000) + (index.length>2000 ? "\n\n... (truncated)":""); status.textContent = 'Ready — ZIP generated in browser (no server).'; });