Building a Movie Streaming Site with Next.js, TMDb API, and VidSrc
In this tutorial, we will build a simple movie streaming site using Next.js, TMDb API for movie data, and VidSrc for streaming. I will walk you through from start to finish so even if you're a beginner you will understand all the steps from fetching APIs to displaying movie details and some styling.
Prerequisites
Before we begin, make sure you have the following:
- Basic knowledge of React and Next.js
- Installed Node.js and npm/yarn
- A free TMDb API Key (Sign up here)
Setting Up the Project
We'll be setting up the latest NextJS 15 project using the npx
command for this project. For the configuration you can use the default settings but for this tutorial I will not be using TypeScript. I suggest you do use TypeScript for your projects but just to speed things up I will not be using it.
Now to get started running the command below:
npx create-next-app@latest
Here is the settings I went with but you can go with anything you prefer.
Great after the download has completed I will go into the folder and install a package to making http requests in our app. My package of choice is axios, which is a very popular JavaScript library that's used by almost every developer I know.
cd movie-streaming-site
npm install axios
npm run dev
Finally you can visit http://localhost:3000/ to make sure the app is running.
Getting TMDb API Key
After we have the local app running we will work on getting our TMDB API key, so let's get started.
First visit TMDB The Movie Database (TMDb) and create an account if you don’t have one.
Once you're on the site then:
- Sign up or log in
- Click on your profile avatar in the top-right corner
- Navigate to Settings
Once you're in the settings page then as shown on the image above on the left navigation click and go to the API page. Once here click Generate to create your free API key. It'll show a few prompts like agreeing to the terms and after a few clicks you'll get the API Key we need to power our app.
Create a .env.local file in the root folder and add:
With the API Key we get from TMDB let's create a .env.local file in the root directory and add our key in the file. I am going to name my key NEXT_PUBLIC_TMDB_API_KEY and make sure to replace your_api_key_here with your actual API key.
NEXT_PUBLIC_TMDB_API_KEY=your_api_key_here
Great just to recap the folder structure of your app so far should look like this.
Home Page
In the homepage we'll display all the popular movies. So for this we'll take a look at the TMDB API documentation to find out what the URL is and how to send the API key in the request itself. Here is a screenshot of the popular endpoint from their website.
Now using this we will go ahead and render the list of popular movies this API returns. The code I have for the homepage is below with some simple styling.
// src/app/page.js
"use client";
import axios from "axios";
import Link from "next/link";
export default async function Home(){
const API_KEY= process.env.NEXT_PUBLIC_TMDB_API_KEY;
const response = await axios.get(`https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`);
const movies = response.data.results;
return(
<div className="p-4">
<h1 className="text-2xl font-bold text-center p-2">Popular Movies</h1>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{movies.map((movie)=>(
<Link key={movie.id} href={`/movie/${movie.id}`} className="block">
<div className="border rounded-lg ">
<img src={`https://image.tmdb.org/t/p/w500${movie.poster_path}alt={movie.title}`} className="w-full"/>
<p className="p-2 text-center">{movie.title}</p>
</div>
</Link>
))}
</div>
</div>
)
}
With the code above we'll show the movie image and the title for this page but you can customize it further to style it differently and make it better.
Movie Details Page
Great now the next page we'll work on is the Movie Details page. For this Make sure to create two new folders which is basically the new routes we'll be making to get the specific movie by it's id. So inside of /app make a movie folder, then [id] folder for the dynamic routing and then finally the page.js.
// src/app/movie/[id]/page.js
"use client";
import Link from "next/link";
import axios from "axios";
export default async function MovieDetail({ params }) {
const { id } = params;
const API_KEY = process.env.NEXT_PUBLIC_TMDB_API_KEY;
const movieResponse = await axios.get(
`https://api.themoviedb.org/3/movie/${id}popular?api_key=${API_KEY}`
);
const movie = movieResponse.data;
return (
<div className="p-4 max-w-2xl mx-auto">
<h1 className="text-2xl font-bold text-center">{movie.title}</h1>
<img
src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
className="w-full rounded-lg mt-4"
/>
<p className="mt-4 text-gray-800">{movie.overview}</p>
<p className="mt-2 font-semibold">Rating: {movie.vote_average}</p>
<div className="mt-4">
<Link href={`/watch/${id}`}>
<button className="bg-red-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Watch Now
</button>
</Link>
</div>
</div>
);
}
In this page I'm not showing some of the information we get from the API but feel free to explore it and use some of the other data it returns for this page.
Movie Streaming Page
Lastly we're create the Movie Streaming page which will be the page where the user can stream the movie. We'll create a route for this so inside of app create a watch folder, then [id] folder and finally page.js.
For the video streaming we'll be using a free API that has some ads but it's just a few clicks of ads. It's a solid and realiable app that works great with both IMDB and TMDB APIs.
// src/app/watch/[id]/page.js
import axios from "axios";
export default async function WatchMovie({ params }) {
const { id } = params;
const embedUrl = `https://vidsrc.to/embed/movie/${id}`;
const API_KEY = process.env.NEXT_PUBLIC_TMDB_API_KEY;
// Fetch movie details
const response = await axios.get(
`https://api.themoviedb.org/3/movie/${id}?api_key=${API_KEY}`
);
const movie = response.data;
return (
<div className="flex flex-col items-center p-4">
<h1 className="text-2xl font-bold mb-4">{movie.title}</h1>
<div className="w-full max-w-4xl">
<iframe
src={embedUrl}
className="w-full h-[500px] border-none rounded-lg"
allowFullScreen
></iframe>
</div>
</div>
);
}
Alright with this code above we'll get a simple page where we can stream the movie now. Go ahead and try it out for yourself and make sure to have some snacks with you! 🍿
Conclusion
If you've reached all the way here then congratulations! You now have a fully functional movie streaming that is 100% Free.
Now to showcase your new project make sure to signup on our site to create your own portfolio website in just a few minutes for free. Honestly it's the quickest and best way to make a portfolio site and not have to worry about any coding to maintain or update it.
So visit 👉 www.MyDevPa.ge and sign up today!
Full code here in Github!
You can get the full code here in our Github.