Backend
If you add the path option to the page.pdf() it will save directly to the disk where the server is hosted.
Frontend
If you return the pdf buffer from the server page.pdf() and send it to client / front-end. You will have to process the pdf.
...
const pdfBuffer = await page.pdf({
printBackground: true,
format: 'A4',
});
res.send(pdfBuffer);
...
Say you have a route /download which will return the pdf buffer from puppeteer's page.pdf() option. And on front-end you have a button with id 'download` to process the stream. Here's how you would do it
- Processing the buffer
- Creating an ObjectURL with that buffer.
- Create an
a tag which points the href to the object url.
- Add download attribute and mimic a fake click to that link.
- Binding the download button to the handler function's 'click' event.
Code
function handleClick() {
fetch('/download')
.then((res) => res.blob()) // --- 1.
.then((readableStream) => {
const blob = new Blob([readableStream], { type: 'application/pdf' }); // --- 1.
blobToSaveAs('invoice', blob); // --- 2.
})
.catch((e) => console.error(e));
}
function blobToSaveAs(fileName, blob) {
try {
const url = window.URL.createObjectURL(blob); // --- 2.
const link = document.createElement('a'); // --- 3.
if (link.download !== undefined) {
link.setAttribute('href', url); // --- 3.
link.setAttribute('download', fileName); // --- 4.
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click(); // --- 4.
document.body.removeChild(link);
}
} catch (e) {
console.error('BlobToSaveAs error', e);
}
}
document.getElementById('download').addEventListener('click', handleClick); // --- 5.