Intro to Next.js to Create Server Side Rendered React.js Apps - Software School (2024-06-13)
Video Transcript
So, they'll talk about a Next.js. At first, you need to install Node.js if you haven't.
All right. What is Next.js? It's a framework that allows us to use React, but mostly on
the server side. So, what happened is React.js is a library that we use on the front end
to build user interfaces. But that came along with the single-page applications. Traditionally,
in the web, whenever you click a link, it would load a completely new page. So, it would
ask for the server, hey, I want the HTML page for this. The server would give it back. And
then every link that you clicked would be a full-page reload. And then people thought,
why don't we just load the page once and then let the client build everything from there? That's
when a single-page applications came along. So, basically, the server just sends the HTML
bare bones, pretty much empty HTML, but then sends a bunch of JavaScript. And then the client side
is the one responsible for building or constructing the page on the client side. That is, all the
work is delegated to the person who requests the website, to their browser. And then the server
side, traditional, kind of came back. And now they're kind of doing a hybrid approach where
they thought, what if we kind of do it traditional way the first time people request a page, we kind
of render it on the server and send it all in full HTML. And then the client gets that full page.
And then from there, it can act as a single-page application in the sense that when they click
a link, it doesn't really request a whole page load. It's just manipulating the document with
JavaScript on the client side to render the completely new page, which isn't actually a new
page. It's just an illusion kind of thing. So, that's when people use React and then they thought,
okay, let's do React on the server side and do this approach. That's when the Next.js came along
and it's pretty much React, but it can also add some server side rendering, meaning it can just
give the user the full page render on the server side. And you might be asking, okay, what's the
benefit? Well, one of the big, huge benefits of this is for search engine optimization as CEO,
because the problem is every time a bot from the search engine, a crawler, they would come and see
your page that's written in React. The HTML is empty. Pretty much there's no information there to
let the search engine know what your website is about. So, Next.js can fix that because it will
render everything or pre-render on the server side. So, whenever the bot crawls and sees your
website, all the information will be there in the HTML already. So, that's a huge benefit.
Anyway, enough of the overview. Let's get to it. So, we're going to need a terminal. Let me open
one here. And I'm going to share my terminal. Hope you can see that. Now, we need to create a Next.js
project. So, we can use npx create-next-app. And then, if you want to pass the name, you can. But
they also recommend now to pass the version for some reason. So, add latest to always get the
latest version. So, you can add that as well. And if you want to put the name here after with space,
you can do it, but it will ask you later if you don't. So, let me put Next.js-posts because I'll
make some data that will be like blog posts or something. Press enter. It will ask you,
would you like to install create-next-app? You can say why for a yes and press enter.
The reason it didn't ask me is because I already did it before. Once you do that and it installs
create-next-app, it will ask you a few questions about the project you're about to generate. Now,
you can be very customizable. Like, you can use TypeScript. You can use other things. We're going
to see. I don't want to use TypeScript right now. I want to keep everything very simple. But if you
want in the future, you can do. So, yes, Lin, I don't need an enter right now. So, say no. I don't
want to use tailwind. No. Do you like to use SRC directory? I don't want to use it right now.
So, no. I press enter, by the way. Do you want to use the app router? Well, this is the new way of
routing that was released by Next.js in the latest versions. I'm not going to use it right now. I'm
just going to do it the traditional way, which is file system-based routing. So, I'm going to say no.
I'm going to press my arrow to the left and say no. Would you like to customize default? No.
Pretty much a selected no for everything. I want to keep it simple. Just if you were to
manually create an Next.js project, all you would have to do is install these dependencies.
React, react-dom, and Next. And then that's it. But it generates everything for us, so it's convenient.
Anyway, you can see here, there's now a new directory, Next.js-posts. So, I can cd to that,
cd Next.js-posts, enter. And I'm going to open my text editor. In that case, Visual Studio Code,
code, space..means-current-directory. You can use whatever, but I use VS Code.
Anyway, let me see here. While I got that open, I am going to start the development server. And to
do that, it's pretty much using the next dev command. So, you would say npx-next-dev. But actually,
they create a script for us. So, we don't have to remember this. We can just say npm-run-dev.
And this will run next dev. You can see here, I highlight what's actually being run when I say
npm-run-dev. Okay, so that's going to power up the development server. I think it's localhost
3000 by default. Let me see the code here. Let me show you. So, here's the code.
Just so you know, package.json has the script dev. That's why I said npm-run-dev because it's
already here. It's basically just calling next dev. And while I'm at it, I want to ask if anybody
has any trouble creating the project, because this is like a crucial moment. You need to have the
project. Otherwise, it cannot go on. You have trouble, let me know. Okay, I'm assuming everybody is
doing okay. So, what do we have here? So, you're going to have this file next config.mjs. Pretty
much is the configuration file for next. If you need to change anything, you would do it here. We
don't care about this right now. There's some js config as well. This is mostly for compiler options,
and it would be more relevant if you had like TypeScript to be tsconfig.json. What we're interested
right now, I have the pages directory, and this is where the stuff goes. So, next, you have to
automatically identify what pages need to be created based on the file sys structure for this
page's directory. So, you have index, you have underscore app underscore document. Basically,
underscore document allows you to kind of change the overall structure, and they have these tags
for html, the head, and the other stuff. So, underscore app, you don't have to worry about,
it's just passing props. And then index, this is the actual homepage. It's basically the slash.
If you go to localhost 3000 slash, it will hit this index page.
And it's pretty much like if you, if you don't react as just a component,
it's a function that returns a jsx template. And what's important here is that you export
the file that otherwise next won't know that this is what you want to show for the page.
So, make sure you export the file, the component that will be used for this page, the index page,
which is slash. Now, let's take a look at the page and see what we get in the browser next year.
By the way, here's the terminal. It's letting you know it's localhost 3000. You can control and
click in some terminals that will follow the link. Let me go to my browser. So, in the browser localhost
3000 enter, it's going to build a page and send you the page.
Okay, so this is the page. Pretty much we are in slash right now. So this, you can see it got
started by editing pages slash index.js. So it's like file system based routing in the sense that
if I want to create the page slash, I would create the file pages slash index because slash is index.
It's implicit. And then if I want to create, for example, post, which is I'm about to do,
I would say if I want to slash post here to be like a page of blog post or something,
I would have to create the pages slash post dot js. Let's do that. Make sure I'm in the right.
Okay, so I'm here, pages, right click, create a new file, posts, plural dot js.
Then I'm going to export the fault of function. And you can call whatever. I usually follow pages.
Let's see the name of the file posts. And obviously, if it's preact, you're going to get props,
but if you don't use it, you can omit and then return some template in jsx, which is
JavaScript, but it looks like HTML. So we can add whatever here, maybe just add a div.
And this is posts index. So we have something. So next day, it's going to automatically know,
hey, I see a file post dot js. Therefore, I must create the endpoint or route slash posts.
And this is what I'm going to show. Going back to the browser, I should be able to go to slash posts
and see that very page. This is the policy index.
I'm going to increase my zoom here. So see better 150. Now I want to just the background is black.
That's because of the styles that is applied there. Let me we can remove that. You don't like it.
Uh, because here, what happens is pages slash underscore app, it imports this global CSS file.
So what like there are different ways of adding style in next js. And if you want global styles,
you can do like an import. And then the path to the CSS file in this case is going to be under
styles here, logos dot CSS. They see a lot of stuff is defined here. If you don't like it,
just delete it all. And they could empty. And going back to posts. Because this underscore app
is actually rendering every page that you go to is actually going through this underscore app.
That's why you always see the CSS being ported there.
So it's kind of like a late layout stuff. You know, if you come from other frameworks like
rails, or there's a layout file, this is kind of look like that. You would make a layouts here
so that every single page has the these this code. I might have noticed this at sign here.
This is just an alias for the imports. This means to go to the root slash styles.
Just not ADC stuff when you import things.
All right, so that's the global style going back to posts. Let's talk about fetching data.
So in the client side, traditionally react. If I were to fetch some data, I could use a use
effect here. So if I import react from react, and I do react dot use effect,
pass a function and a second argument empty array, what what I'm doing is just some people don't
like using react dot here. So you can put use effect here if you don't like by the way.
That's the same thing. Okay. Anyway, I'm going to be explicit. I like doing this way for beginners.
Basically, when when this component is rendered for the first time, that is this template is shown,
right? I want to execute something right after that. And that's the function for the use effect.
Now I need to have the second argument as empty array, because that means I only want to execute
this once after the first render, otherwise it would be executing after every single render.
Render just means this function post is called again to render the template. Anyway, I want to
fetch some data with the fetch API. I'm going to use this website here. Let me see. I can show you.
I'm get the URL for the JSON tippy code. Where is it?
There's a website that has like a fake API that we can use for data since we don't have a back end
right now. And I'm going to get the I'm going to show you in the browser here. Let me show you.
I always like to use it. So this is the address I'm going to post to the zoom chat.
Basically, it's called jsonplaceholder.tippycode or typeycode.com slash post. And I'm going to add
the parameter to limit to just three posts because there's just too many. And the raw data is just
JSON. And there's some information we can use in our app. Basically, it's just the title and body of
the posts. It's like a blog post listing. So I'm going to use that. So let's go here to back to
VS code. So I want to fetch the data for every single post. So fetch that URL. And since we're
using fetch, I'm going to do that then here. And this returns a promise that fulfills with a response
object. And this response, we can extract the body in JSON format calling response.json. That in
turn also returns a promise. So we got to do another then there. And finally, we will get the
retrieved posts. And then we can do something with that. Now, I usually like to break a line here
for the style. I think it looks better like this. Okay, so usually we store this. Okay, we got all
the posts, but we need to store them so we can show them. So I usually store that in a state of
react. I don't do just a plain variable because if you do plain variable react doesn't know about it.
So we will not know when to re render this. Because initially, there will be no posts,
nothing to show. And then it's going to make a request to get the post going to take some time
and then you get a response. And then react needs to know that we have retrieved the posts,
therefore you should re render with all these posts. That's why we always need to use state.
Whenever the state changes, the react component re renders. So I'm going to use react dot use state
and I can pass an initial value to this function. I'm going to put an initial empty array. And then
here it returns two things, the array that sorry, two things right in an array, one that accesses
the value and the second to modify the value. So usually with this structure of const square
brackets, meaning we take the first element extract of the variable called post, and then
comma the second element extract of variables that I usually call set post. Because it's always the
same pattern describe what you're storing here, and set whatever the name for the variable was.
That's just a name convention, you can choose whatever if you want. Somebody's waiting.
Okay. Okay, so somebody just joined. Maybe I can give you something to follow. Hold on.
So we just, we created a project in XJS. And let me give you the command. I'm going to paste
the zoom if you want to catch up. That's the command we use in the terminal to create the
next JS app. And then we run with npm run dev. You want to catch up those are the two commands.
Anyway, let me continue here. So I just created, I want to start posting the state. So when I
retrieve the posts here, I want to call set posts with the retrieved posts, because I want to start
them now. Once I get them stored, I can finally leverage them here. Let's remove this. This is
post index. And I can go and map over the posts. So post is an array of objects. So I can map over
them to return elements components. And I can pass a narrow function here, post. And if I want to be
implicit about the return, I can put the parentheses. And I want to create a div here. And inside the div,
I'm going to add the post.title. Now react is going to complain whenever you map something,
you need to add it to the outermost element, a key that's unique. I usually put the ID of the
resource. So post.id there. So this will map over posts. In this case, there's three posts,
three objects. So it will create three divs. And each div will have the key just for the mapping.
And then inside will have the title of the post. Okay. Now with that, I'm going to go
to the browser to see if it's working.
And you can see automatically fetch. Here you can see one, two, three per line.
Now if you want to learn more about this stuff, I think you can press F12. And I think it's the
source of stab on Chrome. I'm using Firefox right now. So that's why it's called debugger here.
But I think I can go to the code and find control P. And I think this is called post.js.
And press enter there. This one is like the, I don't want that one. Let's see if there is,
oh, this one, the second one is with source map. So I can see exactly the original code.
So I'm just trying to show you how to debug with the DevTools and how to understand the response.
Maybe you don't know exactly what this fetch is doing. So what I would do is I would go here
and put a breakpoint on line 10 to understand what retrieve posts look like. So I would refresh.
And you see it stopped right here. So what I do, I can hover over this and see, oh,
this is an array of three elements. What's the inside of first? Oh, it's an object. It has the
properties body, ID, title and user ID. So you can see I'm using the title, right? This is what's
showing on the page. So this is one way of debugging. If you want, you can also open a console here.
Let me see if you click, where is it? Typically we have it here at the bottom where you can click
console and type what retrieve posts enter. It would also show you there what it means. This
way you understand what data you're dealing with. So you're not blind about what exactly I'm working
with. Since I understood the data, that's why I put a post.title, post.id. So I know exactly
what it was. Anyway, that's the debugger. Clicking back to the debugger or the sources tab into
home. I can uncheck that breakpoint. So I can plus play to let it go and keep going. And I
can close the DevTools. So I understand now the data. I understand now what I'm seeing here.
Now let's touch this up a little bit with some styling. But before I do that, let me know if
you have any questions or are stuck. Okay, I'm assuming everybody's fine. I'll keep going.
So I want to put each of these posts in a box, like a rectangular box to make it easier for us to
distinguish them from each other. Because right now I think it looks like one single thing, but it's
not. So going back to VS Code here. So what I'm going to do is add some CSS. But like I've told
you, I first showed you there's some global CSS. That is one way you could define the classes here
and then use them here. Let's say I use it host-box and define that there. But another way that
Next.js lets you use classes is with what's called the CSS modules. So you notice there's this
home.module.css here. That's used by the index actually. So the way they do it is they import
like this. But notice the import is to a variable called styles. And just the way that it's done,
you're going to see it, it's interesting. So let's try it. So typically what you would do,
let's call it create a file here and name it, let's say the name. I usually call the same name as the
corresponding file. So post.module.css. So Next.js, when you put .module.css, we'll understand what
you mean right away. And here I'm going to define post box. And I just want some border,
one pixel solid black. I hope you can see this, not too small. Then let's add some eight pixels padding
and maybe some background color of f. Let's ff as ff all the way is white. So
just a little bit less fd fd fd. What does it look like? I can even use my vscode to pick it here
actually. Let's see. This one f2 is nice. Okay. What else? Yeah, that's good enough. Now how do
we use this? So go back to post. So we got to import that. So import, give it a name like styles
from, and then you can do like the at sign, which means root from the root slash, you're going to go
.fages slash post.module.css. Now the way you use it is not like what we did here. We actually have
to pass the class name, use the curly brace there and say styles. And then here I need to access a
property. This styles as an object that has the property my class name. So I need to use the bracket
notation because I have a dash in the name. So post dash box. So what this is doing actually,
it's going to an object and referencing this property, but the value is actually a class name,
which is weird. You're going to see why is a class name. Let's go here and go to the browser.
Oops, I need to fix that, right? That's not correct. I need to add the class to what?
To the inner div, not the outer, because the outer is the list. So making sure it's on line 18,
not 16. Okay, so now that's in the right place. Save it back to the browser. You can see there.
Each one of them now is kind of separated. And let me right click and inspect of the dev tools.
And now what you're going to see is interesting. Look at each class name is.
So we got post underscore prefix followed by the actual class name that we wrote,
followed by some underscores of some code or unique identifier. So the reason I'm using CSS
modules is that it kind of gets around there's a problem of CSS conflict. What if in your website
you, for some reason, you're using somebody else's style sheet, like, you know, somebody
bootstrap or whatever. And the class name is the same as the class name that you defined. So you're
going to have a conflict. So the reason for CSS modules, okay, how can we get around the conflict?
Well, let's make our class names unique. So we're going to find a way of, okay, this is the original
name, let's add something to make it unique. So that's what it's doing. So that object that you
saw when you reference style brackets, post box, it's actually giving you the new class name,
the like a translated class name. Okay, so that's what it's doing.
Okay, enough of that. I think I should add a space between them. So I'm going to go to this.
You see this div that encloses them out, I'm going to add like a margin bottom for each
enclosing post box here. So let's try that. I'm going to go to the visual studio code.
And remember, I'm going to use post module at CSS. I want to add this new class called dot post
box list. And all the child elements, immediate child that have the class post box, I want to
have margin bottom of eight, actually 16, let's add 16. Okay, the else is doing, okay, find the
elements that have the class post box that are direct descendant child of the element
post box list class, right? That's why I have this greater than if you don't have the greater than
any, it could be nested nested somewhere under the post box list. But since we don't have any
nested that would would work as well. No problem. I'm going to save that go back to posts. Now I
need to add the class to the div here, class name, curly brace and styles, rackets, post
dash box dash list, like that. Let's see if it's working. Going back here and I can see
the added the class post underscore post box list underscore cut 96. That's like the unique ID.
All right, so it's working. Any questions so far?
Okay, now remember how I told you the big problem with single page application is when I right click
view page source here, I click right click and click view page source. I'm simulating being the
crawler the search engine crawler that's going through all the websites and going through this
website right now to understand what its content are, contents are. So I'm going to copy this code.
It's it's the one liners are hard to see. So I'm going to copy to Visual Studio Code and format it
so you can see it better here. I use control shift P and select format document by the way,
and it automatically makes it nice, easier to see. So it's basically HTML, right? But I'm not
interested in the head. So I'm going to collapse. I'm just setting the body, look at the body here.
That's what people see, right? The crawler is going to look at the body. And you can see here
post box list, right? It's empty, even though we see posts. Why is it empty? This is the big
problem of single page applications. The problem is the next GS sends us the page.
But initially, what all that we see is if you look at post.js is this div here. And that's
because initially post is empty. So there's nothing here to show empty. It would have to first send
file to the client. The browser then will render the empty list. And then it will make a fetch
request here to grab the post. That takes time. And the crawler is not going to wait for that.
The crawler just want to see right away what the page is about. So that's the big problem here.
So how do we fix this? How can we make sure that we see the post immediately as soon as we view
the page source? Well, we have to do a server side rendering, render the HTML on the server side first
then send to the client the whole page already rendered instead of having the client build it
themselves. Now to do that, one of the ways in next GS is you have to go outside here. You got to
export a function. I'll make a nice sync function. It's called get static props. Okay, there are
different strategies of fetching data in next GS. This is one of them. Now you need to exactly
export a function called get static props like this. And then this function is when is where we
do going to do the fetch. Now I'm going to comment this out to ignore it on the client side. I don't
need that there. So I'm going to take it and paste it here. Okay. I just took this code and put it
here. Now we don't need to set post anymore here actually. And I don't need to use then here because
if I use a sync, I can just use a wait. Okay, so I'm going to convert this from promise dot then to
a sync wait, it's the same thing. But because we're using a sync function, it's better to understand.
Okay, so let me delete that. So when we do a wait fetch, basically, this returns what a promise
that fulfills with the promise. So the response object, right? So we can say cost response equals
a wait. And that's the response. And then what did we do? We do response.json, right? So we can do
response.json to extract the response from the response body, the text, and then convert to
json. Now this also returns a promise therefore must use a wait. So the wait is like the equivalent
dot dot then. But okay, and then you put in a variable, we call that retrieve post, right?
And I like put semicolons there. Now that we got set retrieve post, what we do here is we return
an object that has the props property, and that's an object. And the object is whatever you want to
return back to the component there. So let's do post colon retrieved post. So what this is going
to do is next day, yes, at build time, you got to understand it's build time, build time, what is
build time? Well, when you have this next day as project, you're going to build it meaning you're
going to be render all the pages with a command called npm run build or next build. And once you
build it, you're going to put it in some server. And then you run next starts. So the server is
always on and listening to responses. But at build time is only once right, only when you build
is when this data is going to be fetched. Okay, and this is going to inject
a post property to this function here. So props dot posts will appear. So instead of referencing
posts here from the state, I'm not going to take that I'm going to reference that from this variable
props. So I can extract that with this structuring like this if you want. Or if you don't like this,
you just write props dot posts explicitly. Okay, basically posts is now coming from props properties
that are passed down to the post. That's all done by Next.js. Okay, now let's see if that's
if nothing's going to break. So we got the fetch, we got a wait one common problem, by the way,
if you do a sync await, some people forget to put the await. So that might mess up your stuff,
because if you don't put a wait, the code is going to keep executing before the response is
obtained. So don't forget to put the await whenever you have a promise.
Okay, let's see if it's still working in the browser. Close this.
Refresh. There you go. Still the same outcome. But I want to right click and build page source.
What's going to happen? Let me copy the code back to VS code new file.
Let me format documents. And I'm going to see look what happened.
All the posts are there. Initially, which is different from the other, right? Remember,
before there's nothing. At first glance, there's nothing. Now there's something. And because of
this, the search engine crawler will see, Oh, this is the content for the website, and will index it
and add out information so that the other people when they do a search will find content from your
website. So this is one of the big advantages of using Next.js and server side rendering is it
improves search engine optimization SEO, because you render everything in the server side first,
and then you send back to the client and the client doesn't need to build everything from scratch.
Okay, how's everybody doing?
Okay, nice. But
let's see. There's a problem with this approach. Here, if your posts change very often,
the content of the posts, maybe somebody changed and updated the post content.
And if you do that, it's not going to be reflected on the page. Why? Because the page content was
only rendered or built, created a build time, meaning it was done only once. And at some point
in time, and then the application was deployed with that content. And then after sometime in the
future, the content changed. And in order for you to show the new content, you would have to build
the application again and deploy it again. So that's a big problem. So how to get around that?
Well, what if we fetch the posts when I make somebody request it?
Right, I go to the website and then your Next.js server will say, hey, I need to get the posts
right now. Let's retrieve all the posts. So that's different from doing only a build time. Now we're
doing it at runtime, anytime, a dynamic. Let's do it. So to do that, you have to use another
function instead of get static props. You're going to use export async function, a get server side
props. Okay, server side props, that's the name you have to use. And then you're going to pretty
much do the same thing. Just copy and paste the code. And comment out this get static props,
comment out, make the computer ignore it. We don't need it anymore. So that's how you switch
from static to get server side props. Obviously, I could have just renamed it here, but I want to
keep the code here for reference. So let's try again. Let's see what happened.
Going back to Firefox. I want to refresh, see if it's. So the outcome is the same, right?
I always get the same thing, right click, build page source, copy. I'm going to see the same
initial things there by format it. Yeah, it's still here, right, the posts. So visually,
and it didn't seem anything changed. But actually, it's changed. It's something different. If I had
changed the post, this would give you the new post content right away. And if you want to monitor the
things, you can see in the terminal. Here, this is the terminal. Whenever I try to load a page,
it's going to give me some 200. There you see that 200 200. So at every request, it's building all
those fetching all the posts and building all the lists and rendering and sending to the client
on every request. Okay, so that means the data will always be up to date. If you change the post
data, the client will get the new data. That's drastically different from all we do at once
at build time. Okay, let's go and do about we do a page
to see the post. Usually, when you click the post, you see more information, right, the whole post,
right from the index is like the listing of all the posts and you click one. And you can see that
specific text for the post. Now, how do we do that? Well, typically, the route is slash post slash
post ID. So let's create that page. So how do we, you know, the post ID is kind of variable.
It could be one, two, three, four, and so on, right? So how do we do a dynamic route in XGS? So
create a new file with the name square brackets, and it puts the name of the variable here that
will hold that ID. I usually call it post, whatever ID, like post ID, resource name ID,
dot j s. Okay, it's just a post ID in square brackets, and I'm using, okay, so the I is
capitalized. Okay, so this will be the page for the specific post. So I'm going to export default
function, create a react component here. I usually call it post, post ID, whatever the route is for
this. Remember, this will be slash post slash the post ID, post ID, like slash post one,
slash post two, and so on. A little bit like that. Okay, and this also takes props because we got
components and you can return something, a div right now. Great, but when we go to the page,
how do we get here first, first of all, right? This is the post page. Let's just add something
place to order. How do we get there? Well, obviously, they can type in the browser manually, slash
post slash the number. But we don't do that usually click links, right? So let's go back to
post.js, and actually link the post style when I click the post style, it goes to the post page.
So in order to do that, instead of having a div here,
actually inside the div, let's do inside the div, I will
enclose this what's called a link component. So link, like that.
And we've got import at the top. So import link from next slash link, like so.
And then we must tell, okay, where does it go? Remember, HTML is the anchor tag href same thing
here href, but I'm going to use curly braces and say with the back tick. So I want to interpolate
string slash post slash the post ID. In this case, it's under post that ID. That's easy, right?
So if I say dollar curly brace post that ID, it will be interpolated. That means
for every single div that's generated here, it will take the ID of the post and put it here like
post two, one, two, three, and so on. Okay, so that's why I use that make sure it's a back tick,
otherwise it doesn't work. Back tick is the key next to the one on the keyboard.
It's not a single quote. It's not a double quote. It's the back tick.
Okay, let's see if the link is working.
See all of them are linked. I can see it's going post one, two, and three. Let's click two.
Now, what happened here? Page could not be found.
Let's try to fix that. That's a 404.
So in order to fix that, okay, I created a post ID, but next to this doesn't know about
that. So what I would have to do to go to slash post first, I have to create a directory here
called posts. And then I put the post ID inside. So that means, okay, if the user tries to go to
slash post, I need to go to the post directory. And then they're going to type something that could
be a variable like one, two, three, whatever. That's why I have to have the square brackets here.
Now let's try again.
Now can you see it's working, right? If I put one there, it's going to work the same way, but three,
okay. That's the file system based routing.
Okay, with that out of the way, let's actually get the information for the post. So what we do
is typically, okay, we're going to do the same approach as we did for posts. We're going to
choose a strategy of fetching the data. It could be static props, it could be client side,
could be static props, meaning only a build time once, or it could be server side props,
which means every single request, we're going to fetch it again.
I wanted to show you the ones for static props. So since we don't have time,
let's jump right into server side one. So if you were to do fetch a post, just export an
async function, get server side props, and then you're going to do the fetch. Now this case is
just one specific post. And if you go back here, post.js, the route that we're going to use,
going back, I just copied the fetch parameter there. We're going to use something like this,
right? I'm going to use back tick. But it's not necessarily limit three, I'm going to remove
that. It's going to be slash the ID of the post here, post ID. But how do we get that?
You know, I have no way of accessing it. But next.js is nice because if you have like a dynamic
route parameter, you can access it. So you can access from the client side or the server side,
you have to understand where you are right now, because it's different.
Okay, so right now when I'm in server side props, I'm on the server side. Therefore,
the way to access the route is through what's called a context. Okay, so that's the parameter
that's passed to get server side props. And then we're going to access params out of that.
So if I say context.params.post ID, this post ID, by the way, must match the exact file name here.
What's between the square brackets here, you must match that.
Okay, that way I get the post ID that the user typed. And then I can follow the same approach,
you know, await that fetch, put that in a response. And then, okay, take the response compared to
return a promise JSON, put that in retrieved post, whatever you want to call it. And then you
return an object with props, that's an object. And then you call it whatever, let's call just post
singular. And that's retrieve post. And then from the component here, you can access props.
Post. So if I go here and say props.post. Let's say title. And put that in an h1. Let's see what we get.
Oh, yeah, let's go. Let's see if it's working.
Okay, what's the problem here? Error serializing post return.
Server side props. Okay. You can try to go back to your code or you can use the DAB tools if you,
but the problem is we actually, there's a problem using the DAB tools here.
Because you're not going to be so lucky when we switch to server side rendering fetching
there in the server side, that's not client. So I cannot use the DAB tools here. If it were just
client side fetching, I could go and have a look at that, right? If I look at the sources here,
tab, or debugger on Firefox and look for post.js, I don't see it because it was all server side
rendering. So that's the downside of server side rendering is it makes it makes it a bit
a little bit harder to debug stuff. So in order to debug that, you would have to look at the terminal.
For example, let me show you. Let's go back to VS code. Next, yes, post.
And I'm here. So I would go here and console log. I intentionally put something wrong there.
It's something I talked about before. So if I console log retrieve post to see if a post is
actually there, I can put it here, maybe put in an object like so. And if I put a console log in
the God server side props, I should be able to see it in the terminal. I'm going to show you my
terminal here, see my terminal. And I'm going to go in my browser and trigger the page again so you
can see the terminal showing something. Do you see what's happening? I showed right here.
That's my console log. I see retrieve post to promise that's pending. Now I understand what
the problem is. I don't know if you got the problem. The promise was not resolved to a value.
That means you didn't handle the promise. And that's very likely I forgot to put an await.
Let's look. Did I put an await here? I didn't, right? So I have to put an await. Because this
returns a promise, I have to handle it. It's like a dot then. Now if I save that with the await,
go back to the terminal. Let's verify again. Now do you see retrieve post is now an object?
That should be the correct approach, right? Now this object will be passed down to the
component and then we can access all the properties. Title, props.post.title, props.post.body and so on.
Okay. Now that I fixed that, I go to the browser. I verify it's actually here, right?
Now let's add the body of the post. That's not so nice. Okay. Let's go back here and in the client
side, right? Or what's rendered initially. I'm going to add a div props.post. I think it's body,
right? Body. Yeah, body. And let's add some style. It's ugly, right? Very ugly. Maybe
you could add like class name here for the post content box or whatever you want to call it.
And then class name here, post content box, dash, title. And if you want the body,
you can add something. Maybe I don't need it. I think these two are so fights, but
if I want to use it this way, remember, there's two ways here. Globals or CSS modules. When I do
CSS modules, you got to do that same approach, create the file and then do it like we did here
with the styles import styles and then use styles square brackets. Now let me show you
with the global style because the global style, I don't think it uses that conflict resolution
of CSS module. So I think I could just say dot post. I went to style slash globals here, by the way.
So that means every single page will get this definition of style, which is different from
the other one, the CSS modules, only that page gets that specific style sheet, which is kind of
optimization, right? So I wouldn't usually put this in the global, to be honest. But I'm just doing
for the sake of example here. So what do we call it? Post content title. And I had on a class post
content title. Oops, I call it box, right? Post content box and post content box. Let me go back
as you forget. Content box content box title. The box content box title. There you go. So the content
box just want to add some borders on pixel of black padding 16 pixels. And then for the title,
want to add some margin to the non margin border bottom. How about that? I want to pick solid
black. And then maybe some margin margin. You're going to see what it looks like. Just we could
play around later. Maybe I like that. Maybe that's fine. Now let's see if it's working.
Let's refresh. Oops, I've been on the post. Did I save it? Let me make sure I saved it.
Save it. There you go. Okay, just like that. If I right click and inspect,
you see now the class names appear as they were. There's no change in class name,
like pull the CSS modules would add a prefix and a suffix to make it like a unique class name. But
this one doesn't do it if you do it globally. Okay, so we got the title and the content, the body.
And this is all doing at request time. It's fetching the data request time. So your browser will
ask next jazz. Hey, I want to see the post page next just in turn on the server side,
we'll ask another server for the data. And then once it receives it, it will render it there,
pre render on the server side. And then finally, we'll send that render page to the client.
Yeah, so a bit more complex than a traditional approach where you only have a server and a client
and only, you know, this one has like a three, three people, right, a client next to a server and
another server with the data. All right, so I think I'm out of time, but that's my introduction to
next jazz for you server side rendering a react. If you're interested in that, you can keep building
of that's very interesting. You can also do if you learn express j s, you can create express j s
API endpoints from next jazz code in the slash API folder here. Let's just show you real quick.
You see this pages slash API. That's where you could write API stuff just like a next express j
s you see handle function with rec and res. And you can send res and send there. So there's also
that it could act as an API as well. All right, so that's it for the lesson.