Build a Simple YouTube App with Vanilla JavaScript

Trending 3 months ago

The Tuts+ YouTube channel is accelerated approaching 1.5M subscribers. Let’s observe this awesome accomplishment by creating thing YouTube-oriented! We’re going to build a simple, yet afloat functional YouTube app pinch Vanilla JavaScript.

The conception will beryllium beautiful straightforward; we’ll build a elemental UI wherever we tin participate nan ID of a transmission and our app will return info astir it.

1. Scaffolding nan YouTube App

Before we commencement creating our app, location are a fewer things that we person to address.

Grab a YouTube API key

As a first and mandatory thing, we should get a YouTube API cardinal that will springiness america entree to nan YouTube Data API. To do so, we should travel nan instructions connected this page and group up a task successful nan Google Cloud Console pinch nan YouTube Data API v3 enabled. In my case, I’ve already done it while building nan app. Now, it’s your move to make an API and see it successful your forked demo.

this is nan api you needthis is nan api you needthis is nan api you need

For accumulation environments, retrieve that it’s ever wise to restrict nan API requests to circumstantial websites, IP addresses, etc.

Grab a Lottie Animation

Optionally, to make our app arsenic unsocial arsenic possible, we’ll drawback a Lottie animation from nan LottieFiles room and play it for channels pinch 1M aliases much subscribers. 

Confetti Lottie animationConfetti Lottie animationConfetti Lottie animation

First, we’ll make an plus nexus for this animation and customize it arsenic we wish.

Generating an plus nexus for this animationGenerating an plus nexus for this animationGenerating an plus nexus for this animation

As things move quickly, astatine this point, nan LottieFiles squad suggests utilizing the dotLottie record format alternatively of nan accepted Lottie JSON to trim nan record size.

Selecting nan dotLottie record format for nan animationSelecting nan dotLottie record format for nan animationSelecting nan dotLottie record format for nan animation

In our case, arsenic we’re utilizing a CodePen demo, we’ll import nan required .mjs record for illustration this:

1 import { DotLottiePlayer } from "";

Then, arsenic we’ll spot successful an upcoming section, we’ll see nan generated dotlottie-player constituent successful nan markup that represents nan transmission info.

Besides, if you request a refresher astir really to see Adobe After Effects animations connected a web page and Lottie Animations successful general, see nan pursuing tutorials:

2. Define nan Page Markup

Let’s now attraction connected nan app development.

We’ll only specify a conception that will see a heading, a hunt form, and an quiet span element.

We’ll group nan input constituent arsenic required and unit it to hold 24 characters to debar unnecessary AJAX requests. From my tests, I’ve seen that nan magnitude of a YouTube transmission ID is 24, though you tin update nan minlength and maxlength property values if you announcement thing different.

The span constituent will look pinch an due connection nether definite conditions. For example, if we hunt for a YouTube transmission ID that doesn’t beryllium aliases if, for immoderate reason, nan consequence is unsuccessful (i.e. 400 Bad Request, 404 Not Found, etc.). 

Along nan way, we’ll spot nan markup for nan transmission info that will beryllium generated dynamically. 

Here’s nan first page markup:

1 <section class="top-banner">
2 <div class="container">
3 <div class="text">
4 <h1>Simple App With nan YouTube API</h1>
5 <p class="label">Use <mark>UC8lxnUR_CzruT2KA6cb7p0Q</mark> for testing which refers to nan Envato Tuts+ transmission ID</p>
6 </div>
7 <form>
8 <input type="search" minlength="24" maxlength="24" placeholder="Insert a valid YT transmission ID" autofocus required>
9 <button type="submit">SUBMIT</button>
10 <span class="msg"></span>
11 </form>
12 </div>
13 </section>

The autofocus property of nan hunt section won’t activity unless you position nan CodePen demo successful debug mode.

Find a YouTube Channel ID

One speedy measurement to find nan ID of a YouTube transmission is done nan page source. First, navigate to nan desired transmission page, past position its root codification and hunt for The transmission ID will travel aft this guidelines URL.  

