How to build a screenshot downloader app with plain JavaScript in 10 minutes

Post by
Andrew Pierno
How to build a screenshot downloader app with plain JavaScript in 10 minutes

Recently I stumbled across a cool tool for taking instant screenshots from any website.

ScreenshotAPI is an API tool that allows you to capture and render a screenshot of any website by making a single API query from your script.

I found that quite interesting, so I decided to build something based on such a feature.

In this tutorial, we will be building a screenshot downloader app from scratch, making use of HTML, CSS, JavaScript, and the screenshot API.

ezgif.com-gif-maker (4).gif

You can instantly grab the code for this project from CodePen

Create an account on ScreenshotAPI and get a token

To proceed, we will be needing an API token for executing the query. To obtain your token, you will be required to sign up first.

Sign Up for Screenshot API

Go ahead and sign up. You will also be instructed to validate your email, so make sure to do that (check the spam folder as well)

After the email validation process, you will be moved to the dashboard from your profile. There you will find your API key. Copy and preserve the API token.

HTML Markup for the Screenshot Taking App

Create an index.html file, create the boilerplate code (!+tab in emmet) and use the markup below inside the body tags:

<!DOCTYPE html>

<html lang="en">

<head>

   <meta charset="UTF-8">

   <meta http-equiv="X-UA-Compatible" content="IE=edge">

   <meta name="viewport" content="width=device-width, initial-scale=1.0">

   <title>Screenshot Downloader</title>

   <link rel="stylesheet" href="styles.css">

   <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" integrity="sha512-YWzhKL2whUzgiheMoBFwW8CKV4qpHQAEuvilg9FAn5VJUDwKZZxkJNuGM4XkWuk94WCrrwslk8yWNGmY1EduTA==" crossorigin="anonymous" referrerpolicy="no-referrer" />

</head>

<body>

 <div class="container">

   <div class="form">

     <div class="title flex">

       <h1 id="title">Screenshot Downloader</h1>

       <i class="fa fa-camera-retro fa-2x" aria-hidden="true"></i>

     </div>

     <input id="url" type="text" placeholder="Enter url to screenshot">

     <button id="btn" type="submit">Take Screenshot</button>

   </div>

   <div class="image">

     Wait for your screenshot to appear below.

     <span class="reference"></span>

   </div>

 </div>

   <script src="script.js" type="text/javascript"></script>

</body>

</html>

NOTE: We are using Font Awesome for the camera icon

The entire app goes into a container. In the form, we have a title, text input, and button. We use .flex class to display both children h1 and i side-by-side.

After the form, we have the section for the image. At the moment, the div is empty. However, when a URL is submitted and a screenshot is returned, this div will be populated by that screenshot image.

The <span> tag is just for reference. We will use it to specify where to insert the image from JavaScript.

Finally, we link to our JavaScript file. And here is the look of our page (without styling)

App without CSS

Styling The App

The styling is quite straight-forward. I have included some comments to explain what each of them do.

/* Align the body to the center. Align all text within the body to center as well. Set background-color to light blue */

body{

 font-family: "rubik", sans-serif;

 display: flex;

 align-items: center;

 text-align: center;

 justify-content: center;

 background-color: #ADD8E6;

}

/* Change the color of the icon to grey */

i {

 color: grey;

 margin: 0 1rem;

}

/* Ensure that containing box is at the center. Set a max-width so content doesn't burst out of container */

.container {

 margin: 50px auto;

 max-width: 1100px;

}

/* Set height of image container to 50 percent of browser window's height and width to 40 percent of window's width. Sets backround to white. Make the border rounder, and increase font size */

.image {

 margin-top: 10vh;

 height: 50vh;

 width: 40vw;

 font-size: 2rem;

 background-color: white;

 border-radius: 6px;

}

/* Create a class for the eventual screenshot image. This image will not be present at the start. The class will be passed to the new image from JavaScript */

.screenshot {

 height: 100%;

 width: 100%;

}

/* Display title and icon side by side */

.flex {

 display: flex;

 align-items: center;

 justify-content: center;

}

/* Set padding, margin and font-size. Removes border line and make border rounder */

#url {

 padding: .7rem .7rem;

 margin: .3rem .3rem;

 font-size: 1rem;

 border: none;

 border-radius: 6px;

}

/* Same styles with input. Set cursor to pointer and background to blue */

#btn {

 padding: .7rem .7rem;

 margin: .3rem .3rem;

 background-color: blue;

 border: none;

 font-size: 1rem;

 border-radius: 6px;

 color: white;

 cursor: pointer;

}

Implement Screenshot functionality with JavaScript

First in our script will be an async function called loadImage(). As you might have guessed, this function will be responsible for generating the screenshot.

async function loadImage() {

// get url value from from field and token from dashboard. Construct URL

 let formUrl = document.getElementById('url').value

 let token = "GA0KVYA-EQ94WNV-GKMC33C-3JZKQ3F"

 let url = `https://shot.screenshotapi.net/screenshot?token=${token}&url=${formUrl}`

// Make a get request to screenshotnet API and get response object

 const response = await fetch(url)

 const object = await response.json()

 //create a new image element

 let newImg = document.createElement('img')

 // set class on that element

 newImg.className= 'screenshot'

// set src property with the images' url from response object

 newImg.setAttribute('src', object.screenshot)

// get the nodes where you want to insert the new image

 let container = document.querySelector('.image')

 let reference = document.querySelector('.reference')

/* check if an image already exists. if so, simply replace that image. if not, then insert the new image before the reference element (<span>) */

 if (document.images.length >= 1 ) {

     let existingImg = document.querySelector('.screenshot')

     container.replaceChild(newImg, existingImg)

 } else {

     container.insertBefore(newImg, reference)

 }

}

NOTE: Comments are for code explanation. They are not part of the executable code

Finally, we add an event listener to the button. When it gets clicked, we want to try loading the screenshot.

// Get reference to button

let button = document.getElementById('btn')

// add event listener, run an async function when button gets clicked

button.addEventListener("click", async (event) => {

   // prevent from submission

   event.preventDefault()

   try {

     loadImage()

   } catch(e) {

     console.log("Error!");

     console.log(e);

   }

})

You can get the full code from Codepen

Summary

So in this tutorial, we built a screenshot-taking app with some HTML, CSS, and JavaScript.

In the script, we make a query to screenshots API passing in our desired website to the URL parameter as well as the API token to the token parameter. The API responds with an object from which we can obtain the screenshot URL and render using JavaScript.

I hope you enjoyed this tutorial. You can check out the code and tweak it to your taste.

Thanks for following along.