McAPI - Screenshot API JavaScript / Node JS

JavaScript / Node sample code to capture website screenshots with the McAPI Screenshot REST API service.

Requirements: A free RapidAPI account. Replace YOUR_API_KEY in the snippets below with your RapidAPI key.

All samples below work with the free tier of the API, see RapidAPI McAPI Screenshot Listing for available plans.

See the overview page for a reference that lists all available parameters and error codes.

Take a screenshot using Node JS with request module

Although deprecated, the request module is still in wide use. In the first snippet, we take a screenshot of the Indiehackers website. The device is set to Default (=1024x768px). With the storeExternal option set to "false", the screenshot will be returned as a base64 encoded JPEG.

The source code:

// JavaScript
  
const request = require('request');

const options = {
  method: 'POST',
  url: 'https://mcapi-screenshot.p.rapidapi.com/',
  headers: {
    'content-type': 'application/json',
    'x-rapidapi-key': 'YOUR_API_KEY',
    'x-rapidapi-host': 'mcapi-screenshot.p.rapidapi.com',
  },
  body: {
    url: 'https://indiehackers.com',
    format: 'jpeg',
    storeExternal: 'false',
    devices: [ 'Default' ]
  },
  json: true
};

request(options, function (error, response, body) {
	if (error) throw new Error(error);

	console.log(body);
});

The response will be delivered as a JSON object in body, e.g.:

{
  service: "McAPI Screenshot Generator, https://mcapi.io",
  version: "V1",
  url: "https://indiehackers.com",
  screenshots: [
    {
      device: "Default",
      screenshot: "data:image/jpeg;base64,/9j/4AAQSkZJRgAB ... 9yXvZG0pSuhyP/9k="
    }
  ]
}

McAPI Screenshot API - Sample screenshot with JavaScript

The returned image from the Node JS request:

Image of McAPI Screenshot API Sample Screenshot Node JS

Create a screenshot using Node JS with axios module

A modern, promise based replacement for request is the axios module which is almost 100% source code compatible.

Here's the same API call as above with axios:

// JavaScript
  
var axios = require("axios").default;

var options = {
  method: 'POST',
  url: 'https://mcapi-screenshot.p.rapidapi.com/',
  headers: {
    'content-type': 'application/json',
    'x-rapidapi-key': 'YOUR_API_KEY',
    'x-rapidapi-host': 'mcapi-screenshot.p.rapidapi.com',
  },
  data: {
    url: 'https://indiehackers.com',
    format: 'jpeg',
    storeExternal: 'false',
    devices: [ 'Default' ]
  }
};

axios.request(options).then(function (response) {
	console.log(response.data);
}).catch(function (error) {
	console.error(error);
});

Specifying devices

The Screenshot API contains a built-in database of over one hundred predefined devices and screen sizes. To get a list of all devices use the listDevices option, like so:

// JavaScript
  
...

body: {
  listDevices: 'true',
}

...

The API will now return an array of all known devices:

{
  devices: [

    ...
  
    { name: "iPhone 12 mini", width: 375, height: 812 },
    { name: "iPhone 12 mini landscape", width: 812, height: 375 },
    { name: "iPhone 12", width: 390, height: 844 },
    { name: "iPhone 12 landscape", width: 844, height: 390 },
    { name: "iPhone 12 Pro", width: 390, height: 844 },
    { name: "iPhone 12 Pro landscape", width: 844, height: 390 },
    { name: "iPhone 12 Pro Max", width: 428, height: 926 },
    { name: "iPhone 12 Pro Max landscape", width: 926, height: 428 },

    ...
  ]
}

Internally, the API also maintains proper User Agent-strings for the respective device, not shown in the list.

Specifying a predefined device is simple, just use its name in the call:

// JavaScript
  
...

body: {
  url: 'https://mcapi.io',
  devices: [ 'iPhone 12' ]
}

...

The devices param is an array; to create multiple screenshots in batch mode, specify additional devices (max. five):

// JavaScript
  
...

body: {
  url: 'https://mcapi.io',
  devices: [ 'iPhone 12', 'iPhone 12 landscape' ]
}

...

Note that specifying multiple devices will cause the API to load the target URL for each device and then take a screenshot; this can take some time with heavy sites; see the discussion on timeouts.

Specifying viewports

If none of the predefined devices and screen sizes are suitable for your application, you can specify your own viewport:

// JavaScript
  
...

body: {
  url: 'https://mcapi.io',
  viewPort: { 'width': 800, 'height': 600 }
}

...

This will create a screenshot with 800x600px; if a viewport is specified, the API will use a generic desktop User agent-string when loading the target URL.

Note that the viewPort param is ignored if a devices array is also specified.

Cookie consent banners and ad blocking

If so desired, the API can also automatically click the "Accept" button on GDPR cookie consent banners (Note that this feature is currently experimental, discussion.)

Consider this screenshot of the CNBC website with default API settings. The site displays a very prominent banner:

Screenshot API - Cookie Consent Banner JavaScript Node JS

Set the cookie-param to "true" like so:

// JavaScript
  
...

body: {
  url: 'https://cnbc.com',
  cookie: 'true',
  devices: [ 'Default' ]
}

...

The screenshot now shows the site without the banner.

Screenshot API - Clicked Cookie Banner and Ad with JavaScript Node JS

Blocking ads in screenshots

While it can be useful to take screenshots with ads (for example to check ad placement or ad rotation), in many cases you will want them blocked. The screenshot API comes with a built-in ad blocker, activate it like so:

// JavaScript
  
...

body: {
  url: 'https://cnbc.com',
  cookie: 'true',
  adblock: 'true',
  devices: [ 'Default' ]
}

...

The website now without cookie warning and without ads:

Screenshot API - Clicked Cookie Banner and Ad blocked JavaScript Node JS

The header-parameter - writing screenshots to a file (JavaScript)

With the storeExternal option set to "false", the screenshot image is returned as a base64 encoded string. Per default, this string is preceded by a header that describes the media type (or MIME) of the string.

Sample data block for a screenshot, to be returned as a PNG:

// JavaScript

...

body: {
  url: 'https://mcapi.io', 
  storeExternal: 'false',
  format: 'png'
}

...

The result will look like this:

{
  service: "McAPI Screenshot Generator, https://mcapi.io",
  version: "V1",
  url: "https://mcapi.io",
  screenshots: [
    {
      device: "Default",
      screenshot: "data:image/png;base64,iVBORr/klmpqa2 ... 9yXvZG0pjjmSuhQmCC"
    }
  ]
}

You can now directly set the "screenshot"-string as the src property of an img tag, like so:

// JavaScript

...

if(result.statusCode == 200){
  // In real life you would iterate over the screenshots array
  let imageData = body.screenshots[0].screenshot;
  console.log('<img src="' + imageData + '"/>');
}
else{
  // error handling
}

...

The MIME header will make sure that the image data is interpreted correctly by the browser. However, when writing the image data to a JPEG or PNG file, including the header would result in an invalid file. To create a screenshot image without the header, set the header-parameter to "false", like so:

// JavaScript

...

body: {
  url: 'https://mcapi.io',
  storeExternal: 'false',
  format: 'png',
  header: 'false'
}

...

The returned screenshot image without header:

{
  service: "McAPI Screenshot Generator, https://mcapi.io",
  version: "V1",
  url: "https://mcapi.io",
  screenshots: [
    {
      device: "Default",
      screenshot: "iVBORr/klmpqa2 ... 9yXvZG0pjjmSuhQmCC"
    }
  ]
}

Now, all we have to do is decode the base64 string using a buffer and then write the screenshot to a file, shown here as a complete NodeJS program:

// JavaScript

const request = require('request');
const fs = require('fs')

const options = {
  method: 'POST',
  url: 'https://mcapi-screenshot.p.rapidapi.com/',
  headers: {
    'content-type': 'application/json',
    'x-rapidapi-key': 'YOUR_API_KEY',
    'x-rapidapi-host': 'mcapi-screenshot.p.rapidapi.com',
  },
  body: {
    url: 'https://indiehackers.com',
    format: 'png',
    storeExternal: 'false',
    header: 'false',
    devices: [ 'Default' ]
  },
  json: true
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);
  if(response.statusCode == 200){
    // In real life you would iterate over the screenshots array
    let imageData = body.screenshots[0].screenshot;
    var buffer = Buffer.from(imageData, 'base64');
    
    fs.writeFile('screenshot.png', buffer, err => {
      if (err) {
        // error handling
      }
    })
  }
  else{
    // error handling
  }
});


Back to McAPI Screenshot API main page.