Envato Tuts+ Channel IDEnvato Tuts+ Channel IDEnvato Tuts+ Channel ID Envato Tuts+ Channel ID
Traversy Media Channel IDTraversy Media Channel IDTraversy Media Channel ID Traversy Media Channel ID

3. Set nan Main Styles

As this is simply a ample tutorial, for nan liking of simplicity, we’ll skip nan starting styles and only ore connected nan main ones—you tin position each of them by clicking nan CSS tab of nan demo.

Form Styles

On mean screens and supra (>700px), nan layout should look for illustration this:

The shape layout connected ample screensThe shape layout connected ample screensThe shape layout connected ample screens

On smaller screens, nan shape elements will divided into 2 lines:

The shape layout connected mobile screensThe shape layout connected mobile screensThe shape layout connected mobile screens

Here are nan associated styles:

3 .top-banner form {
4 position: relative;
5 display: grid;
6 grid-template-columns: 1fr auto;
7 grid-gap: 15px;
8 align-items: center;
9 justify-content: center;
10 max-width: 1000px;
11 }
13 .top-banner form input {
14 font-size: clamp(24px, 2vw, 32px);
15 height: 40px;
16 padding-bottom: 10px;
17 border-bottom: 1px solid currentColor;
18 }
20 .top-banner form input::placeholder {
21 opacity: 1;
22 color: var(--white);
23 }
25 .top-banner form button {
26 font-weight: bold;
27 padding: 15px 30px;
28 border-radius: 5px;
29 background: var(--red);
30 transition: background 0.3s ease-in-out;
31 }
33 .top-banner form button:hover {
34 background: var(--darkred);
35 }
37 .top-banner form .msg {
38 position: absolute;
39 top: 100%;
40 left: 0;
41 }
43 @media (max-width: 700px) {
44 .top-banner form {
45 grid-template-columns: 1fr;
46 }
48 .top-banner form .msg {
49 position: static;
50 }
51 }

Channel Styles

As soon arsenic we successfully get backmost from nan server info for a channel, they will look successful a paper layout for illustration this:

The transmission infoThe transmission infoThe transmission info

The styles aren’t thing excessively complicated, truthful we won’t spell into much item astatine this point:

3 .card {
4 padding: 4%;
5 text-align: center;
6 margin-top: 70px;
7 color: var(--white);
8 background: var(--total-black);
9 border-radius: 7px;
10 overflow: hidden;
11 }
13 .card .details img {
14 border-radius: 50%;
15 }
17 .card .details .title {
18 margin-top: 10px;
19 }
21 .card .details .description {
22 max-width: 80%;
23 margin: 30px auto 0;
24 }
26 .card .total-videos {
27 position: relative;
28 z-index: 1;
29 margin-top: 30px;
30 }
32 .card .total-subscribers {
33 position: relative;
34 display: inline-grid;
35 grid-template-columns: auto auto;
36 grid-gap: 10px;
37 align-items: center;
38 font-weight: bold;
39 margin-top: 60px;
40 background: var(--red);
41 }
43 .card .total-subscribers dotlottie-player {
44 position: absolute;
45 top: 50%;
46 left: 50%;
47 transform: translate(-50%, -50%);
48 }
50 .card .total-subscribers .outer {
51 padding: 10px;
52 }
54 .card .total-subscribers svg {
55 fill: var(--red);
56 background: var(--white);
57 padding: 5px;
58 box-sizing: content-box;
59 }

4. Add nan JavaScript

At this moment, we’re fresh to build nan halfway functionality of our YouTube app. Let’s do it!

On Form Submission

Each clip a personification submits nan shape by pressing nan Enter cardinal aliases nan Submit button, we’ll do 2 things:

  1. Stop nan shape from submitting, hence forestall reloading nan page.
  2. Grab nan worth that is contained successful nan hunt field.

Here’s nan starting code:

1 const topBanner = document.querySelector(".top-banner");
2 const form = topBanner.querySelector("form");
3 const input = topBanner.querySelector("input");
5 form.addEventListener("submit", (e) => {
6 e.preventDefault();
7 const channelId = input.value;
8 });

Perform an AJAX Request

