Let’s Create IMDB Clone without a Complex structure
Let’s Create IMDB Clone without a Complex structure
IMDb is an online database of information related to films, television series, home videos, video games, and streaming content online — including cast, production crew, and personal biographies, plot summaries, trivia, ratings, and fan and critical reviews ~ Wikepedia
Today, I will be telling you how you can make IMDB clone using Reactjs without any complex Coding.
- Demo Link — Imdb-clone-by-py
- Github Link — ImdbClone
Prerequisites
- Nodejs Installed
- Basic javascript Required
- IDE like Vs code, Atom, etc.
- Working Internet Connection
Let’s Get Started
- I will be using Vite+React to enhance the performance of our web App.
- Install the Vite+React app using the node package manager
npm create vite@latest
- Give a name to this project and click enter
- Choose React and click enter
- Choose Javascript
That’s It, It took 7 seconds to install in it my laptop

- Go to your imdb-clone directory
cd imdb-clone
- Install necessary packages in our app
npm install
- Run the development server by typing the following command
npm run dev
Go to the link given in the local section

- Install necessary packages which we will be using in our app
npm i react-router-dom react-responsive-carousel
To enable routing in our app, we will using react-router-dom
For Slider, We will be using react-responsive-carousel

- Open the app in your Text editor or IDE
code .
- Open the src folder and Remove App.css from the app because our whole CSS will be in index.css .
- Clear App.jsx Code and create a Empty functional component.

