Let's Create a Movies app in Next Js using Tmdb API and Tailwind CSS
Create A movies app in Next js, tmdb API, and tailwind CSS with proper SEO tags and Sitemaps
In this article, We will create a movies app using next js, tmdb API, and Tailwind CSS with proper SEO and sitemap integration. In past, I had created a project like this and added it to my portfolio
External Packages I will use
- Moviestmdb => To interact with tmdb API easily.
- Tailwind CSS => For styling our app
- Slugify => To generate slugs (link for our movies).
- Next Seo => For Seo of the site.
and few others as a dev dependency.
Initial Setup
npx create-next-app moviesapp
This will create our next js app.
Tailwind CSS setup
Installation
yarn add -D tailwindcss@latest postcss@latest autoprefixer@latest
This will install Tailwind CSS in our app
Create
postcss.config.file
in the root directory and add the following code.// postcss.config.js module.exports = { plugins: { tailwindcss: {}, autoprefixer: {}, } }
Create a config file for tailwind CSS using the following command.
npx tailwindcss init
replace purge array with the following code in the tailwind.config.js
, this will purge the CSS and thus reduce the size of our CSS file.
purge: ["./pages/**/*.js", "./components/**/*.js"],
- Add the following styles in
global.css
@tailwind base;
@tailwind components;
@tailwind utilities;
- Finally import tailwind CSS in
_app.js
import "tailwindcss/tailwind.css";
Next Js config
- Add the following code to the
next.config.js
, this will help next js to enable optimization of images hosted on external sources.
module.exports = {
images: {
domains: ["image.tmdb.org"],
},
};
Moviestmdb and Slugify Setup
- Installation.
yarn add slugify moviestmdb
- Get tmdb API key from here
- Create a
.env.local
file in the root directory. - Paste Your tmdb API key as:
TMDB_API_KEY="****************************************"
- create a new folder naming configs in the root directory.
- create a new file inside naming
tmdb.js
- add the following code .
import Moviestmdb from "moviestmdb"; const tmdb = new Moviestmdb(process.env.TMDB_API_KEY); export default tmdb;
Add the initial setup has been completed now we will work with receiving the data add displaying it.
Index Page
We will fetch popular movies and pass them as props on the index page.
import tmdb from "../configs/tmdb";
//code has been not included to reduce size
export const getStaticProps = async () => {
const movies = await tmdb.discover("movie", [
{
param: "sort_by",
value: "vote_count.desc",
},
]);
return {
props: {
movies: movies.results,
},
};
};
getStaticProps will generate build time data.
[{param:"sort_by",value:"vote_count.dec}]
will return us most popular movies as per the vote count.
Creating the slug for the movie
- Tmdb returns us the movie data based on its id.
- So the request would be like
this would not beneficial for the SEO purpose as the slug would be likeconst movie= tmdb.movie(27205)
/movies/27205
and search engine crawlers will not understand what it means.
So for this purpose, I have installed the slugify
package which will convert the title into the string of slug and we will add id at the end of that slug, then the slug would be like /movies/inception-27205
.
While making the request we will split the string into an array and get the last element of the array. Now I will create a utility function for this purpose.
All our utility functions will go inside a new folder naming utils
. I will create a new file under the utils
directory of the name gen-slug.js
with the following code.
import slugify from "slugify";
const slugWithId = (title, id) => {
const slug = `${slugify(title, {
lower: true,
remove: /[*+~.()'"!:@]/g,
})}-${id}`;
return slug;
};
export default slugWithId;
- I am importing the slugify package
- Then I have created a default export function which takes to argument -> title and id
- Then using slugify I have converted the title into a slug and removed any unnecessary characters and also added the id of the movie at the end
Parse The slug
While we are in the utils directory let's create a function to parse the slug and return the id from it.
- Create a file naming
parse-slug.js
and add the following node.
export default function getIdFromSlug(slug) {
return slug.split("-").pop();
}
- this function will take a slug and then split it into an array and return the last element of the array using the
.pop()
method. .split(separator)
method of string converts a string into an array. it takes a separator which is used for splitting the string..pop()
method of the array returns the last element of the array
const id = getIdFromSlug("avengers-infinity-war-299536")
// returns 299536
Movie page
It's time for us to create a single movie page.
- Create a folder of the name
movies
inside the page directory. - Create a file in this folder naming
[slug].js
- Now add the following code to it.
import tmdb from "../../configs/tmdb";
import getIdFromSlug from "../../utils/parse-slug";
export default function SingleMovie({ moviesData }) {
return <div>{moviesData.title}</div>;
}
export const getServerSideProps = async (ctx) => {
const slug = ctx.params !== undefined ? ctx.params.slug : "";
const id = getIdFromSlug(slug);
const moviesData = await tmdb.movie(id, {
append: ["credits"],
});
return {
props: {
moviesData,
error: false,
},
};
};
- getServerSideProps will render the page on request time.
- slug will contain route param example
avengers-infinity-war-299536
. - id will be parsed using getIdFromSlug(slug) function.
- then we will pass the id into the
tmdb. movie()
method. - we can also get other details such as videos, translations, images, credits, etc by passing them to the appended array.
Tv Shows Page
Same as the movies page now we will add tv shows page. There are few changes in response such as there are no properties as title
or original_title
instead these are changed into name
and original_name
The TV details page for the tv show will be the same as the movies page.
SEO & Sitemap
SEO
- For the purpose of SEO,I have installed the
next-seo
package which helps us to include important meta tags - I have also included Opengraph data on every page.
Sitemap
Generating sitemap in next-js is quite complex.
We will have to create a node js script for generating the sitemap of the site, scripts will go in the scripts
directory.
First, we will fetch popular movies based on their vote count using the moviestmdb package.
Then with the help of the
fs
module of node js we will generate a JSON file containing an array of movie objects with the property of title, id, slug.After that, we will create another script that will convert the JSON data into the XML format.
This step will be repeated for tv shows also with minor changes.
The scripts will generate an XML sitemap and JSON file.
The reason I am generating the JSON file is that we can use it to generate static movie pages for our site if we ever wanted.
you can check the sitemaps at this link
Features You can add
Search For movies and tv shows.
Improve the UI.
Movie page can be more enriched using the data provided by tmdb API see here