Open In App

Next.js Data Fetching

Last Updated : 24 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Next.js is a popular React-based framework that allows developers to build server-side rendered (SSR) and statically generated web applications with ease. One of the most important aspects of building web applications is data fetching, which refers to the process of getting data from a server or an API and displaying it on a webpage.

Before we get started, let’s briefly discuss the different types of data fetching techniques available in Next.js.

  • Static Site Generation(getStaticProps): This technique pre-generates the HTML at build time and serves it as a static page. This approach is ideal for websites that do not require real-time data and have a low frequency of updates.
  • Server-Side Rendering(getServerSideProps): This technique renders the HTML on the server and sends it to the client. This approach is ideal for websites that require real-time data and have a high frequency of updates.
  • Dynamic Routing(getStaticPaths): This technique pre-renders pages for dynamic paths at build time. This approach is ideal for websites that have dynamic content and require SEO optimization.

We will build a simple application that fetches data from an API and displays it on a webpage. The API we’ll be using is the JSONPlaceholder API, which provides fake data for testing and prototyping.

Our application will display a list of blog posts on the homepage, and when a user clicks on a post, they will be taken to a detailed view of the post.

Getting Started: To get started, we’ll need to create a new Next.js application. Open up your terminal and run the following command:

npx create-next-app data-fetching

This will create a new Next.js application in a directory called NextJS-data-fetching.

Next, navigate into the directory by running 

cd data-fetching

Example 1: Fetching Data with getStaticProps: To fetch data using Static Site Generation, we’ll need to create a function called getStaticProps. This function will run at build time, and the data returned will be used to pre-generate the HTML. 

  • pages/index.js:

Javascript




import Link from "next/link"
  
const Home = ({ posts }) => {
    return (
        <div>
            <h1>Latest Posts</h1>
            <ul>
                {posts.map(post => (
                    <li key={post.id}>
                        <Link href={`/post/${post.id}`}>
                            {post.title}
                        </Link>
                    </li>
                ))}
            </ul>
        </div>
    )
}
  
export async function getStaticProps() {
    const res = await fetch('https://[Your API]/posts')
    const posts = await res.json()
  
    return {
        props: {
            posts,
        },
    }
}
  
export default Home


Steps to run: Run the command in terminal.

npm run dev

This will start the server at http://localhost:3000

If you open your browser and navigate to http://localhost:3000, you should see a list of blog posts.

Output: It will display the result on the basis of API call.

In this example, we’re using fetch to fetch a list of posts from the JSONPlaceholder API. We then return the list of posts as props to the Home component. getStaticProps is a function that is executed at build time and generates a static HTML page that is served to all users. It can fetch data from any data source and return it as props to the page component. 

Example 2: Fetching Data with getServerSideProps: To fetch data using Server-Side Rendering, we’ll need to create a function called getServerSideProps. This function will run on the server and the data returned will be used to render the HTML. Create a new file called posts/[id].js in the pages directory and add the following code:

Javascript




import React from "react";
import Link from "next/link";
  
const Post = ({ post }) => {
    return (
        <div>
            <h1>{post.title}</h1>
            <p>{post.body}</p>
            <Link href="/">Go back to homepage</Link>
        </div>
    );
};
  
export async function getServerSideProps({ params }) {
    const res = await fetch(
        `https://[Your API]/posts/${params.id}`
    );
    const post = await res.json();
  
    return {
        props: {
            post,
        },
    };
}
  
export default Post;


Let’s break down this code. We define a functional component called Post, which receives a post object as a prop. We display the title and body of the post and provide a Link to go back to the homepage.

The getServerSideProps function is an asynchronous function that fetches data for a specific post from the JSONPlaceholder API based on the id parameter in the URL. The props object returned will be passed as props to the Post component when it is rendered.

Now, if you click on a blog post from the homepage, you’ll be taken to a detailed view of the post that was fetched using SSR.

Output:

 

Example 3: Fetching Data with getStaticPaths: Create a new directory user in the pages directory, inside it create a new file called [id].js, we’ll fetch a list of posts by a specific user from the JSONPlaceholder API using getStaticPaths and getStaticProps. We’ll also use dynamic routes to create a separate page for each user.

Filename: user/[id].js

Javascript




import Link from "next/link";
  
const User = ({ user, posts }) => {
    return (
        <div>
            <h1>{user.name}</h1>
            <p>{user.email}</p>
            <h2>Posts by {user.name}</h2>
            <ul>
                {posts.map((post) => (
                    <li key={post.id}>
                        <Link href={`/post/${post.id}`}>
                            {post.title}
                        </Link>
                    </li>
                ))}
            </ul>
        </div>
    );
};
  
export async function getStaticPaths() {
    const res = await fetch("https://...com/users");
    const users = await res.json();
  
    const paths = users.map((user) => ({
        params: { id: user.id.toString() },
    }));
  
    return { paths, fallback: false };
}
  
export async function getStaticProps({ params }) {
    const [userRes, postRes] = await Promise.all([
        fetch(`https://[Your API]/users/${params.id}`),
        fetch(`https:[Your API]/posts?userId=${params.id}`),
    ]);
  
    const [user, posts] = await Promise.all(
        [userRes.json(), postRes.json()]);
  
    return {
        props: {
            user,
            posts,
        },
    };
}
  
export default User;


In the example above, getStaticPaths is a function that generates an array of paths based on dynamic data. In this case, we’re fetching a list of users from the JSONPlaceholder API and generating a path for each user’s ID. We then return an object that contains the paths and sets fallback to false. getStaticProps is a function that is executed at build time for each path generated by getStaticPaths. We then return the user’s details and the list of their posts as props to the User component.

In the getStaticProps function, we’re using Promise.all to fetch the user’s details and a list of their posts in parallel. We then return the user’s details and the list of their posts as props to the User component.

Filename: index.js 

Javascript




import Link from "next/link";
  
const Home = ({ users }) => {
    return (
        <div>
            <h1>Users</h1>
            <ul>
                {users.map((user) => (
                    <li key={user.id}>
                        <Link href={`/user/${user.id}`}>
                            {user.name}
                        </Link>
                    </li>
                ))}
            </ul>
        </div>
    );
};
  
export async function getStaticProps() {
    const res = await fetch("https://[Your API]/users");
    const users = await res.json();
  
    return {
        props: {
            users,
        },
    };
}
  
export default Home;


Output:

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads