By adding an API route
and calling it from the client side
we covered all possible ways
to fetch data in a Next.js app.
So it is now time to decide
which one is the best option
in our particular case.
Let's review our options quickly.
Option 1a is to fetch products on the server side
using "getStaticProps".
This way the product data
is fetched at build time,
and included in the statically generated page,
which means the page loads very quickly
and it's also easily indexable by search engines.
Approach 1b is similar, but with the addition
of the "revalidate" option,
which results in Incremental Static Regeneration.
This means we get all the benefits of
a statically generated page,
but the page will be regenerated periodically
which means that if the data changes in the backend
the page will also be up to date.
The only downside is that
this approach is not compatible
with exporting the website statically
using the "next export" command.
Option 1c uses "getServerSideProps",
which means the data will be fetched
on the server side but at runtime,
that is on every request.
This approach is similar to using
traditional server side frameworks
like Ruby on Rails, or PHP for example,
in that the server generates
the HTML page dynamically on every request.
Moving on, we have option 2a
that is to fetch the data on the client side,
directly from the backend API,
that in our case is the Strapi CMS.
This is a valid approach if we want to fetch
fresh data every time,
and it's ok to access the backend API
directly from the browser.
Alternatively, we can opt for 2b
which is similar but fetching the data
from an API route
that's on this same Next.js app,
so the browser doesn't need access
to the backend API.
This requires writing an API handler,
that runs on the Next.js server
and fetches the data from the backend CMS.
possibly transforming the data in the process.
So we have 5 different options,
which I have summarised in this table.
Which one is the best
depends on your specific requirements,
and the best choice may be different
for different types of data,
even inside the same application.
For example, if you want to be able to
export your app as a fully static website
using the "next export" command
then that means you cannot use
Incremental Static Regeneration
or Server-side Rendering,
so your choice narrows down to 3 options.
While if you want your data
to be easily indexed by search engines
then you need to choose an approach
where the HTML is generated by the server.
To help you with the choice I have prepared
a simple flow chart.
I believe the first question
you should ask yourself is:
is this data going to be the same for all users?
For example, if we have a list of products
in a shop website, then the answer is "yes":
all users that visit our shop
should see the same products.
But if we're talking about
a user profile page for example,
where the user can enter or update
their address details,
in that case the answer will be "no":
each user will see different data.
Now, if the data is the same for all users
that points to a server-side approach
because the server can generate a page
and reuse it for all users,
including search engines.
In this case the next question I propose is:
can the data change?
So if we have a list of products,
can those products be updated,
or can we add new products?
And in that case, do we expect the page
to automatically reflect those changes?
If the answer is "no":
then we can use Static Generation.
If our list of products is fixed,
then we can statically generate the page once
and always return the same page.
On the other hand, if we want our page
to automatically update when the data changes
then the best approach is
Incremental Static Regeneration.
And this is in fact probably the best choice
for the products on our website.
There is a backend CMS, where the shop staff
could go and edit the products at any time,
and we want our website to update automatically.
But it's ok if a new product
doesn't show up immediately,
but say within 5 minutes,
or whatever we set as the "revalidate" period.
Now, let's go back to the initial question,
that is: is the data the same for all users?
If the answer is "no",
which means the data is user-specific,
this points to fetching the data on the client side.
Because we want to fetch the data
for that specific user.
So at this point we should consider if
it's ok to access the backend API directly
from the users' web browser?
If the answer is yes,
then that's what we'll do.
But frequently the answer is "no",
which means we need to write an API route,
that acts as a proxy
between our frontend app running in the browser,
and the backend API where the data is stored.
Now, you may have noticed that
among the possible choices here
I didn't include the "getServerSideProps" approach.
And that's deliberate, because
based on my own experience, with Next.js
there are usually better options.
But that's just my opinion,
maybe you will find a use case where
"getServerSideProps" is in fact a good choice.
So hopefully this flow chart will help you
in choosing the right approach
for your own use cases.
But to go back to our product list example,
I mentioned that the best choice
is probably Incremental Static Regeneration.
So let's now go back to our application,
and select option 1b, that is ISR.
What I'm going to do is copy this whole file
into the original "index" page.
And, we can remove this comment at the top.
Also, we set "revalidate" to 30 seconds for testing,
but a more appropriate value for production
is usually something like 5 minutes.
Ok. At this point we can go and delete
all the other "index" pages
with all the different data fetching options.
And we're left with a single "index" page,
that will be visible at the root of our website.
Now, I actually forgot about our API route.
Since we deleted the version
of the "index" page that was using it
we can delete the API route as well.
And with this, we are ready
to continue developing our shop website,
adding some more functionality.