Introduction to Dynamic Routes
In this episode, we are going to be talking about dynamic routes, and we are going to use them to connect our movies to the single movie page for each movie, of course, because we can't create a static page for every single movie that is going to come to us from our back end. So, we need to use dynamic routes for that.
And then we are going to try to connect to that single movie page via ID of the movie, and then by slug of the movie, and then at the end we are going to try to get a little bit more complicated by creating a route which is going to be something like movies, then the genre of the movie, and then the slug of the movie. As you will see, not that difficult using Next.js.
Minor Styling Adjustments
So, before we begin, I just want to make a few stylistic changes. Uh first of all, in our index.js under pages, I'm just going to add a margin bottom to this flex like this.
And then in our card.js file, here under the body, I just want to add a style for the link which we are going to be adding in this video. And that's it. Just these two small changes.
Adding the Next.js Link Component
So, our goal for this episode is to add a link to each of these movies, and then when the user clicks on it, it's going to take the user to the single movie page. So, first of all, we need to add that link. Of course, you will go to the card.js because that's the component that is displaying each of these movies, and then we are going to import a link from next/link.
Okay, now I just want to add that link below this dangerously set inner HTML or this movie description. Now, since the href is required when using link, I'm just going to put it to go to the root of my site for now, just for us to be able to see the link that we added. So, I'm just going to save this, check it out in the browser. As you can see, so it's the link more about this movie. Uh for now, it's just going to take us to the front page on which we are already on.
Creating a Dynamic Page with ID
Okay, so we added a link. Now, we need to link this to the movie page. How do we do that? Well, first of all, we are going to go to our code editor.
Now, we are going to create the movie page, but that page is not going to be called movie.js or something like that, but it's going to be called something like this. So, if we go here to the pages, I'm going to create a new page, actually new directory, and I'm going to call it movies.
And now in that movies directory, we are going to create a special page which is going to be called square bracket ID square bracket.js, like this.
So, we are calling it that because first of all, we are going to try to get to our movies using the ID of the actual movie. So, we are going to create this file, and now as you can see, we have movies, and then in it we have ID.js. Okay, great.
Now, in this file, I'm just going to add some boilerplate for displaying our movies. Like this. So, we are importing box and flex. We are defining a function called movie. We are using this box variant container. This is where our movie title is going to go. We are not going to get it dynamically just yet, a little bit later. This is where our movie description is going to go. This is the only two pieces of data that we will be displaying on this page. And then down here, we are just exporting movies. And that's about it. So, this is our movie page, which is called ID.js, as I said, because we are going to get those movies by ID.
Linking to the Dynamic Page
Okay, now we save this. So, how do we link this link from the card to this ID.js?
Well, very simply, actually. First of all, in href, you're going to define to which page do you want to connect inside of your project. So, in our case, that is going to be movies and ID. So, it's going to be movies and ID. So, this is the first part of our link.
Now, we have to define as what we are going to connect to. So, how our actual route is going to look like. And in this case, this is going to be as, and then you do backticks, not quotes. And then in those backticks, you would write movies, and then you need to pass the actual ID of the movie that you want to connect to. So, in our case, that is going to be movie ID. Great. Save this.
Now, let's go to our browser. And now, if I click on any of these movies, as you can see, I go to this route movies/1, and then we get movie title and description. So, this is all hardcoded. If I go back, click on more about this movie, then I would go to movies/2. And you get the idea.
Fetching Data with getServerSideProps
Okay, so we are getting the routes, we are getting the correct routes. Now, all we need to do is get the actual data of the movie and then display it on this page, right? So, we are going to be doing that in just a second.
So, if you go to your localhost:1337, so your Strapi, and do a /movies, you will get the list of all of your movies. So, what if I want to get the first movie or the movie with the ID of one? Well, I would just do /1. And now I would just get this Inception movie. Great. So, this is what we are going to be using to get the data for our single movie page.
So, we go to our browser, and first of all, we go to our ID.js file, and down here we are going to define how are we going to get that data. Of course, it's going to be very similar to what we did on our home page, where we used get server-side props. So, for now, I'm just going to add this function right here, get server-side props, and return nothing. But what is interesting here is this context variable that we're getting from get server-side props. So, let's take a look at that variable and see what we are getting from it. Right, so I'm going to console.log out context, save it, and now we can't go to our browser because as we said, get server-side props works only on the server. So, we should be able to get the log of this context if we go to our terminal.
So, we are getting a few things here, but also we are getting this. So, this is our context right here. And at the end of that context, as you can see, you have a query of ID equals two. So, this is where we are going to be getting the ID of our movie. So, you are going to get it from that context variable that comes with get server-side props.
Okay, so let's go to our code editor, and here we're just going to destructure this context variable and get our ID. So, something like this. const ID is equal to context.query, and now if we console.log out ID, save this, go to our terminal, as you can see right here, we get number two.
Displaying Dynamic Movie Data
So, this is going to be our ID that we're going to connect to our API URL, and then we are going to go to movies, and we are going to get the ID from this context variable. So, from here, I think you probably know what to do.
So, first of all, I'm going to get my API URL variable. So, I'm going to use get config, and of course, we have to import it like this. Next, we are also going to import isomorphic-unfetch because we need that to actually fetch the data. Okay. And now down here, we are going to actually fetch our data using this ID here. So, we are using our variable API URL variable, then movies, then the ID of the movie that we are getting through context. Next, we are defining it as data, and now we want to add it to our props for this page, and we are just going to call that prop movie, and sending this data that we are getting from our server.
Save it, and actually we can just try to console.log out this movie data to see if this works. So, in here, we are going to destructure a movie, and then inside of this function, we are going to console.log out movie. Save this. Go to our browser, and as you can see, we are getting this data right here. So, the movie name is Big Lebowski, description, we are getting all of that here. Great.
Now, let's just instead of having this static data right here, we are just going to actually get that dynamic data that we are getting from our back end and display it instead of this movie title and lorem ipsum text. So, here instead of movie title, we would just do movie.movie title, like this. And here, instead of this text, we are going to dangerously set inner HTML and call in movie.description like this.
And save this, go to our browser and as you can see already this data is changed. Now we have Big Lebowski right here, the description of that movie. If we go to our front page, go down here, go to Inception, we're getting Inception and The Goodfellas also should be working, right?
Switching from ID to Slug
Okay, now we're getting our movies dynamically. We are getting the data for those movies and we are getting those movies by ID. The next thing, because of course you don't want to get those movies by ID, you want to get them by slug. So that is what we're going to be doing next.
So to be able to get your movie by slug, you first of all have to add a slug field to our movies because we still don't have them. Actually, I have it right here because I added it before recording this video, but you would just go right here, add another field, add a text field and just call it slug and that's it. You don't need to do anything else and then you would go to your movies and fill out those slugs, right? You would just add slug like Big Lebowski right here, for the Inception it would be Inception and so on. And if we check out our movies, localhost:1337/movies, you will see that all of those movies have the slugs. Right, slug for Inception, for Big Lebowski, for Goodfellas.
Great. Now we want to create a route that is going to be movies/slug of the movie and not just the ID. So this is very simple to do and here you would rename this file from id.js to be slug.js. So I'm going to rename it to be slug.js. Okay, so refactor that.
Next thing you need to do, you need to go to the card.js file and now instead of href being movies ID, since we are not going to get it by ID but by slug and we change the name of that file, we need to change this to slug also. And also what we need to do in as is going to be movies/movie.slug. Okay, save this.
Fixing the Slug-Based Data Fetch
Now if we go to slug.js, we need to get the data for that movie. Of course we cannot use the ID because we are not getting the ID from the context. So we need to change this ID to be slug. So we are now getting the slug from that context variable. Uh and I wish it would be just easy to just rename this to slug, but this won't work as you will see. So if we change this to slug, so if we go to our browser and click on Inception, as you can see we are getting this, so status code 404 not found.
Now why is this? Well, this is because if we go to our Strapi backend, to our movies endpoint, as you've seen before, we can access each movie by doing movies/ID. Now if we go to movies/1, we will get the movie Inception. But if I go to movies and then Inception, I will get 404 not found. Now this is because Strapi doesn't work that way. It knows how to access a singular movie by ID, but it doesn't know how to access it by slug. But if you go to the Strapi documentation, you will see that Strapi has great filtering options and filters are very easy to use. So if we want to show the movie that has a slug of Inception, we would just go here and do question mark slug equals Inception. And you will get this. Great.
So we know how to access our movie by slug. Instead of movies slug, we are going to do just like we did in the URL bar of our browser. So we are going to do movies question mark slug equals slug. Now this is still not going to work. Now as you can see, this still doesn't work, but we are actually getting a movie. Right? As you can see we are getting Inception, description, we are getting all of this. Now this doesn't work because here we are using filtering and we are not getting just the movie object, but we are getting the array of objects because if you want to filter some data, you're probably expecting multiple results. But since we are filtering this by slug, we are probably just going to get one result. So to correct this situation and get the data for our movie, all we need to do is go to our code editor and here instead of movie is data, just add zero. So we are going to get the first item in that array and that first item is going to be our movie object. And now as you can see this works. So we get Inception, we get the description and it works for all of our movies. Great.
Creating Nested Dynamic Routes
Okay, so I know what you guys are going to be asking in the comments, so what if I have a genre of the movie and then I want to create a route which is going to be movies then a genre then the slug of that movie. So that I don't have to explain that to you in the comments, we are going to do it right here. As you will see it will be very quick and it's not that hard to do.
So we are now going to create another content type in our Strapi backend. We are going to go to content type builder, click on create new content type and we are going to call that content type genre. Okay, click continue. Then we are going to add some fields to it. We are going to add a field of title and another field of slug. So click finish. So we are just going to have a title and a slug. Save this.
Now we can go to genres and fill out those genres with some genres, right? I'm going to add sci-fi, comedy and crime. There's just one thing I want to do, we are going to go to movies and in movies, actually we are going to go to content type builder and then to movie and then we are going to add another field and that field is going to be the relation field. So we want to connect our movie like we did for the actors, we want to connect them to the genres and we are going to have movie has one genre. So for now we are just going to leave it that the movie has one genre, so that's one-to-one relationship, I think. We will click finish and save this.
Now we can go to movies, go to Big Lebowski and then set the genre for this to be comedy. Save it. Go to Goodfellas, this is going to be crime. Save it and Inception is going to be sci-fi. Save this. As you can see we have a genre right here. This is an object with the ID of one and it says the title of it is sci-fi, the slug is sci-fi and we have that for each of our movies. Great.
Implementing Nested Routes in Next.js
Now that we defined the genre for each movie, now we can create a route that is going to be movies/genre/the slug of the movie.
So what we're going to be doing now, we are going to go to movies and in it we are going to create a new directory called square bracket genre square bracket. Like this, and now I'm just going to move slug.js into genre. Okay, so now we have movies, then we have this weird directory with square brackets and then we have slug.js in it. Great.
Now we have to go to our card.js and we need to of course change href and we need to change as. So our the href now is going to be genre slug. So movies genre slug. And here in as, we are going to of course need to have one more parameter, so the slug will stay, but here we will have movie.genre.slug. And this is because if we go to our endpoint, we will see that this is our genre and we are getting the slug of it. We are going to use that slug to be the part of our route.
So now if I go to Inception for example, I will go to movies sci-fi Inception and I will get all the data for that movie. Same thing for the Big Lebowski. This is going to be movies comedy Big Lebowski and so on. As you can see, it's pretty easy to do this kind of complicated routes in Next.js.
Conclusion
Okay, so this has been it for this episode. Uh remember everything we did here will be available for you on GitHub, the link will be in the description below and as always thank you guys for watching and I will see you in the next one.