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.
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 .
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>
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)
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.
Top comments (6)
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.
Cool idea. At a glance it seems most of those
let
could beconst
really nice tutorial, and easily understandable code for newbies too.πππ
Thanks. Glad you found it useful.
That screenshot would only cover the viewport, not the entire scrollable website.
I mean it cool but it takes screenshot of static website... Not the content shown on my screen...