Youtube Data API with Javascript and Create React App

Quick start to making a webapp with Youtube Data API with Javascript and Create React App.

Let’s make a basic web app that utilizes the Youtube Data API. For a quick start, I am using create-react-app

I was fumbling to find YouTube eyeshadow tutorials quickly. Instead of typing in a search bar, I wanted something I could check off to find my videos in a single click.

This is how I did it:

1. Install node and npm from here.
2. In the terminal run npx create-react-app <your-app-name>
3. cd <your-app-name>
4. Edit your public/index.html to add <script src=”"></script> within the <head> tag.
5. In your code editor, replace your src/App.js with the following:

import “./App.css”;
import React, { useEffect, useState } from “react”;
// Notice how we don’t need extra node packages besides the ones built into create-react-app!
function App() {
// Here we’re setting up state using useState because we’re using React Hooks with functional components.
// In a class component we would use this.state = instead.
// We will use this to store the search results obtained by the YouTube Data API
const [searchResults, setSearchResults] = useState([]);

const colorNames = [
// Here we are using the Array.prototype.reduce method to automatically generate an object contatining checkbox states for every color.
const [colorState, setColorState] = useState(
colorNames.reduce((acc, color) => {
acc[color] = false;
return acc;
}, {})
// This code is lifted from the Google API Explorer documentation example code. However, one important change was made: We replace all instances of gapi with window.gapi to find our imported gapi object in React. Note that we’re getting this object from the script tag in our index.html
function loadClient() {
// Get your api key following the directions here:
return window.gapi.client
function () {
// You can delete these console logs if you don’t want unneccesary logs.
console.log(“GAPI client loaded for API”);
function (err) {
console.error(“Error loading GAPI client for API”, err);
// useEffect is the React hooks way to run code once when a component is mounted, similar to componentDidMount in React classes. Here we load our gapi client, setting us up to make API requests in the app.
useEffect(() => {
window.gapi.load(“client”, loadClient);
// This is where our JSX starts and where our app is rendered and styled.
return (
<div className=”App”>
<h1>Select the colors you’d like to see the tutorials of:</h1>
<div id=”colors”>
// We use here to display labels and checkboxes for all of our colors.
{ => (
<div key={color}>
<label htmlFor={color}>
// We convert lower case color names to human readable title case.
{color[0].toUpperCase() + color.slice(1)}
// We create a controlled checkbox input element for every color, using the colorState variable that we created earlier to store the state values.
// For checkboxes we use the checked prop instead of the value prop that we use in text inputs.
// We create a copy of the colorState object with only our newly checked color value changed.
onChange={() =>
setColorState({ …colorState, [color]: !colorState[color] })
// This is the button the user will have to click to submit their search query and render the embedded videos matching their preferences.
onClick={() => {
// We get the checked colors and construct our search query based on them, currently just by joining them on a single space and adding the word “eyeshadow”
const checkedColors = colorNames
.filter((color) => colorState[color])
.map((color) => `”${color}”`);
part: [“snippet”],
maxResults: 25,
// If no colors are checked, then checkedColors.length will be 0 (falsy) in which case we will just search for “natural” eyeshadow.
q: `${
checkedColors.length ? checkedColors.join(“ “) : “natural”
} eyeshadow`,
function (response) {
// Handle the results here (response.result has the parsed body).
console.log(“Response”, response);
// Here we save our search results to state so we can map over them below. We only need the response.result.items array so we can discard all of the other metadata in response.
function (err) {
console.error(“Execute error”, err);

// We only show the first 5 results here to improve loading times, but feel free to change this as you please.
{searchResults.slice(0, 5).map((sr) => (
<div key={}>
// For each search result, we have an embedded video using the url scheme. The iframe needs to be enclosed by a div with a unique key to comply with React guidelines requiring every mapped element to be uniquely identified.
export default App;

Use npm start to run your app.

Luckily, create-react-app projects can be easily deployed to Heroku. If you want to do this, first install the Heroku command line tools via homebrew. Then you can create your heroku app by running this command in your terminal in your project root folder:

heroku create <YOUR-APP-NAME>

Now we just need to deploy it to Heroku by git adding and git committing any unsaved changes and then running this command:

git push heroku main

After a few minutes you should be able to view your app online at https://<YOUR-APP-NAME>!

And that’s it! Hope you have as much fun with it as I did!

The above code is licensed under the GNU GPLV3. You can find out more at

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store