Different rendering techniques in Next.js
What is Next.js?
Quite simply, Next.js is a React framework for developing single page Javascript applications. What makes Next.js so popular is its ability to support SSR (Server Side Rendering) out of the box which reduces the complexity of building an application from scratch. It also supports code splitting which helps you load only what your user needs without requiring them to download unnecessary code at once.
In this article we’ll go through the rendering techniques that Next.js provides and explain them so you can start writing your own applications with confidence!
Static Site Generation (SSG)
Static generation is a term used to describe a process that generates HTML pages during the build time, which are then served to the browser.
SSG in Next.js without dynamic data:
Static site generation without fetching external data means that all of the content on your website can be generated from its own source code, rather than being fetched from external sources like databases or APIs. For example, if we are making an about company page:
// pages/about.js
const About = () => {
return <div>
<h1>About Us</h1>
// Page content...
</div>
}
export default About
SSG in Next.js with data:
getStaticProps
getStaticProps is a special async function provided by Next.js that will run to fetch data once when that page builds. it runs on the server side and it is not visible to the client-side. getStaticProps always return data object and sends it to the component as a prop. For example:
export const getStaticProps = async () => {
const res = await fetch('http://worldtimeapi.org/api/ip');
const data = await res.json()
const { datetime } = data;
return {
props: {
datetime,
}
}
}
NOTE: In development (next dev), getStaticProps will be called on every request.
Incermental Site Regeneration (ISR)
getStaticProps + revalidate
ISR allows us to generate and update pages after the site is built. It can efficiently use static generation on a per-page basis without rebuilding the entire site. ISR is an add-on on top of getStaticProps, You can use ISR by adding the revalidate property to getStaticProps function. As shown in the example:
export const getStaticProps = async () => {
const res = await fetch('http://worldtimeapi.org/api/ip');
const data = await res.json()
const { datetime } = data;
return {
props: {
datetime,
},
revalidate: 10, // In seconds
}
}
The revalidate value inside the return statement represents the time interval to rebuild the page if a request comes after that interval.
Server Side Rendering (SSR)
getServerProps
SSR is a web performance optimization technique for websites that want to ensure their pages load quickly and reliably. When you visit a website that uses server-side rendering, the server receives your request, renders the page on its own, and sends it to you in the form of HTML code. This means that you see an HTML document on your browser as soon as you open the page, instead of waiting for it to be generated by JavaScript.
Next.js has built-in support for server-side rendering, which means that if you export a function called getServerSideProps from a page, Next.js will pre-render this page on each request. The following example shows how to fetch data using the SSR technique in Next.js:
export const getServerSideProps = async () => {
const res = await fetch('http://worldtimeapi.org/api/ip');
const data = await res.json()
const { datetime } = data;
return {
props: {
datetime,
}
}
}
Client Side rendering (CSR)
Plain ReactJS Way
Well, Next.js specifically provides us with the three techniques explained above, but it also supports the plain React way - Client Side Rendering - by using the useEffect Hook. Client-side data fetching is useful when your page doesn’t require SEO indexing, when you don’t need to pre-render your data, or when the content of your pages needs to update frequently.
As shown in the example:
import { useState, useEffect } from 'react'
import axios from 'axios'
const CSR = () => {
const [name, setName] = useState()
const [isLoading, setIsLoading] = useState(true)
useEffect(() => {
axios.get('https://jsonplaceholder.typicode.com/users/1').then(res => {
setName(res.data.name)
setIsLoading(false)
}
)}, [isLoading])
return (
<div>
<p>Client Side rendering (CSR):</p>
{ isLoading ? <p>Loading...</p> : <h1> {name} </h1> }
</div>
)
}
export default CSR
NOTE: Next.js team has created a React hook library for data fetching called SWR. This hook will be covered in a separate blog post.
Summary
Next.js provides you the flexibility to render different pages in your application using the different rendering techniques that we discussed above. Choosing which technique to use entirely depends on your use case. If you have a lot of data fetching then you should consider using server-side rendering. If you hava a simple page, with not many requests such as a blog post, then, static-site-generation, and getStaticProps would be preferred, and so on.