How to create Thumbnail Downloader using JS and PHP


A YouTube thumbnail is the first thing users see when they come across a video. It plays a crucial role in determining whether a viewer clicks on the video or not. In this article, we'll walk you through creating a YouTube thumbnail downloader using JavaScript and PHP. This tool allows users to download thumbnails of YouTube videos by simply entering the video URL.

YouTube thumbnails are stored in a structured URL format, making it easy to retrieve them programmatically.

Step 1: Understanding Video URLs and Thumbnails

YouTube thumbnails are stored in a structured URL format, making it easy to retrieve them programmatically. A typical YouTube video URL looks like this:

https://www.youtube.com/watch?v=VIDEO_ID

The VIDEO_ID is a unique identifier for every video on YouTube. You can replace the VIDEO_ID in the YouTube thumbnail URL format to retrieve thumbnails. The standard thumbnail is URL format.


Alternatively, other sizes are available:
  • default.jpg: Default size (120x90 px)
  • mqdefault.jpg: Medium quality (320x180 px)
  • hqdefault.jpg: High quality (480x360 px)
  • sddefault.jpg: Standard definition (640x480 px)
Step 2: Creating the Interface

The first step is to create a simple interface where users can input the YouTube video URL and download the thumbnail.

✲    index.php
<?php
  if(isset($_POST['button'])){
    $imgUrl = $_POST['imgurl'];
    $ch = curl_init($imgUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $downloadImg = curl_exec($ch);
    curl_close($ch);
    header('Content-type: image/jpg');
    header('Content-Disposition: attachment;filename="thumbnail.jpg"');
    echo $downloadImg;
  }
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Thumbnail Downloader | Coding Zemigle</title>
  <link rel="stylesheet" href="style.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"/>
</head>
<body>
  <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
    <header>Thumbnail Downloader</header>
    <div class="url-input">
      <div class="field">
        <input type="text" placeholder="Enter or paste video URL" required>
        <input class="hidden-input" type="hidden" name="imgurl">
        <span class="bottom-line"></span>
      </div>
    </div>
    <div class="preview-area">
      <img class="thumbnail" src="" alt="">
      <i class="icon fas fa-cloud-download-alt"></i>
      <span>Paste video url to see preview</span>
    </div>
    <button class="download-btn" type="submit" name="button">Download</button>
  </form>

  <script>
    const urlField = document.querySelector(".field input"),
    previewArea = document.querySelector(".preview-area"),
    imgTag = previewArea.querySelector(".thumbnail"),
    hiddenInput = document.querySelector(".hidden-input"),
    button = document.querySelector(".download-btn");

    urlField.onkeyup = ()=>{
      let imgUrl = urlField.value;
      previewArea.classList.add("active");
      button.style.pointerEvents = "auto";
      if(imgUrl.indexOf("https://www.youtube.com/watch?v=") != -1){
        let vidId = imgUrl.split('v=')[1].substring(0, 11);
        let ytImgUrl = `https://img.youtube.com/vi/${vidId}/maxresdefault.jpg`;
        imgTag.src = ytImgUrl;
      }else if(imgUrl.indexOf("https://youtu.be/") != -1){
        let vidId = imgUrl.split('be/')[1].substring(0, 11);
        let ytImgUrl = `https://img.youtube.com/vi/${vidId}/maxresdefault.jpg`;
        imgTag.src = ytImgUrl;
      }else if(imgUrl.match(/\.(jpe?g|png|gif|bmp|webp)$/i)){
        imgTag.src = imgUrl;
      }else{
        imgTag.src = "";
        button.style.pointerEvents = "none";
        previewArea.classList.remove("active");
      }
      hiddenInput.value = imgTag.src;
    }
  </script>

</body>
</html>



Here, we've created an input field for users to enter the YouTube video URL and a button to trigger the download process. There's also an image tag to display the thumbnail preview.


This script listens for a button click, extracts the video ID from the entered URL, and then constructs the thumbnail URL. If the video ID is found, the thumbnail is displayed; otherwise, an error message is shown.

Step 3: Styling with CSS

While JavaScript handles the display of the thumbnail, we’ll use PHP to enable users to download the image. When the download button is clicked, the image will be sent to the server via an AJAX request, and PHP will handle the downloading.

✲    style.css
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Verdana", sans-serif;
}

body{
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: #1A3A3A;
}

form{
  width: 450px;
  background: #fff;
  padding: 20px 30px;
  border-radius: 5px;
  box-shadow: 10px 10px 13px rgba(0,0,0,0.1);
}

form header{
  text-align: center;
  font-size: 25px;
  font-weight: 500;
  margin-top: 10px;
  color: #1A3A3A;
}

form .url-input{
  margin: 30px 0;
}

.url-input .title{
  font-size: 18px;
  color: #1A3A3A;
}

.url-input .field{
  margin-bottom: 40px;
  height: 50px;
  width: 100%;
  position: relative;
}

.url-input .field input{
  height: 100%;
  width: 100%;
  border: none;
  outline: none;
  padding: 0 15px;
  font-size: 15px;
  background: #F1F1F7;
  border-bottom: 2px solid #ccc;
  font-family: 'Noto Sans', sans-serif;
}

.url-input .field input::placeholder{
  color: #b3b3b3;
}

.url-input .field .bottom-line{
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: #1A3A3A;
  transform: scale(0);
  transition: transform 0.3s ease;
}

.url-input .field input:focus ~ .bottom-line,
.url-input .field input:valid ~ .bottom-line{
  transform: scale(1);
}

form .preview-area{
  border-radius: 5px;
  height: 220px;
  display: flex;
  overflow: hidden;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  border: 2px dashed #1A3A3A;
}

.preview-area.active{
  border: none;
}

.preview-area .thumbnail{
  width: 100%;
  display: none;
  border-radius: 5px;
}

.preview-area.active .thumbnail{
  display: block;
}

.preview-area.active .icon,
.preview-area.active span{
  display: none;
}

.preview-area .icon{
  color: #1A3A3A;
  font-size: 80px;
}

.preview-area span{
  color: #1A3A3A;
  margin-top: 25px;
}

form .download-btn{
  color: #fff;
  height: 53px;
  width: 100%;
  outline: none;
  border: none;
  font-size: 17px;
  font-weight: 500;
  cursor: pointer;
  margin: 30px 0 20px 0;
  border-radius: 5px;
  background: #1A3A3A;
  pointer-events: none;
  transition: background 0.3s ease;
}

.download-btn:hover{
  background: #6616d0;
}

@media screen and (max-width: 460px){
  body{
    padding: 0 20px;
  }
  
  form header{
    font-size: 24px;
  }
  
  .url-input .field,
  form .download-btn{
    height: 45px;
  }
  
  form .download-btn{
    font-size: 15px;
  }
  
  form .preview-area{
    height: 130px;
  }
  
  .preview-area .icon{
    font-size: 50px;
  }
  
  .preview-area span{
    margin-top: 10px;
    font-size: 12px;
  }
}



This PHP script receives the videoId via a POST request, constructs the thumbnail URL, and forces the browser to download the image as a .jpg file.

In this updated JavaScript, we added an AJAX call to send the videoId to download.php, where PHP handles the actual downloading.

With this simple YouTube thumbnail downloader, users can enter a video URL, preview the thumbnail, and download it. The combination of JavaScript and PHP enables an interactive and smooth user experience. You can further improve the application by adding features like selecting different thumbnail sizes, improving error handling, and refining the UI.