PDFKit library working in Express.js but not in Next.js API route

I'm working on a project where I need to generate PDFs using the pdfkit library. I've managed to get it working in an Express.js server, but I'm facing issues when trying to do the same in a Next.js API route.

Express.js Code (src/index.ts):

import express from 'express';
import PDFDocument from 'pdfkit';
const app = express();

app.get('/', (req, res) => {
  const doc = new PDFDocument();
  doc.text("hello hello hello HI");
  doc.end();
  doc.pipe(res);
});

const port = parseInt(process.env.PORT) || 3000;
app.listen(port, () => {
  console.log(`listening on port ${port}`);
});

This code works perfectly, generating the PDF as expected when I navigate to the root URL.

Next.js API Route (api/route.ts):

import PDFDocument from 'pdfkit';
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
  const doc = new PDFDocument();
  doc.text("hello hello hello HI");
  doc.end();
  doc.pipe(NextResponse);
}

In the Next.js API route, I'm trying to achieve the same functionality, but it's not working. When I navigate to the corresponding API route in the Next.js app, the PDF is not generated and I get an error.

What I've Tried:

  1. Verified that pdfkit is correctly installed and imported.
  2. Checked that the API route is correctly set up and accessible.

Question:

How can I generate a PDF using pdfkit in a Next.js API route? Is there a different approach I need to take compared to the Express.js implementation? Is there any option/system to generate the pdf in client browser?

Any help or pointers would be greatly appreciated.

Upvotes: 0

Views: 389

Answers (1)

Subha
Subha

Reputation: 1608

The problem is that NextResponse object from next.js isn't directly compatible with the pdfkit's piping mechanism. Instead, you need to gather the PDF content into a buffer and then send it as a response.

Try this following approach.

export async function GET(request: Request) {
  const doc = new PDFDocument();
  let buffers = [];

  //Collect the PDF data into a buffer
  doc.on('data', buffers.push.bind(buffers));
  doc.on('end', () => {
    const pdfData = Buffer.concat(buffers);
    return NextResponse.next(pdfData);
  });

  //content addition to PDF
  doc.text("hello hello hello HI");
  doc.end();
}

Try the above solution,I think it will work.

You can also check the official docs to know the other details/approach as well.

Upvotes: 0

Related Questions