Before we spell done nan AJAX request, it’s important to publication nan docs and understand really to building it. In our case, we want to get transmission info, truthful we’ll attraction connected nan channel endpoint and walk nan pursuing parameters:

  1. The portion parameter pinch values nan snippet and statistic names. 
  2. The API key. Again, you should usage your ain key.
  3. The transmission ID we’re willing to get info. In a erstwhile section, we covered a measurement to find nan ID of an existing channel.

We tin moreover research pinch nan HTTP requests done nan helper instrumentality that is disposable connected nan correct broadside of this page

Experiment pinch a trial requestExperiment pinch a trial requestExperiment pinch a trial request

With each nan supra successful mind, our petition URL should look thing for illustration this:

1 const BASE_URL =",snippet";
2 const API_KEY = "AIzaSyAHupLf37J-vEziyQ-pItfoaLS5XUqdVq8";
3 const channelID = input.value;
5 const url = `${BASE_URL}&id=${channelId}&key=${API_KEY}`;

We’ll usage nan Fetch API to execute nan AJAX request—I presume you’re acquainted pinch this technique. There’s besides a series if you request a refresher. As discussed previously, we’ll adhd due correction handling for unsuccessful cases. For example, if we hunt for a non-existing transmission aliases nan position petition hasn’t succeeded.

An illustration of correction handlingAn illustration of correction handlingAn illustration of correction handling

So, our AJAX petition would look thing for illustration this:

1 ...
3 form.addEventListener("submit", (e) => {
4 ...
6 fetchYTStatistics(channelId)
7 .then((data) => {
8 if (typeof data.items !== "undefined") {
9 createCard(data);
10 } else {
11 msg.textContent = "Please hunt for a valid YT transmission ID 😩";
12 }
13 })
14 .catch((error) => {
15 msg.textContent = error;
16 });
17 });
19 async function fetchYTStatistics(channelId) {
20 const url = `${BASE_URL}&id=${channelId}&key=${API_KEY}`;
21 const response = await fetch(url);
23 if (!response.ok) {
24 return Promise.reject(
25 `Something isn't moving arsenic expected. Error: ${response.status}`
26 );
27 }
28 const data = await response.json();
29 return data;
30 }

Here’s an illustration of nan consequence data:

An illustration of nan consequence dataAn illustration of nan consequence dataAn illustration of nan consequence data

Build nan Card

With nan AJAX petition successful place, each clip we type a transmission ID successful nan hunt field, nan API will return transmission information if they are available. We’ll past cod only nan required information and connect it to nan page arsenic a paper component.

The transmission infoThe transmission infoThe transmission info

Two things to statement here:

  • The Lottie animation will play only if nan transmission subscribers are astatine slightest 1M.
  • We’ll usage nan NumberFormat API to format nan numbers related to nan transmission videos and subscribers. 
  • The outer links won’t activity unless you position nan CodePen demo successful debug mode.

Here’s nan codification responsible for this job:

