In the previous post, we saw how to read and write data from and into a local JSON file in an Next.js app.
You don't need to read that to go through this post.
Now, we take a step further and fetch data from a server through a REST API. The same works for getting data from the file system (if you don't use routes), or databases.
Fetching Data & Pre-rendering
Fetching data from an exernal source brings us back to the concept of pre-rendering.
In short, Next.js creates the HTML for each page in advance to improve performances.
You can build on pre-rendering in two ways:
- using
getStaticProps()
if the content to get from the external API doesn't change frequently. ThegetStaticProps()
function is used to fetch data at build time. - using
getServerSideProps()
when the content changes more frequently. ThegetServerSideProps()
function fetches data on every request, and is used for dynamic pages that need to be updated frequently.
Using Static Generation To Fetch Data From A Server
Inside the lib folder we create a new file and we call it users.js.
In this file, we will store the logic to fetch data from Jsonplaceholder.
The following code creates an asynchronous function called getUsers()
. It uses the fetch API to get data from jsonplacceholder.
If the Promise completes successfully, it returns data in a JSON format.
export async function getUsers() {
// Fetch data from an external API endpoint
const res = await
fetch('https://jsonplaceholder.typicode.com/users')
if (!res.ok) throw new Error('failed to fetch data')
return res.json();
}
Fetch Data With getStaticProps()
Now, inside index.js we can take advantage of the async getStaticProps()
function to call getUsers()
.
First, we need to import getUsers()
in index.js as follows:
...
import { getUsers } from '../lib/users'
Then, we need to declare the async getStaticProps()
function outside the Home component. Here you can see the structure of the Home component in index.js at this point.
...
import { getUsers } from '../lib/users'
export async function getStaticProps() { ... }
export default function Home({ localData }) { ... }
In the body of getStaticProps()
we can add the code to trigger getUsers()
.
Don't worry about localData, that is a piece of code from the previous article where we got data from a local JSON file.
We assign the data from getUsers()
to the users variable and we return it as a property.
Notice that we pass the property to the Home component as well.
...
import { getUsers } from '../lib/users'
export async function getStaticProps() {
const users = await getUsers()
const localData = await getLocalData()
console.log(users);
return {
props: {
localData,
users
},
};
}
export default function Home({ users, localData }) { ... }
Finally, notice the console.log(users);
.
You will not see the log in your browser's console because it runs on the server-side and not on the client-side.
Therefore, you will see the log in the terminal you use to run your Next.js application.
By adding some JSX code inside the Home component you can get the list of users on screen (CSS omitted for clarity).
<section>
<h2>Users</h2>
<ul>
{users && users.map(({ id, name, website }) => (
<li key={id}>
{id} - {name}
<br />
{website}
</li>
))}
</ul>
</section>
The line below
{users && users.map(({ id, name, website }) => (
uses the logical AND (&&) operator to run the map method on users
only if users
is truthy.
You might get something like this:
Other JavaScript operators you may want to know:
Fetch Data With getStaticProps()
The getServerSideProps
function is used to fetch data on every request, and is used for dynamic pages that need to be updated frequently.
In this example we can simply swap 'getStaticProps' for getServerSideProps
and the code will run just fine.
However, rememebr that
-
getStaticProps()
fetches data at build time and it is a good choice if the content to get from the external API doesn't change frequently. -
getServerSideProps()
fetches data on every request, and is used for dynamic pages that need to be updated frequently.
Top comments (9)
Yeaaaaa great you made it thanks for your input💪💪💪💪
I’m thinking of making another post for this series with a new app including what I learned + deployment. Maybe I’ll have time next week:)
Are you working on a personal project?
Yes with Next.js but the project will include login,signup,dashboard with user profile,search option,list display,single detail page,payment method,api and database yes something like that in a components bases someone can use in a real world application.thanks you covered api👍,i'm following you
Thanks a lot. You are a good teacher.
your articles is so great! i love you split you journey articles into small chunk. im also new with next js, and i tried to create a simple CRUD budget app that would track your income / expense with next js, but i have a problem with the fetching data.
so when i tried to add new income / expense data, the new data added is not automatically updated to the display, i need to refresh the page first to get the new data. i used
getServerSideProps
to fetch data from the api. by usinggetServerSideProps
it should be automatically fetch the data right? or am i missing something?Hey thanks!
It’s hard to help without seeing the code. But it sounds like you 1) request initial data when you visit the page 2) update data on server 3) expect the updates to reflect in your app. However 3) doesn’t happen because the backend doesn’t “push” the changes to the frontend.
You might set up your API to support POST requests that return updated data
Thanks for this piece of information.
I do the same like this but have problem. Rendering page is too slow. I used shallow routing and it ISC help.
But I want without it?
Could you share some code?