DEV Community

Cover image for Build a screenshot downloader app with plain JavaScript in 10 minutes
Kingsley Ubah
Kingsley Ubah

Posted on

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 which allows you 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 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 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>

Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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)
  }

}

Enter fullscreen mode Exit fullscreen mode

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);
    }
})
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (6)

Collapse
 
supportic profile image
Supportic

I mean it's a cool coding project where you learn to deal with API calls and such but you can also open devtools of the browser, press ctrl+shift+p to open command palette, type Screenshot and there you go.

Collapse
 
rtpharry profile image
Matthew Harris

Cool idea. At a glance it seems most of those let could be const

Collapse
 
jriffs profile image
Jedi of JavaScript

really nice tutorial, and easily understandable code for newbies too.πŸ‘πŸ‘πŸ‘Œ

Collapse
 
ubahthebuilder profile image
Kingsley Ubah

Thanks. Glad you found it useful.

Collapse
 
supportic profile image
Supportic

That screenshot would only cover the viewport, not the entire scrollable website.

Collapse
 
sushant0625 profile image
Sushant Gupta

I mean it cool but it takes screenshot of static website... Not the content shown on my screen...