Solution 1 :

You can use puppeteer to load the page inside a headless chrome instance

  • Open the page and wait for it to load
  • Using page.evaluate return the dataUrl of the canvas
  • Convert the dataUrl to a buffer and write the result to a file
const puppeteer = require('puppeteer');
    const fs = require('fs');

    (async () => {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto('');

        const dataUrl = await page.evaluate(async () => {
            const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time));

            await sleep(5000);

            return document.getElementById('canvas').toDataURL();

        const data = Buffer.from(dataUrl.split(',').pop(), 'base64');

        fs.writeFileSync('image.png', data);
        await browser.close();

Problem :

I know one can use tools such as wget or curl to perform HTTP requests from the command line, or use HTTP client requests from various programming languages. These tools also support fetching images or other files that are referenced in the HTML code.

What I’m searching for is a mechanism that also executes the JavaScript of that web page that renders an image into an HTML canvas. I then want to extract that rendered image as an image file. The goal to achieve is to grab a time series of those images, e.g. weather maps or other diagrams that plot time-variant data into a constant DOM object, via a cron job.

I’d prefer a solution that works from a script. How could this be done?


Comment posted by Teemu

You’re running the Cron task on Node.js?

Comment posted by paux

I have control over the server where this runs, so Node.js is an option

Comment posted by jsdom

Take a look at

Comment posted by Stranger in the Q

why you cannot render this images separately from webpage logic?

Comment posted by paux

Sorry for the delay in accepting your answer, I finally came around to try this out and adapt it to my needs, as these were my first steps with plain Node.js. Your example works like a charm! In my case, the canvas didn’t have an id, but I could grab it using