Next JS is a popular React framework known for its great rendering capabilities and data fetching strategies. In this Answer, we will go through the primary methods used in Next JS to fetch data: Static Site Generation (SSG), Server-side rendering (SSR), Incrementatal-static Regeneration (ISR), and Client-side rendering (CSR).
Even though we use similar methods like ISR, SSG, SSR, and CSR for fetching and rendering data, these methods are like tools in a toolbox. We use them differently for getting data ready and making it look great on your website.
To see, how these methods work for rendering, click here.
Data fetching is the process of obtaining data from a database or API, which is then used to generate the HTML of a page. The choice of data fetching strategy often depends on the nature of the data, the response times, and the user experience we aim to provide.
Let’s explore each of these methods.
Static Site Generation pre-renders pages at build time, making it an excellent choice when dealing with static content. It ensures rapid content delivery and high performance.
Next JS offers two main functions for SSG:
getStaticProps
getStaticPaths
getStaticProps
The getStaticProps
fetches data at build time and uses it to generate a static HTML page. Consider the following code example:
import React from 'react'; export async function getStaticProps(context) { const res = await fetch('https://jsonplaceholder.typicode.com/posts'); const posts = await res.json(); return { props: { posts, }, }; } function Blog({ posts }) { return ( <div> <h1>Blog Posts</h1> <ul> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> </div> ); } export default Blog;
In the example above, we’re fetching posts from an API at build time, and this data is passed as a prop to the Blog
component.
getStaticPaths
The getStaticPaths
specifies dynamic routes that are rendered at build time.
export async function getStaticPaths() {return {paths: [{ params: { id: '1' } },{ params: { id: '2' } }],fallback: false};}export async function getStaticProps({ params }) {// Fetch necessary data for the blog post using params.id}export default function Post() {// Render post...}
In the example above, pages with the ids 1
and 2
are pre-rendered at build time. The fallback: false
means that any paths not returned by getStaticPaths
will result in a 404 page.
Server-side rendering is the process of generating the HTML of a page on each request. SSR is a good choice when dealing with dynamic and user-specific data.
For SSR, Next JS provides the getServerSideProps
function.
getServerSideProps
The getServerSideProps
fetches data on each request. This function runs at request time, meaning the data passed to the page is always fresh.
Here’s a simple example:
import React from 'react'; export async function getServerSideProps(context) { const res = await fetch('https://jsonplaceholder.typicode.com/posts'); const data = await res.json(); return { props: { data, }, }; } export default function Blog({ data }) { // Render data... return ( <div> <h1>Blog Posts</h1> <ul> {data.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> </div> ); }
In the example above, the Blog
component will always receive the freshest data from the API because the fetch is done at the request time.
Client-side rendering fetches data from the client-side, after the initial page render. CSR is a good choice for non-essential data or data that doesn’t affect SEO.
In Next JS, CSR is performed using React hooks like the useEffect
in combination with the fetch API or libraries like axios.
Here’s a CSR example:
import React, { useState, useEffect } from 'react'; function Home() { const [data, setData] = useState(null); useEffect(() => { async function fetchData() { const res = await fetch('https://jsonplaceholder.typicode.com/posts'); const json = await res.json(); setData(json); } fetchData(); }, []); // Render data... return ( <div> <h1>Posts</h1> <ul> {data && data.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> </div> ); } export default Home;
In this example, data is fetched from the client side after the initial page render.
Incremental Static Regeneration enables us to implement static generation without requiring a complete site rebuild. Instead, updates to static pages are triggered at intervals predetermined by us. This method permits the modification of static pages post-build, and using ISR, you can use the advantages of static generation while effectively handling a large number of pages.
import React from 'react'; export async function getStaticProps(context) { const res = await fetch('https://jsonplaceholder.typicode.com/posts'); const posts = await res.json(); return { props: { posts, }, revalidate: 60, // Re-generate the page every 60 seconds }; } function Blog({ posts }) { return ( <div> <h1>Blog Posts</h1> <ul> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> </div> ); } export default Blog;
The code above is similar to SSG, except that the revalidate
property is added within the getStaticProps
function. This property indicates how often Next JS should attempt to re-generate the page content, allowing it to stay up-to-date with potential changes in the data source. In this example, the page will be re-generated every 60 seconds (revalidate: 60
).
Selecting the appropriate data fetching strategy can have a significant impact on the performance of your Next JS application. Here are some key points to consider when deciding:
Static Site Generation (SSG): Ideal for content that can be generated at build time and doesn’t change often. It offers high performance and SEO benefits.
Server-side rendering (SSR): Best suited for pages that need fresh data on each request, which can’t be achieved with SSG. It offers real-time data but may increase server load.
Client-side rendering (CSR): Suitable for non-critical data that doesn’t need to be pre-rendered for SEO purposes. It decreases server load but may not provide the best initial load performance.
Next JS provides flexible data fetching strategies that can fulfill various application requirements, improving performance and enhancing user experiences. Learning these techniques allows you to optimize your Next JS applications effectively.
Free Resources