Next.js is a popular JavaScript framework that offers server-side rendering and static site generation capabilities. Pre-rendering is an important feature of Next.js that allows developers to render a page on the server before it is sent to the client. It allows a page to be sent to the client faster, making the user experience faster and smoother. Additionally, server-side props can be passed to the page, making the page more personalized and dynamic. In this article, we'll discuss the basics of pre-rendering with Next.js and how to use server-side props to create more dynamic pages.
What is Pre-Rendering?
Pre-rendering is a technique where we generate page content on the server before sending it to the client. From the NextJS side, you prepare all the values that are needed for your page to render and pass them as props. It is possible to enable cache for content by just defining cache headers. After content is loaded, NextJS starts a process called hydration. During that process, it attaches all events and other listeners so that after it, the application starts behaving as a regular single-page application.
Benefits of Pre-Rendering
This technique has many benefits but the main one would be speed. In a typical single-page application, the usual process would be fetching required static content. That means a required bundle of JavaScript, libraries, CSS, and templates. After that, it requests to fetch the data required for that page. Once it is both loaded, then it starts building content and rendering it in the browser.
The difference with server-side rendering is that on the client's requests, on the server data is prepared, and content is generated. The final result is sent to the client as a bundle. This results in faster delivery of the content, which means also improved and smoother user experience and better SEO.
Using Server-Side Props
For the example of using server-side rendering, we can start by using a simple component that just displays the first and last name of the person.
// /server-side-props
export default function ServerSideProps({ person }) {
const { firstName, lastName } = person;
return (
<>
Hello {firstName} {lastName}
</>
)
}
This component wouldn't use server-side rendering, but there would be no need to. However, we could have a dynamic page that shows the name details of different people. Then we could use server-side rendering to prepare those values and start rendering them on request. We can enable that by exporting the getServerSideProps function in the same file where our page component is exposed.
// /server-side-props
export default function ServerSideProps({ person }) {
const { firstName, lastName } = person;
return (
<>
Hello {firstName} {lastName}
</>
)
}
export async function getServerSideProps(context) {
return {
props: {
person: { firstName: "John", lastName: "Doe" }
}, // will be passed to the page component as props
}
}
In the example above, values used are passed to the component as props. However, in the getServerSideProps, values are hardcoded. Which breaks the point of having server-side rendering. But those values could depend on some URL path parameter and values could be retrieved from some API or database.
In that case, we need a path id. Function getServerSideProps has one parameter, context, and in it we get all the required request data including the id parameter.
export async function getServerSideProps(context) {
const personId = context.params.id;
const personData = await fetchData(personId);
return {
props: {
person: personData
},
}
}
In the above code, the fetchData function is called with the await. That is possible because the getServerSideProps function is marked as async so you can make asynchronous requests in it.
Fetching data from local API in getServerSideProps
If your pre-rendering content uses data exposed on your NextJS project API, you do not want to call that API in the getServerSideProps function. If you do that, first, the user would request to get content, then another request would be made to get data. After the request is completed, pre-rendering content runs and it is all sent to the user. A better solution is to exclude data logic used by your API route and call it directly in the getServerSideProps function.
When to use server-side rendering
Server-side rendering can be used whenever your application depends on the data that needs to be fetched on request. That could be authorization data or geo-location. But when you are writing your code, if there is data that needs to be fetched at the start and not be updated, might be a good indicator to use server-side rendering.
Conclusion
Server-side rendering is a great technique for improving the UX and SEO of your application. It can speed up the response of your pages, and I hope you got enough insight from this post on how to use it. The code used in the examples above can be found in my GitHub repository.
For more, you can follow me on Twitter, LinkedIn, GitHub, or Instagram.
Top comments (6)
Hey Kristijan Pajtasev, this is a great post on server side rendering. Thanks for sharing this wonderful blog. Learned much and had clear understanding of what a server side rendering mean. Thank you, keep up the good work 😊
Thank you very much for your feedback :) i appreciate it :)
One of the problems we came across with server-side props was that it noticeably slowed down our loading time at the start, first contentful paint was over 5s.
Have you encountered this?
Haven't had that situation but it is possible to happen. What is the work being done in your function. If it is some slow service request it can happen.
It's just retrieving some data from MongoDB, only about 20 odd documents.
Server side rendering, oh, the irony.