1 function createCard(data) {
2 const allData = data.items[0];
3 const { customUrl, title, description, thumbnails } = allData.snippet;
4 const { default: thumbnail } = thumbnails;
5 const { videoCount, subscriberCount } = allData.statistics;
6 const div = document.createElement("div");
7 div.classList.add("card", "container");
9 const markup = `
10 <div class="details">
11 <img width="${thumbnail.width}" height="${thumbnail.height}" src="${thumbnail.url}" alt="${title}">
12 <div class="title">
13 <a href="${customUrl}" target="_blank">${title}</a>
14 </div>
15 <p class="description">${description}</p>
16 </div>
17 <div class="total-videos">
18 <a href="${customUrl}/videos" target="_blank">Browse</a>
19 <span class="count">${formatNumber(videoCount)}</span> videos
20 </div>
21 <div class="total-subscribers">
22 ${
23 subscriberCount >= 1000000
24 ? `<dotlottie-player src="" background="transparent" speed="1" style="width: 300px; height: 300px;" loop autoplay></dotlottie-player>`
25 : ""
26 }
27 <span class="outer">
28 <span class="count">${formatNumber(subscriberCount)}</span>
29 Subscribers
30 </span>
31 <svg xmlns="" width="40" height="40" viewBox="0 0 24 24">
32 <path d="M4.652 0h1.44l.988 3.702.916-3.702h1.454l-1.665 5.505v3.757h-1.431v-3.757l-1.702-5.505zm6.594 2.373c-1.119 0-1.861.74-1.861 1.835v3.349c0 1.204.629 1.831 1.861 1.831 1.022 0 1.826-.683 1.826-1.831v-3.349c0-1.069-.797-1.835-1.826-1.835zm.531 5.127c0 .372-.19.646-.532.646-.351 0-.554-.287-.554-.646v-3.179c0-.374.172-.651.529-.651.39 0 .557.269.557.651v3.179zm4.729-5.07v5.186c-.155.194-.5.512-.747.512-.271 0-.338-.186-.338-.46v-5.238h-1.27v5.71c0 .675.206 1.22.887 1.22.384 0 .918-.2 1.468-.853v.754h1.27v-6.831h-1.27zm2.203 13.858c-.448 0-.541.315-.541.763v.659h1.069v-.66c.001-.44-.092-.762-.528-.762zm-4.703.04c-.084.043-.167.109-.25.198v4.055c. 0-2.814.192-3.146 1.892-3.167 6.367.021 4.467.35 6.175 3.167 6.367 2.6.177 11.062.177 13.666 0 2.814-.192 3.146-1.893 3.167-6.367-.021-4.467-.35-6.175-3.167-6.367zm-12.324 10.686h-1.363v-7.54h-1.41v-1.28h4.182v1.28h-1.41v7.54zm4.846 0h-1.21v-.718c-.223.265-.455.467-.696.605-.652.374-1.547.365-1.547-.955v-5.438h1.209v4.988c0 .262.063.438.322.438.236 0 .564-.303.711-.487v-4.939h1.21v6.506zm4.657-1.348c0 .805-.301 1.431-1.106 1.431-.443 0-.812-.162-1.149-.583v.5h-1.221v-8.82h1.221v2.84c.273-.333.644-.608 1.076-.608.886 0 1.18.749 1.18 1.631v3.609zm4.471-1.752h-2.314v1.228c0 .488.042.91.528.91.511 0 .541-.344.541-.91v-.452h1.245v.489c0 1.253-.538 2.013-1.813 2.013-1.155 0-1.746-.842-1.746-2.013v-2.921c0-1.129.746-1.914 1.837-1.914 1.161 0 1.721.738 1.721 1.914v1.656z" />
33 </svg>
34 </div>
35 `;
37 div.innerHTML = markup;
38 document.body.appendChild(div);
39 }
41 function formatNumber(number) {
42 return new Intl.NumberFormat("en", {
43 notation: "compact"
44 }).format(number);
45 }

The generated markup arsenic it’s rendered successful nan browser console:

The paper markupThe paper markupThe paper markup

Reset Things

Lastly, aft nan AJAX request, we’ll do nan following:

  • Remove nan .card constituent from nan page.
  • Clear nan contented of nan .msg element.
  • Clear nan worth of nan hunt section and springiness attraction to that field.

Here’s nan related code:

1 ...
3 if (document.querySelector(".card")) {
4 document.querySelector(".card").remove();
5 }
6 msg.textContent = "";
7 form.reset();
8 input.focus();

Your YouTube App Is Ready!

Done, folks! This really was rather a agelong journey, truthful acknowledgment for pursuing along! I dream you enjoyed nan extremity consequence and that helped you study immoderate caller things.

Once again, don’t hide to put your ain cardinal for unrecorded app testing!

As a reminder, let’s look again astatine nan app:

As always, acknowledgment a batch for reading!

Next Steps

There are truthful galore things that you tin do to widen nan functionality of this YouTube app. Here are immoderate thoughts:

  • Create different conception to show nan latest transmission videos.
  • Instead of showing conscionable a transmission each time, modify nan codification to show aggregate transmission info simultaneously successful a grid format, arsenic we did pinch nan upwind app.

If there’s thing other that you mightiness want to spot arsenic an app extension, fto america cognize connected X aliases successful nan demo comments!

Discover More JavaScript Tutorials and Resources

Interested successful practicing modern JavaScript done nosy hands-on projects? If so, cheque retired these JavaScript tutorials: 

Source Tuts Plus
Tuts Plus