The Tuts+ YouTube channel is quick approaching 1.5M subscribers. Let’s have a good time this nice achievement by creating one thing YoutTube-oriented! We’re going to construct a easy, but absolutely purposeful YouTube app with Vanilla JavaScript.
The idea can be fairly simple; we’ll construct a easy UI the place we will enter the ID of a channel and our app will return information about it.
1. Scaffolding the YouTube App
Earlier than we begin creating our app, there are some things that we now have to deal with.
Seize a YouTube API key
As a primary and necessary factor, we should always get a YouTube API key that may give us entry to the YouTube Information API. To take action, we should always comply with the directions on this page and arrange a mission within the Google Cloud Console with the YouTube Information API v3 enabled. In my case, I’ve already achieved it whereas constructing the app. Now, it’s your flip to generate an API and embody it in your forked demo.
For manufacturing environments, keep in mind that it’s all the time sensible to limit the API requests to particular web sites, IP addresses, and so forth.
Seize a Lottie Animation
Optionally, to make our app as distinctive as attainable, we’ll seize a Lottie animation from the LottieFiles library and play it for channels with 1M or extra subscribers.
First, we’ll generate an asset hyperlink for this animation and customise it as we want.
As issues transfer shortly, at this level, the LottieFiles staff suggests utilizing the dotLottie file format as an alternative of the standard Lottie JSON to scale back the file dimension.
In our case, as we’re utilizing a CodePen demo, we’ll import the required .mjs
file like this:
1 |
import { DotLottiePlayer } from "https://webdesign.tutsplus.com/https://unpkg.com/@dotlottie/player-component@newest/dist/dotlottie-player.mjs"https://webdesign.tutsplus.com/; |
Then, as we’ll see in an upcoming part, we’ll embody the generated dotlottie-player
part within the markup that represents the channel information.
Moreover, should you want a refresher about how one can embody Adobe After Results animations on an online web page and Lottie Animations generally, contemplate the next tutorials:
2. Outline the Web page Markup
Let’s now concentrate on the app growth.
We’ll solely outline a piece that may embody a heading, a search kind, and an empty span
ingredient.
We’ll set the enter
ingredient as required and drive it to attend 24 characters to keep away from pointless AJAX requests. From my assessments, I’ve seen that the size of a YouTube channel ID is 24, though you possibly can replace the minlength
and maxlength
attribute values should you discover one thing completely different.
The span
ingredient will seem with an acceptable message below sure situations. For instance, if we seek for a YouTube channel ID that doesn’t exist or if, for some motive, the response is unsuccessful (i.e. 400 Dangerous Request, 404 Not Discovered, and so forth.).
Alongside the best way, we’ll see the markup for the channel information that can be generated dynamically.
Right here’s the preliminary web page markup:
1 |
<part class="top-banner"https://webdesign.tutsplus.com/> |
2 |
<div class="container"https://webdesign.tutsplus.com/> |
3 |
<div class="textual content"https://webdesign.tutsplus.com/> |
4 |
<h1>Easy App With the YouTube API</h1> |
5 |
<p class="label"https://webdesign.tutsplus.com/>Use <mark>UC8lxnUR_CzruT2KA6cb7p0Q</mark> for testing which refers back to the Envato Tuts+ channel ID</p> |
6 |
</div>
|
7 |
<kind>
|
8 |
<enter kind="search" minlength="24" maxlength="24" placeholder="Insert a sound YT channel ID" autofocus required> |
9 |
<button kind="submit"https://webdesign.tutsplus.com/>SUBMIT</button> |
10 |
<span class="msg"https://webdesign.tutsplus.com/></span> |
11 |
</kind>
|
12 |
</div>
|
13 |
</part>
|
Discover a YouTube Channel ID
One fast technique to discover the ID of a YouTube channel is thru the web page supply. First, navigate to the specified channel web page, then view its supply code and seek for https://www.youtube.com/channel/
. The channel ID will come after this base URL.
3. Set the Fundamental Types
As this can be a massive tutorial, for the sake of simplicity, we’ll skip the beginning kinds and solely think about the primary ones—you possibly can view all of them by clicking the CSS tab of the demo.
Kind Types
On medium screens and above (>700px), the structure ought to seem like this:
On smaller screens, the shape components will cut up into two strains:
Listed below are the related kinds:
1 |
/*CUSTOM VARIABLES HERE*/
|
2 |
|
3 |
.top-banner kind { |
4 |
place: relative; |
5 |
show: grid; |
6 |
grid-template-columns: 1fr auto; |
7 |
grid-gap: 15px; |
8 |
align-items: heart; |
9 |
justify-content: heart; |
10 |
max-width: 1000px; |
11 |
}
|
12 |
|
13 |
.top-banner kind enter { |
14 |
font-size: clamp(24px, 2vw, 32px); |
15 |
top: 40px; |
16 |
padding-bottom: 10px; |
17 |
border-bottom: 1px strong currentColor; |
18 |
}
|
19 |
|
20 |
.top-banner kind enter::placeholder { |
21 |
opacity: 1; |
22 |
colour: var(--white); |
23 |
}
|
24 |
|
25 |
.top-banner kind button { |
26 |
font-weight: daring; |
27 |
padding: 15px 30px; |
28 |
border-radius: 5px; |
29 |
background: var(--red); |
30 |
transition: background 0.3s ease-in-out; |
31 |
}
|
32 |
|
33 |
.top-banner kind button:hover { |
34 |
background: var(--darkred); |
35 |
}
|
36 |
|
37 |
.top-banner kind .msg { |
38 |
place: absolute; |
39 |
prime: 100%; |
40 |
left: 0; |
41 |
}
|
42 |
|
43 |
@media (max-width: 700px) { |
44 |
.top-banner kind { |
45 |
grid-template-columns: 1fr; |
46 |
}
|
47 |
|
48 |
.top-banner kind .msg { |
49 |
place: static; |
50 |
}
|
51 |
}
|
Channel Types
As quickly as we efficiently get again from the server information for a channel, they may seem in a card structure like this:
The kinds aren’t something too difficult, so we gained’t go into extra element at this level:
1 |
/*CUSTOM VARIABLES HERE*/
|
2 |
|
3 |
.card { |
4 |
padding: 4%; |
5 |
text-align: heart; |
6 |
margin-top: 70px; |
7 |
colour: var(--white); |
8 |
background: var(--total-black); |
9 |
border-radius: 7px; |
10 |
overflow: hidden; |
11 |
}
|
12 |
|
13 |
.card .particulars img { |
14 |
border-radius: 50%; |
15 |
}
|
16 |
|
17 |
.card .particulars .title { |
18 |
margin-top: 10px; |
19 |
}
|
20 |
|
21 |
.card .particulars .description { |
22 |
max-width: 80%; |
23 |
margin: 30px auto 0; |
24 |
}
|
25 |
|
26 |
.card .total-videos { |
27 |
place: relative; |
28 |
z-index: 1; |
29 |
margin-top: 30px; |
30 |
}
|
31 |
|
32 |
.card .total-subscribers { |
33 |
place: relative; |
34 |
show: inline-grid; |
35 |
grid-template-columns: auto auto; |
36 |
grid-gap: 10px; |
37 |
align-items: heart; |
38 |
font-weight: daring; |
39 |
margin-top: 60px; |
40 |
background: var(--red); |
41 |
}
|
42 |
|
43 |
.card .total-subscribers dotlottie-player { |
44 |
place: absolute; |
45 |
prime: 50%; |
46 |
left: 50%; |
47 |
rework: translate(-50%, -50%); |
48 |
}
|
49 |
|
50 |
.card .total-subscribers .outer { |
51 |
padding: 10px; |
52 |
}
|
53 |
|
54 |
.card .total-subscribers svg { |
55 |
fill: var(--red); |
56 |
background: var(--white); |
57 |
padding: 5px; |
58 |
box-sizing: content-box; |
59 |
}
|
4. Add the JavaScript
At this second, we’re able to construct the core performance of our YouTube app. Let’s do it!
On Kind Submission
Every time a consumer submits the shape by urgent the Enter key or the Submit button, we’ll do two issues:
- Cease the shape from submitting, therefore forestall reloading the web page.
- Seize the worth that’s contained within the search subject.
Right here’s the beginning code:
1 |
const topBanner = doc.querySelector("https://webdesign.tutsplus.com/.top-banner"https://webdesign.tutsplus.com/); |
2 |
const kind = topBanner.querySelector("https://webdesign.tutsplus.com/kind"https://webdesign.tutsplus.com/); |
3 |
const enter = topBanner.querySelector("https://webdesign.tutsplus.com/enter"https://webdesign.tutsplus.com/); |
4 |
|
5 |
kind.addEventListener("https://webdesign.tutsplus.com/submit"https://webdesign.tutsplus.com/, (e) => { |
6 |
e.preventDefault(); |
7 |
const channelId = enter.worth; |
8 |
});
|
Carry out an AJAX Request
Earlier than we undergo the AJAX request, it’s essential to learn the docs and perceive how one can construction it. In our case, we need to get channel information, so we’ll concentrate on the channel endpoint and move the next parameters:
- The
half
parameter with values thesnippet
andstatistics
names. - The API key. Once more, you must use your individual key.
- The channel ID we’re to get information. In a earlier part, we coated a technique to discover the ID of an current channel.
We will even experiment with the HTTP requests by the helper software that’s obtainable on the proper facet of this page.
With all of the above in thoughts, our request URL ought to look one thing like this:
1 |
const BASE_URL ="https://webdesign.tutsplus.com/https://www.googleapis.com/youtube/v3/channels?half=statistics,snippet"https://webdesign.tutsplus.com/; |
2 |
const API_KEY = "https://webdesign.tutsplus.com/AIzaSyAHupLf37J-vEziyQ-pItfoaLS5XUqdVq8"https://webdesign.tutsplus.com/; |
3 |
const channelID = enter.worth; |
4 |
|
5 |
const url = `${BASE_URL}&id=${channelId}&key=${API_KEY}`; |
We’ll use the Fetch API to carry out the AJAX request—I assume you’re acquainted with this method. There’s additionally a series should you want a refresher. As mentioned beforehand, we’ll add correct error dealing with for unsuccessful instances. For instance, if we seek for a non-existing channel or the standing request hasn’t succeeded.
So, our AJAX request would look one thing like this:
1 |
...
|
2 |
|
3 |
kind.addEventListener("https://webdesign.tutsplus.com/submit"https://webdesign.tutsplus.com/, (e) => { |
4 |
...
|
5 |
|
6 |
fetchYTStatistics(channelId) |
7 |
.then((information) => { |
8 |
if (typeof information.objects !== "https://webdesign.tutsplus.com/undefined"https://webdesign.tutsplus.com/) { |
9 |
createCard(information); |
10 |
} else { |
11 |
msg.textContent = "https://webdesign.tutsplus.com/Please seek for a sound YT channel ID 😩"https://webdesign.tutsplus.com/; |
12 |
}
|
13 |
})
|
14 |
.catch((error) => { |
15 |
msg.textContent = error; |
16 |
});
|
17 |
});
|
18 |
|
19 |
async operate fetchYTStatistics(channelId) { |
20 |
const url = `${BASE_URL}&id=${channelId}&key=${API_KEY}`; |
21 |
const response = await fetch(url); |
22 |
|
23 |
if (!response.okay) { |
24 |
return Promise.reject( |
25 |
`One thing is not working as anticipated. Error: ${response.standing}` |
26 |
);
|
27 |
}
|
28 |
const information = await response.json(); |
29 |
return information; |
30 |
}
|
Right here’s an instance of the response information:
Construct the Card
With the AJAX request in place, every time we kind a channel ID within the search subject, the API will return channel information if they’re obtainable. We’ll then accumulate solely the required information and connect it to the web page as a card part.
Two issues to notice right here:
- The Lottie animation will play provided that the channel subscribers are at the least 1M.
- We’ll use the NumberFormat API to format the numbers associated to the channel movies and subscribers.
- The exterior hyperlinks gained’t work except you view the CodePen demo in debug mode.
Right here’s the code accountable for this job:
1 |
operate createCard(information) { |
2 |
const allData = information.objects[0]; |
3 |
const { customUrl, title, description, thumbnails } = allData.snippet; |
4 |
const { default: thumbnail } = thumbnails; |
5 |
const { videoCount, subscriberCount } = allData.statistics; |
6 |
const div = doc.createElement("https://webdesign.tutsplus.com/div"https://webdesign.tutsplus.com/); |
7 |
div.classList.add("https://webdesign.tutsplus.com/card"https://webdesign.tutsplus.com/, "https://webdesign.tutsplus.com/container"https://webdesign.tutsplus.com/); |
8 |
|
9 |
const markup = ` |
10 |
<div class="particulars">
|
11 |
<img width="https://webdesign.tutsplus.com/${thumbnail.width}" top="https://webdesign.tutsplus.com/${thumbnail.top}" src="https://webdesign.tutsplus.com/${thumbnail.url}" alt="https://webdesign.tutsplus.com/${title}"> |
12 |
<div class="title">
|
13 |
<a href="https://www.youtube.com/${customUrl}" goal="_blank">${title}</a> |
14 |
</div>
|
15 |
<p class="description">${description}</p> |
16 |
</div>
|
17 |
<div class="total-videos">
|
18 |
<a href="https://www.youtube.com/${customUrl}/movies" goal="_blank">Browse</a> |
19 |
<span class="depend">${formatNumber(videoCount)}</span> movies |
20 |
</div>
|
21 |
<div class="total-subscribers">
|
22 |
${ |
23 |
subscriberCount >= 1000000 |
24 |
? `<dotlottie-player src="https://lottie.host/5fa38a1c-c8ba-4c3d-83b5-1a99b8796da3/jJFC2WMsxa.lottie" background="clear" velocity="1" type="width: 300px; top: 300px;" loop autoplay></dotlottie-player>` |
25 |
: "" |
26 |
} |
27 |
<span class="outer">
|
28 |
<span class="depend">${formatNumber(subscriberCount)}</span> |
29 |
Subscribers
|
30 |
</span>
|
31 |
<svg xmlns="https://www.w3.org/2000/svg" width="40" top="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.099.106.194.182.287.229.197.1.485.107.619-.067.07-.092.105-.241.105-.449v-3.359c0-.22-.043-.386-.129-.5-.147-.193-.42-.214-.632-.107zm4.827-5.195c-2.604-.177-11.066-.177-13.666 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 |
`; |
36 |
|
37 |
div.innerHTML = markup; |
38 |
doc.physique.appendChild(div); |
39 |
}
|
40 |
|
41 |
operate formatNumber(quantity) { |
42 |
return new Intl.NumberFormat("https://webdesign.tutsplus.com/en"https://webdesign.tutsplus.com/, { |
43 |
notation: "https://webdesign.tutsplus.com/compact" |
44 |
}).format(quantity); |
45 |
}
|
The generated markup because it’s rendered within the browser console:
Reset Issues
Lastly, after the AJAX request, we’ll do the next:
- Take away the
.card
ingredient from the web page. -
Clear the content material of the
.msg
ingredient. - Clear the worth of the search subject and provides focus to that subject.
Right here’s the associated code:
1 |
...
|
2 |
|
3 |
if (doc.querySelector("https://webdesign.tutsplus.com/.card"https://webdesign.tutsplus.com/)) { |
4 |
doc.querySelector("https://webdesign.tutsplus.com/.card"https://webdesign.tutsplus.com/).take away(); |
5 |
}
|
6 |
msg.textContent = ""https://webdesign.tutsplus.com/; |
7 |
kind.reset(); |
8 |
enter.focus(); |
Your YouTube App Is Prepared!
Accomplished, people! This actually was fairly an extended journey, so thanks for following alongside! I hope you loved the top outcome and that helped you be taught some new issues.
As soon as once more, don’t neglect to place your individual key for dwell app testing!
As a reminder, let’s look once more on the app:
As all the time, thanks so much for studying!
Subsequent Steps
There are such a lot of issues that you are able to do to increase the performance of this YouTube app. Listed below are some ideas:
- Create one other part to indicate the most recent channel movies.
- As an alternative of exhibiting only a channel every time, modify the code to indicate a number of channel information concurrently in a grid format, as we did with the climate app.
If there’s anything that you just would possibly need to see as an app extension, tell us on X or within the demo comments!
Uncover Extra JavaScript Tutorials and Sources
Thinking about training fashionable JavaScript by enjoyable hands-on tasks? If that’s the case, take a look at these JavaScript tutorials:
Trending Merchandise
[product_category category=”trending” per_page=”8″ columns=”2″ orderby=”date” order=”desc”].