next js
What is SSR, SSG, ISR in Next.js. React Server side components
01 Aug 2023
5 Min Read
React is a popular and powerful javascript library which helps developers to create single page applications. But it has some issues with SEO as it just bundles the whole javascript code and send it to the client. then client executes that javascript and renders the web page. Drawback over here is when crawl bots try to crawl these pages they find unexecuted javascript code which is of no use. Which affects the ranking of that website
To overcome this nextjs comes with solution of server side rendering (Not only next.js but remix also offers similar features). Next.js renders the whole page server side then sends to the client due to which search engine bots can easily crawl that webpage and it helps in the seo.
SSR: Server Side Rendering
To overcome this nextjs comes with solution of server side rendering (Not only next.js but remix also offers similar features). Next.js renders the whole page server side then sends to the client due to which search engine bots can easily crawl that webpage and it helps in the seo as bot can see rendered HTML page.
Inside next.js page component you can export a function called getServerSideProps. In this function you can query database in request time and pass this data in form of props to the page component which saves the client side data fetching time. In getServerSideProps you get a context object which provides request object. You can get the Query parameters, headers and cookies with this object.
This becomes useful when you have some data which is publically available and you want to show it to every user with minimum delay. Because this data can be cached easily which also reduces database queries.
Pro Tip: Use SSR when the data gets frequently modified.
Example Use Case: Let's Suppose you want to show a blogpost, you can just take the requested slug from context object and fetch the blogpost on server-side then you can generate a html page with this data and send it back to the user. So unlike react here bots can see rendered HTML page instead of some javascript.
export default function Page({ data }) {
return <pre>{data}</pre>
}
export const getServerSideProps = async (context) => {
const res = await <Query your database>
const data = await res.json()
return { props: { data } }
}
SSG: Static Site Generation
In server-side rendering on every request (if cache miss) server requests the data from the database. But considering the previous use case of blogs website, there is a high chance that the content of the blog is not going to change so it will again and again query same data. Solution for this is Static Site Generation.
In Static Site Generation a page is rendered on the build time. When we run next build it fetches the data and renders the static page. This page is served over CDN for faster delivery.
In next.js you can export a function called getStaticProps which works same as getServerSideProps just it runs only one time that too when its build phase.
export const getStaticProps = async () => {
const res = await <Query your database>
const data = await res.json()
return { props: { data } }
}
But what if we have to generate multiple static pages based on the query params or our paths are depends on some external data. we can solve this issue with getStaticPaths. Which is used with getStaticProps which help to fetch the data and getStaticPaths will decide for which paths we have to fetch the data.
export async function getStaticPaths() {
// Get the paths you want to pre-render based on posts
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// { fallback: false } means other routes should 404.
return { paths, fallback: false }
}
Pro Tip: Use this when the data is stale and hardly it is going to change in future.
Example Use Case: In Blog Website, Documentations or Any kind of data which you can pre render before user requests it.
ISR: Incremental Static Regeneration
With SSG we can create static pages expecting that the data is never going to change. But what if the data changes are we going to rebuild the entire application? well we can do that but it is not a good way to handle it. This problem can be solved using Incremental Static Regeneration.
Solution 1: You can regenerate that page in a particular time interval.
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
// Next.js will attempt to re-generate the page:
// - When a request comes in
// - At most once every 10 seconds
revalidate: 10, // In seconds
}
}
It solves the problem but not that efficiently. Considering we have to change the data immediately (Updating the availability of ecommerce item) this method will fail. Also we are still making much requests to the database than required.
It is useful when you have to cache and fetch data periodically. like leaderboard section which updates after every day (GFG).
Solution 2: With On-Demand Revalidation
You can create an API endpoint which is accessible by you only, which will call below method.
res.revalidate('/blogs/post');
Or,
It's another use case will be for Ecommerce Websites. If you have updated a price of a product you can revalidate that specific product page immediately without any delay in the api which you are calling and will save some extra queries for you.