In this section we've seen different ways
to render our pages with Next.js.
Let's do a quick recap now,
so you can better understand when to use
which approach in your own projects.
We started the course by using static
rendering for everything.
All our pages were generated at build time,
which meant we could also export
our app as a static website.
This approach has the advantage that,
for every request,
the server just needs to return
an existing HTML file.
That means our users can get
a response very quickly,
and the server doesn't use much
CPU or other resources.
At the other end of the spectrum
we have dynamic rendering,
where each page is generated at run time,
every time a client requests it.
This allows us to display the latest data,
but it comes at the cost of slower response times,
and higher server utilization.
Next.js then provides some features that sit
somewhere in the middle between
these two extremes.
If we have a dynamic route, like our ReviewPage,
we can write a generateStaticParams function
and render all possible pages
statically at build time.
However if we request a new path at runtime
by default Next.js will generate
the new page on demand.
This way all our pages are static,
but we can still add new pages without
redeploying our application.
Then we've seen Time-based Revalidation,
which lets us generate static pages
but also make them expire after
a certain number of seconds,
causing them to be regenerated periodically.
So if the data changes the pages will update,
albeit not immediately, but after
the time interval expires.
On-demand Revalidation is even better
in that it lets you rerender your pages
as soon as the data changes,
and only when the data changes.
If you use a CMS that supports
webhook notifications,
or have some other way to know exactly
when the data is modified,
this can be a great solution.
Now, I shall also point out that
all these approaches are server based.
Whether our pages are rendered
statically or dynamically,
the data is always loaded on the server,
in a React Server Component,
and the server returns prerendered
HTML to the browser.
It's also possible to load
data on the client side,
calling "fetch" in the browser.
This is how traditional Single
Page Applications work,
and you can still do that even with Next.js,
by using Client Components.
Although if you fetch data on the client side,
you lose all the advantages of prerendering.
So, given all these different options,
which one should you choose?
As always, it depends on your requirements.
If you have a page showing
data that never changes,
obviously it should be static.
If the data can change, but it's
the same for all users,
then you can opt for one of
the "static+" approaches.
If you only want to be able to add new pages,
then the default dynamicParams
behavior may be enough.
While if you also need to modify existing content
then you can use Revalidation.
Either On-demand Revalidation,
if you have a way to get notified
when the data changes,
or otherwise use Revalidation
with a time interval.
If your page must display the very latest data,
or user-specific data, that's
different for every request,
then you need dynamic rendering.
In this case you could also consider
client-side data fetching.
We'll see an example of that in a later section.
Now, from our previous videos we know that
when using "fetch" to load data,
the fetch options can affect
how the page is rendered.
Fetch and rendering usually go hand in hand,
however they are two separate things,
and there are cases where they
can behave differently.
Let me go through a few examples.
If we set "force-dynamic" in our page
that also disables the fetch cache.
This is documented in the Next.js reference
for the "dynamic" option.
If we configure our page to "revalidate",
that will effectively apply the same
setting to any "fetch" requests.
So, usually the options we set in our page
will propagate to the "fetch"
requests made by that page.
But, we can also choose to configure
the "fetch" calls instead.
If we set "cache" to "no-store"
that will cause our page to
be rendered dynamically.
We've seen this in one of our tests.
And if we set "revalidate" for a fetch request,
that will also cause the page to be regenerated
based on the same time interval.
Now, let's take a look at some other scenarios.
The same page could make more
than one fetch request,
if it includes multiple components
that display different data.
And each fetch request could set its own options,
like different "revalidate" intervals.
In that case when rendering the pageÂ Next.js
will use the shorter interval,
because if some data can change more often
then the page also needs to be re-rendered
at the same frequency.
Similarly, if one fetch request uses revalidation,
but another one sets "cache" to "no-store",
then disabling the cache will take precedence,
meaning the page will be treated as dynamic.
Another interesting case is
what happens if we have conflicting values
in the page configuration versus
the fetch configuration?
For example, if the page sets a
longer "revalidate" interval.
Again, the shorter interval wins,
meaning that the page configuration will effectively
be overwritten by the fetch value.
In all these examples,
in the end Next.js will use similar settings
for both fetch and page rendering.
But that's not always the case.
If we don't set any options,
then fetch will cache all responses by default.
While the page will use "dynamic: auto",
which will try to cache as much as possible.
Frequently this results in the page to be static.
And, again, that's in line
with the fetch behavior.
But in some cases the page will
be treated as dynamic instead.
This happens if, for example,
you have a dynamic route without
"generateStaticParams".
In this case the page will be rendered
dynamically at every request,
but fetch will use cached data.
We'll see an example of this in the next section.
Now, some of you may be thinking:
what if I'm not using "fetch" in my application?
What if I'm loading data directly
from a database instead?
In that scenario you can always
use the page-level settings,
because after all your database will only
be called when the page is rendered.
But if you do need to manually
cache database results,
React provides a "cache" function to do that.
You can find out more in the
Next.js documentation.