- Enable Routing in App.jsx
import { BrowserRouter as Router, Routes, Route } from "react-router-dom"
- Create Router, Routes and Route in return section
<div className='App'><Router><Routes><Route exact path="/" element={<Home />} /><Route path="movie/:id" element={<MovieDetails />} /><Route path="movies/:type" element={<MovieList />} /><Route path="/*" element={<Error />} /></Routes></Router></div>
Explanation of the above code
In our IMDB-Clone, There will be a Home component, MovieDetails component, MovieList Component, and Error component.
- Our Root Page will be Home Page that’ why we give it a path “ / ”
- We will be fetching our Movie details from its ID, that’s why we give it a path “movie/:id ”
- We will navigate according to movie type that’s why I am giving it a path “movies/:type”
- For the error Page, I am giving it a path “/*”
Continuing our code
- Create a component folder in the src folder
- In Component folder, Create Home.jsx, MovieDetails.jsx, MovieList.jsx and import them in App.jsx

Let’s create a Header component in our components folder
import { Link } from "react-router-dom"import '../index.css'const Header = () => {return (<div className="header"><div className="headerLeft"><Link to='/'><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/69/IMDB_Logo_2016.svg/2560px-IMDB_Logo_2016.svg.png" className="header__icon" alt="icon" /></Link><Link to='movies/popular'><span> Popular</span></Link><Link to='movies/top_rated'><span>Top Rated</span> </Link><Link to='movies/upcoming'><span>Upcoming</span> </Link></div></div>)}export default Heade
- We used Link to navigate to different nav links of our header
- You can find all the CSS of this code here -https://github.com/piyushyadav0191/imdb-clone/blob/master/src/index.css
- Import and insert our Header component in App.jsx
<div className='App'><Router><Header /><Routes>....//// Rest Code</div>
- It should look like this after importing the header component

- Let’s check that the Routes are working or not

Cool, It is Working
- Let’s Create a Home component
- For Movie fetching Details, you need an API key from TMDB from its official documentation but don’t worry about it because you can use mine
- Create a state and use an effect which will fetch our movie details through our API key from the TMDB Site.
import {useState, useEffect} from 'react'const Home = () => {const [PopularMovies, setPopularMovies] = useState([])useEffect(()=>{fetch("https://api.themoviedb.org/3/movie/popular?api_key=4e44d9029b1270a757cddc766a1bcb63&language=en-US")}, [])return (<h1>Home</h1>)}
- Let’s Check that do we getting any data from our API key in the network section of the Console

- Cool, we are getting a response from our API key.
- Convert our data in JSON format and take the result as parameter
useEffect(()=>{fetch("https://api.themoviedb.org/3/movie/popular?api_key=4e44d9029b1270a757cddc766a1bcb63&language=en-US").then(res => res.json()).then(data => setPopularMovies(data.results))console.log(data)}, [])
- Let’s make a carousel for our home component
<div className='poster'><CarouselshowThumbs={false}autoPlay={true}transitionTime={3}infiniteLoop={true}showStatus={false}>{PopularMovies.map(movie => (<Link style={{textDecoration:"none",color:"white"}} to={`/movie/${movie.id}`} ><div className="posterImage"><img src={`https://image.tmdb.org/t/p/original${movie && movie.backdrop_path}`} /></div><div className="posterImage__overlay"><div className="posterImage__title">{movie ? movie.original_title: ""}</div><div className="posterImage__runtime">{movie ? movie.release_date : ""}<span className="posterImage__rating">{movie ? movie.vote_average :""}<i className="fas fa-star" />{" "}</span></div><div className="posterImage__description">{movie ? movie.overview : ""}</div></div></Link>))}</Carousel></div>
Explanation of above code
- I simply mapped our popular movies' states and wrapped them in the link because I need to go to that page of the poster I click on.
- I gave the link a dynamic id which we will receive from the API
- movie.backdrop_path->You will notice when I checked my network tag there was backdrop path of images provided by the API. If you don’t remember then refer the below Image.

- I got original_title, overview, release date etc from the API itself. There is nothing I did except from fetching the data from the api
- We use Carousel package and you can refer its original documentation to add more properties.
Let’s see our Output

Cool, right?
Let’s create MovieList below our carousel
- Put the MovieList component below the closing tag of carousel and don't forget to import the movielist
//// Rest COde
</Carousel>
<MovieList />
</div>
Edit the Movie List component so that we will get movielist in a card
- Create card in components folder and import it in MovieList file. Add the following code in card component
import {useEffect, useState} from 'react'import { Link } from 'react-router-dom'const Card = ({movie}) => {const [isLoading, setisLoading] = useState(true)useEffect(() => {setTimeout(() => {setisLoading(false)}, 1500);},[])return (<>{isLoading?<div className="cards"></div>:<Link to={`/movie/${movie.id}`} style={{textDecoration:"none", color:"white"}}><div className="cards"><img className="cards__img" src={`https://image.tmdb.org/t/p/original${movie?movie.poster_path:""}`} /><div className="cards__overlay"><div className="card__title">{movie?movie.original_title:""}</div><div className="card__runtime">{movie?movie.release_date:""}<span className="card__rating">{movie?movie.vote_average:""}<i className="fas fa-star" /></span></div><div className="card__description">{movie ? movie.overview.slice(0,118)+"..." : ""}</div></div></div></Link>}</>)}export default Card
- After coming this far, You should be able to understand our code in our card component easily. If not Try to put more efforts in it.
- Import the Card component in MovieList.jsx and paste the following code
import React, {useEffect, useState} from "react"import { useParams } from "react-router-dom"import Cards from "./Card"const MovieList = () => {const [movieList, setMovieList] = useState([])const {type} = useParams()useEffect(() => {getData()}, [type])const getData = () => {fetch(`https://api.themoviedb.org/3/movie/${type ? type : "popular"}?api_key=4e44d9029b1270a757cddc766a1bcb63&language=en-US`).then(res => res.json()).then(data => setMovieList(data.results))}return (<div className="movie__list"><h2 className="list__title">{(type ? type : "POPULAR").toUpperCase()}</h2><div className="list__cards">{movieList.map(movie => (<Cards movie={movie} />))}</div></div>)}export default MovieList
Explanation of Above Code
- I used params from react-router-dom to get Popular parameter
- Other than params, there is no complex thing I have done except used useEffect to activate our getData function called
Continuing our code
- Before further coding, Let’s check out output of our Home Compoennt

All good, up till now, right?
- Let’s create MovieDetails component to get popular, top rated and upcoming navlinks.
- Paste the following code in MovieDetails Component
import React, {useEffect, useState} from "react"import { useParams } from "react-router-dom"const MovieDetails = () => {const [currentMovieDetail, setMovie] = useState()const { id } = useParams()useEffect(() => {getData()window.scrollTo(0,0)}, [])const getData = () => {fetch(`https://api.themoviedb.org/3/movie/${id}?api_key=4e44d9029b1270a757cddc766a1bcb63&language=en-US`).then(res => res.json()).then(data => setMovie(data))}return (<div className="movie"><div className="movie__intro"><img className="movie__backdrop" src={`https://image.tmdb.org/t/p/original${currentMovieDetail ? currentMovieDetail.backdrop_path : ""}`} /></div><div className="movie__detail"><div className="movie__detailLeft"><div className="movie__posterBox"><img className="movie__poster" src={`https://image.tmdb.org/t/p/original${currentMovieDetail ? currentMovieDetail.poster_path : ""}`} /></div></div><div className="movie__detailRight"><div className="movie__detailRightTop"><div className="movie__name">{currentMovieDetail ? currentMovieDetail.original_title : ""}</div><div className="movie__tagline">{currentMovieDetail ? currentMovieDetail.tagline : ""}</div><div className="movie__rating">{currentMovieDetail ? currentMovieDetail.vote_average: ""} <i class="fas fa-star" /><span className="movie__voteCount">{currentMovieDetail ? "(" + currentMovieDetail.vote_count + ") votes" : ""}</span></div><div className="movie__runtime">{currentMovieDetail ? currentMovieDetail.runtime + " mins" : ""}</div><div className="movie__releaseDate">{currentMovieDetail ? "Release date: " + currentMovieDetail.release_date : ""}</div><div className="movie__genres">{currentMovieDetail && currentMovieDetail.genres?currentMovieDetail.genres.map(genre => (<><span className="movie__genre" id={genre.id}>{genre.name}</span></>)):""}</div></div><div className="movie__detailRightBottom"><div className="synopsisText">Synopsis</div><div>{currentMovieDetail ? currentMovieDetail.overview : ""}</div></div></div></div><div className="movie__links"><div className="movie__heading">Useful Links</div>{currentMovieDetail && currentMovieDetail.homepage && <a href={currentMovieDetail.homepage} target="_blank" style={{textDecoration: "none"}}><p><span className="movie__homeButton movie__Button">Homepage <i className="newTab fas fa-external-link-alt"></i></span></p></a>}{currentMovieDetail && currentMovieDetail.imdb_id && <a href={"https://www.imdb.com/title/" + currentMovieDetail.imdb_id} target="_blank" style={{textDecoration: "none"}}><p><span className="movie__imdbButton movie__Button">IMDb<i className="newTab fas fa-external-link-alt"></i></span></p></a>}</div><div className="movie__heading">Production companies</div><div className="movie__production">{currentMovieDetail && currentMovieDetail.production_companies && currentMovieDetail.production_companies.map(company => (<>{company.logo_path&&<span className="productionCompanyImage"><img className="movie__productionComapany" src={"https://image.tmdb.org/t/p/original" + company.logo_path} /><span>{company.name}</span></span>}</>))}</div></div>)}export default MovieDetails
I am leaving the explanation of above code to you. If you didn’t understand it. Do comment down and we will discuss it together
Our Final Output

What’s Next?
You can further code this project to implement your idea. I have few tips from my side.
- Make this Clone a responsive for mobiles
- Use react-skeleton loading
- Use Watch Movie API to Watch Movie on this App.
If you are happened to stepped on some error while coding project then let me know about it in the response and we will discuss it togethor.
Comments
Post a Comment