How to Create a Youtube clone using react

How to Create a Youtube clone using react

ยท

3 min read

React is an open-source JavaScript library that is used to develop interactive user interfaces. It is managed by Facebook and a community of individual developers and companies. React mainly focuses on developing single-page web or mobile applications. here, we will create a Youtube clone.


Modules required:

  • npm
  • React
  • axios
    $ npx install axios --save
    

Basic setup:

  • Start a project by the following command:
    $ npx create-react-app youtube-clone
    
  • now go to youtube-clone :
    $ cd youtube-clone
    
  • Start the server- Start the server by typing the following command in the terminal :
    $ npm start
    
    open localhost:3000

Basic setup

  • Change directory to src and delete everything:
    $ cd src && rm *
    
  • now create several index.js,app.js,YoutubeApi.js,SearchBar.js,VideoDetails.js,VideoItem.js,VideoList.js file

  • For styling add semantic UI CDN to index.html

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css">
    

Edit index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

Edit App.js

import React from 'react';
import SearchBar from './components/SearchBar';
import YoutubeApi, { baseParams } from './api/YoutubeApi';
import VideoList from './components/VideoList';
import VideoDetails from './components/VideoDetails';

class App extends React.Component {
  constructor(){
    super();
    this.state = {video: [], selectedVideo: null};
  }

  componentDidMount(){
    this.onFormSubmit('Configure passwordless sudo for a specific user in linux itsvinayak');
  }

  onFormSubmit = async (term) => {
    const res = await YoutubeApi.get('/search',{
          params: {
            ...baseParams,
            q: term,
          }
        })

    this.setState({
      video: res.data.items,
      selectedVideo: res.data.items[0],
    });
  }

  onVideoSelect = (video) => {
    this.setState({
      selectedVideo: video
    });
  }

  render(){
    return(
      <div className="ui container">
       <SearchBar onFormSubmit={this.onFormSubmit}/>
         <div className="ui two column stackable grid">
             <div className="ten wide column">
               <VideoDetails video={this.state.selectedVideo} />
             </div>
             <div className="six wide column">
               <VideoList
                 onVideoSelect={this.onVideoSelect}
                 videos={this.state.video}
               />
           </div>
          </div>
         </div>
    );
  }
}

export default App;

Edit youtube-clone/src/components/VideoList.js

import React from 'react';
import VideoItem from './VideoItem';

const VideoList = ({videos,onVideoSelect}) => {
  const renderlist = videos.map(video => {
    return( <VideoItem onVideoSelect={onVideoSelect} video={video}/> );
  });

  return(
    <div className="ui relaxed divided list">
      {renderlist}
    </div>
  );
};

export default VideoList;

Edit youtube-clone/src/components/VideoDetails.js

import React from 'react';

const VideoDetails = ({video}) => {
  if (!video){
    return(
      <div class="ui active inverted dimmer">
       <div class="ui text loader">Loading</div>
     </div>
    );
   }

  const videoSrc = `https://www.youtube.com/embed/${video.id.videoId}`
  return(
    <div>
        <div className="ui embed">
        <iframe src= {videoSrc}
                allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
                title={video.snippet.title}
                allowFullScreen>
        </iframe>
        </div>
        <div className="ui segment">
        <div className="content">
          <a href="{video.snippet.title}" className="header"> {video.snippet.title}</a>
          <div className="description">{video.snippet.description}</div>
      </div>

      </div>
    </div>
  );
}

export default VideoDetails;

Edit youtube-clone/src/components/SearchBar.js

import React from 'react';


class SearchBar extends React.Component{
  constructor() {
    super();
    this.state = {
      term:''
    };
  }
  onInputChange = (e) => {
    this.setState({term: e.target.value})
  }
  onFormSubmit = (e) => {
    e.preventDefault();

    // call back function
    this.props.onFormSubmit(this.state.term);

  }
  render(){
    return(
      <div className="ui segment search-bar">
        <form onSubmit={this.onFormSubmit} className="ui form">
          <div className="field">
             <div className="ui red ribbon label">YouTube video search</div>
            <div className="ui input icon focus" style={{marginTop:"10px"}}>
               <input
                 value={this.state.term}
                 type="text"
                 placeholder="Search..."
                 onChange={this.onInputChange}
               />
                <i className="search icon"></i>
            </div>
          </div>
        </form>
      </div>
    );
  }
}

export default SearchBar;

youtube-clone/src/components/style/videoitem.css


.video-item{
  display:flex!important;
  align-items: center!important;
  cursor: pointer;
}

.video-item.item img{
  max-width:180px;
}

.video-item .video-content{
  overflow: hidden;
  text-align: justify;
}

Edit youtube-clone/src/api/YoutubeApi.js

Get an API key from google developer google developer

import axios from "axios";


const KEY = 'API_KEY_FROM_GOOGLE_CONSOLE';

export const baseParams = {
  part: "snippet",
  maxResults: 5,
  key: KEY
};

export default axios.create({
  baseURL: "https://www.googleapis.com/youtube/v3",
});

project is live here

source code @github

Did you find this article valuable?

Support Vinayak's Blog by becoming a sponsor. Any amount is appreciated!

ย