0

I'm new to Next.js, and I'm trying to use wkhtmltoimage but I can't seem to send the generated image stream as a response in my Next.js API.

const fs = require('fs')
const wkhtmltoimage = require('wkhtmltoimage').setCommand(__dirname + '/bin/wkhtmltoimage');


export default async function handler(req, res) {
  try {
    await wkhtmltoimage.generate('<h1>Hello world</h1>').pipe(res);
    
    res.status(200).send(res)
  } catch (err) {
    res.status(500).send({ error: 'failed to fetch data' })
  }
}

I know I'm doing plenty of stuff wrong here, can anyone point me to the right direction?

Bwrites
  • 103
  • 1
  • 3

1 Answers1

1

Since you're concatenating __dirname and /bin/wkhtmltoimage together, that would mean you've installed the wkhtmltoimage executable to ./pages/api/bin which is probably not a good idea since the pages directory is special to Next.js.

We'll assume you've installed the executable in a different location on your filesystem/server instead (e.g., your home directory). It looks like the pipe function already sends the response, so the res.status(200).send(res) line will cause problems and can be removed. So the following should work:

// ./pages/api/hello.js
const homedir = require("os").homedir();

// Assumes the following installation path:
//   - *nix:     $HOME/bin/wkhtmltoimage
//   - Windows:  $env:USERPROFILE\bin\wkhtmltoimage.exe
const wkhtmltoimage = require("wkhtmltoimage").setCommand(
  homedir + "/bin/wkhtmltoimage"
);

export default async function handler(req, res) {
  try {
    res.status(200);
    await wkhtmltoimage.generate("<h1>Hello world</h1>").pipe(res);
  } catch (err) {
    res.status(500).send({ error: "failed to fetch data" });
  }
}
Mark G
  • 1,868
  • 1
  • 6
  • 15
  • How do i setCommand when calling from node_modules? I have installed the npm version of the wkhtmltoimage – Bwrites Apr 05 '22 at 02:18
  • 1
    @Bwrites [node-wkhtmltoimage](https://github.com/timstudd/node-wkhtmltoimage) is only a wrapper for the executable and doesn't include it — unless you actually see a `bin` directory inside the `./node_modules/wkhtmltoimage` directory or the `wkhtmltoimage` executable inside the `./node_modues/.bin` directory? – Mark G Apr 05 '22 at 02:30
  • Oh! No, I don't actually see that. It's nowhere in `node_modules/bin` as well. Does a wrapper mean it allows you to use it in JS even if it's an exectuable? I get this error, btw `Error: spawn /node_modules/wkhtmltoimage ENOENT` does this mean all I have to do is install the executable, point to it, then I could finally use it in my application? – Bwrites Apr 05 '22 at 02:35
  • 1
    @Bwrites Yep, all you have to do is install it. The easiest way would be to download a prebuilt binary [here](https://wkhtmltopdf.org/downloads.html). Then install it to your `$HOME/bin` directory just to test it out against the code I posted up there (you could always move it elsewhere once you get the hang of it). – Mark G Apr 05 '22 at 02:37