Sending PDF from a post request in SvelteKit

Viewed 107

I have form data that I'm sending to my endpoint with a POST request and I'm trying to create a PDF with puppeteer and send it back as response.

My /generate endpoint code

import { launch } from 'puppeteer';

export async function post({ request }) {
    const browser = await launch({
        headless: true
    });

    const page = await browser.newPage();
    const html = `<div>Test</div>`;
    await page.setContent(html, {
        waitUntil: 'domcontentloaded'
    });

    const pdfBuffer = await page.pdf({
        format: 'A4'
    });

    await browser.close();

    return {
        headers: {
            'Content-Type': 'application/pdf'
        },
        status: 200,
        body: pdfBuffer
    };
}

And the following is my client-side javascript

try {
    const response = await fetch('/generate', {
        method: 'POST',
        // headers: {
        //  'Content-Type': 'application/json'
        // },
        body: JSON.stringify(values)
    });
    const abuffer = await response.arrayBuffer();
    const buffer = Buffer.from(new Uint8Array(abuffer));
    const buff = await sharp(buffer).toFormat('jpeg').toBuffer();
    let base64data = buff.toString('base64');
    
} catch (e) {
    console.log(e);
}

I'm getting a Buffer is undefined.. error trying this code.
Any help is appreciated, thanks

1 Answers

The main problem seems server-side. When you try to return application/pdf you should get the error:

Body returned from endpoint request handler must be a plain object

You could send the data as base 64 like this:

return {
    status: 200,
    body: {
        pdf: pdfBuffer.toString('base64'),
    }
};

Client:

const response = await fetch('/generate', {
    method: 'post',
    headers: {
        'Accept': 'application/json',
    },
})

const json = await response.json();

// Test download
const link = document.createElement('a');
link.href = `data:application/pdf;base64,${json.pdf}`;
link.download = 'puppeteer-pdf.pdf';
link.click();

If you are going to convert the PDF to an image anyway, I would recommend doing that directly on the server and just return the image.

Related