In my last project, I needed to show the data before the first render, mainly because of SEO. For solving this problem Next.js offer some different data fetching methods.
Client Side Rendering (CSR):
This method in my use case wasn’t appropriate because the data's HTML are be shown after the first render, and it is bad for the SEO because Search Systems get the first HTML to analyze your content.
Using CSR, the browser is responsible for executing the js function and then processing the content. To implement CSR:
import { useState, useEffect } from 'react'
function Test() {
const [data, setData] = useState(null)
useEffect(() => {
fetch('/api/test')
.then((res) => res.json())
.then((data) => {
setData(data)
})
}, [])
return (
<div>
<h1>{data.name}</h1>
</div>
)
}
Server Side Rendering (SSR):
In this method, the server is responsible to run the functions and show the page with all data's HTML. For SEO it's good but it needs a lot of server processing and it can reduce the website's performance.
Implementing a getServerSideProps function for every request for the page, the server will make a new request and Next.js will pre-render this page using the data. If your API has a cost for each request CSR and SSR aren't good.
export async function getServerSideProps() {
const res = await fetch('/api/test')
return {
props: {
data: await res.json()
}
}
}
function Test({ data }) {
return (
<div>
<h1>{data.name}</h1>
</div>
)
}
Static Site Generation (SSG):
The SSG method allows us to have all data in the first render and the data are requested only one time, during the build.
It's very nice for the SEO, the request's cost, and performance, but if your content is updated you need to build your website again.
To implement we need to add a function called getStaticProps. If you are using a dynamic page ([id].js) you should add another function called getStaticPaths to define which paths will have the SSG method.
export async function getStaticPaths() {
return {
paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
fallback: false, // can also be true or 'blocking'
}
}
export async function getStaticProps() {
const res = await fetch('/api/test')
return {
props: {
data: await res.json()
}
}
}
function Test({ data }) {
return (
<div>
<h1>{data.name}</h1>
</div>
)
}
If the page isn't dynamic you don't need the getStaticPaths function to SSG works.
Incremental Static Regeneration (ISR):
SSG is a good method for my use case, but I needed something good for SEO and request cost, and an automatic data update.
ISR allows us to update SSG pages after your build. You only need to add a prop called revalidate.
export async function getStaticProps() {
const res = await fetch('/api/test')
return {
props: {
data: await res.json()
}
revalidate: 10, // In seconds
}
}
function Test({ data }) {
return (
<div>
<h1>{data.name}</h1>
</div>
)
}