I Was Surprised How Next.js Cached My Server Components
Summary
TLDRIn this video, the creator delves into Next.js 14's caching mechanisms, highlighting challenges faced while updating a Zeta database-driven deals page. They explore static and dynamic routes, the use of 'revalidate' for cache control, and the impact of server components on caching. The script also uncovers why certain pages aren't statically built, discusses the role of Clerk for authentication, and introduces methods to force cache updates, providing insights into optimizing Next.js applications for performance.
Takeaways
- π The speaker spent two hours trying to understand caching in Next.js 14 and discovered various caching mechanisms.
- π The speaker's investigation into caching was prompted by issues with their 'deals for dev' page not reflecting updates in real-time.
- π οΈ They added a 'revalidate' parameter to the homepage to ensure it's only cached for a maximum of 2 minutes, forcing updates to be visible more quickly.
- π The speaker learned about different types of caching Next.js performs, including static route caching and dynamic route considerations.
- π« Static routes are cached by default in Next.js, whereas dynamic routes are not cached unless specifically configured to be so.
- π The use of 'generateStaticParams' can pre-render dynamic routes at build time, allowing them to be cached.
- π During the build process, Next.js indicates whether pages are built statically or dynamically, providing insight into caching behavior.
- π The speaker suggests using 'revalidate' as a method to manually trigger updates for cached pages.
- π‘ The speaker recommends implementing automatic revalidation for pages that are updated through an admin dashboard to ensure consistency across the site.
- π The speaker discovered that certain pages were not being cached due to the use of 'Clerk Provider' for authentication, which references header information.
- π The video also highlights the importance of understanding the documentation for Next.js caching to troubleshoot and optimize caching behavior.
Q & A
What issue did the speaker face with Next.js caching?
-The speaker faced an issue where updates made directly to the database were not reflected on the Next.js page until it was reloaded, which was confusing and indicated a caching problem.
What is the purpose of the 'revalidate' function in Next.js?
-The 'revalidate' function in Next.js is used to specify how long a page should be cached. After the specified time, the page will revalidate and rebuild, ensuring that the user gets the most recent version of the page.
What is the difference between static and dynamic routes in Next.js?
-In Next.js, static routes are regular page routes that do not contain dynamic parameters, while dynamic routes include parameters denoted by brackets, such as a specific ID for a given deal.
How can you make a dynamic route in Next.js cacheable?
-You can make a dynamic route in Next.js cacheable by using 'generateStaticParams' to define all the individual routes for that dynamic route. This allows Next.js to generate these pages at build time and cache them.
What does ISR stand for in the context of Next.js?
-ISR stands for Incremental Static Regeneration in Next.js, which is a feature that allows pages to be generated at runtime and then cached for better performance.
How can you check if a page in Next.js is built statically or dynamically?
-You can check if a page is built statically or dynamically by running a local build of your site. Next.js will indicate for each individual page whether it is static or dynamic.
What is the role of 'daily.dev' as mentioned in the script?
-'daily.dev' is a content aggregation platform that the speaker uses to stay updated with the latest industry content, including articles and podcasts on topics like JavaScript and Next.js.
Why were some pages not being cached in the speaker's Next.js application?
-Some pages were not being cached because they were accessing information in the headers, search parameters, or cookies, which automatically opts out of full route caching in Next.js.
What is the significance of using the Clerk provider in the speaker's Next.js application?
-The Clerk provider is used for authentication in the speaker's Next.js application. It was found that using the Clerk provider can cause certain routes to be considered dynamic due to the provider's internal use of header information.
What is the recommended approach to handle caching for admin dashboard updates in Next.js?
-The recommended approach is to implement a 'revalidate path' feature that can be triggered after updates in the admin dashboard, ensuring that the updated information is reflected on the corresponding pages by invalidating the cache.
What tools and services are used in the speaker's Next.js project?
-The speaker's Next.js project uses Zeta as a database with a UI for direct database manipulation, Prisma for integration with a PostgreSQL database, Sentry for error tracking and alerting, and Clerk for authentication.
Outlines
π€ Caching Confusion in Next.js 14
The speaker delves into an exploration of caching mechanisms in Next.js version 14, prompted by issues with their deals for dev's page, which failed to reflect real-time updates from the Zeta database. They discuss the discovery of static and dynamic routes, the default caching behavior of static routes, and the implementation of the 'revalidate' function to address the issue. The speaker also hints at a more efficient caching strategy to be introduced later in the video.
π Understanding Static and Dynamic Pages in Next.js
This paragraph discusses the distinction between static and dynamic pages in Next.js, highlighting how static pages are cached by default and dynamic pages are not. The speaker shares insights on identifying statically built pages during the build process and mentions a sponsor, daily.dev, as a valuable resource for staying updated with industry content. They also touch upon the use of 'generateStaticParams' to cache dynamic routes and speculate on ISR (Incremental Static Regeneration) functionality.
π οΈ Advanced Caching Strategies and Debugging Tips
The speaker provides a deeper dive into caching, explaining the difference between router cache and full route cache, and how certain actions like accessing headers or search parameters can opt pages out of full route cache. They also share a debugging experience related to specific pages not being statically built or cached, attributing the issue to the use of the Clerk provider which references header information. The paragraph concludes with a preview of advanced caching strategies, including the use of an API endpoint for manual revalidation and the implementation of revalidate paths for auto-updating content.
Mindmap
Keywords
π‘Caching
π‘Next.js
π‘Revalidate
π‘Zeta Database
π‘Static Route
π‘Dynamic Route
π‘Generate Static Params
π‘Incremental Static Regeneration (ISR)
π‘Server Components
π‘Full Route Cache
π‘Daily.dev
Highlights
Investigation into caching in Next.js version 14 after experiencing issues with a live stream.
DealsForDev.com utilizes Zeta database for data storage across various applications.
Issues with not seeing updated content on the homepage despite database changes, leading to confusion.
Introduction of 'revalidate' function to limit page cache duration to 2 minutes.
Explanation of Next.js caching behavior for different page types, including static and dynamic routes.
Static routes in Next.js are cached by default, unlike dynamic routes which are not cached at all.
Use of 'generateStaticParams' to statically cache dynamic routes at build time in Next.js.
Incremental Static Regeneration (ISR) may work to update and cache new pages as they are navigated to.
Local build of a Next.js site reveals whether pages are built statically or dynamically.
Daily.dev as a sponsor, a platform for staying updated with the latest industry content.
Discovery of pages not being statically built due to referencing headers, search params, or cookies.
Clerk provider's use of header information causing admin routes to be considered dynamic.
Introduction of an API endpoint 'revalidate' to manually trigger page revalidation.
Implementation of revalidate path in admin dashboard for automatic page updates upon content changes.
Overview of Next.js caching, including full route caching and client-side routing caching.
Integration of technologies like Clerk for authentication, Zeta database, Prisma, and Sentry in the DealsForDev project.
Invitation for feedback and suggestions on caching strategies in the comments section.
Transcripts
well I just spent about two hours on a
live stream trying to figure out caching
in nextjs specifically 14 and I found
out a bunch of different things that I
had no idea what was going on so I'm
curious as you go through these videos
let me know what of these different
specific ways that nextjs cashes or
doesn't did you already know or did you
find out as well let me know in the
comments so the reason I started digging
into this was because of my deals for
dev's page this is deals Ford dev.com
the hottest deals for developers that
you should go check out at deal ford.com
but what would happen is I would go into
my Zeta database so I use Zeta for
storing all of our data I use this in a
bunch of different applications uh so I
have my deals for dev's database I have
all this information here and what
happened is we don't have a full admin
dashboard yet so we have admin dashboard
and then deals I don't have full like uh
crud operations for uh the deals that
people submit so because of that what
would happen is if I needed to make a
change to that conference for example I
would go into the database I would find
that deal and because Zeta has a UI I
would manually update that to like
updated that conference or whatever that
is but then when I would come to this
page I wouldn't see if I would refresh
and I would refresh I would refresh
refresh I wouldn't see that that
conference had the updated title which
is super confusing but if I then went to
the details page for that conference I
would see that it was updated here so I
was super super confused by this and
what I did I didn't fully understand
caching at the time so I've gotten a lot
better what I did do though is go to the
homepage and I added this revalidate
function or parameter which basically
says that this page should only be
cashed for 2 minutes at Max so it'll
cash it and then if someone comes within
the next two minutes they'll still get a
cash version if they come after that two
minutes it will revalidate it'll rebuild
this page and then cash it for another
two minutes and this is because uh Chris
Wix who's been working with me kind of
mentioned like hey this does cashing
that you need to account for now this is
not the best way to handle this and I'll
show you a much better option later on
in the video what I've learned though is
how and why and when and where nextjs is
doing the caching for the different
types of pages that I have here so quick
question for you do you know why this
individual page for this individual deal
does not get cashed versus the homepage
does get cashed let me know in the
comments and we'll go ahead and uh dive
into that right now so what nextjs does
is by default any static route does get
cashed so as I even though this is all
run on the server this is a server
component by default and I'm running
this on the server and then I pass it
down to things down here without this
line here this gets cashed
forever and they do that based on a
static route which I hate this name of
static route because we now are mixing
this with what static Pages were and any
like a static route now interestingly in
the nextjs world is defined by just a
regular page route so an example of that
is at the root of this under the root of
the app directory in xjs 14 I have this
page component it's not a dynamic route
in the sense that it doesn't have if we
look inside of deals a dynamic route
like this which is referencing the ID of
a given deal with me so static page
because it doesn't have a dynamic route
so the difference between these two
pages is this is a static route so it
gets cached and it stays cached until
you tell it not to be you can do that
with the revalidate thing I'm going to
fix this and find a better way that I'll
show you in a minute in a second I you
don't want to do that because this is
basically not caching this at all when
it could be there's a better way to do
this I'll show you that in a second but
if I go to the deals page because this
is a dynamic route because we have this
Dynamic param denoted by the brackets uh
category Pages same thing but ID here
because of that this is not cached at
all and it's going to be loaded on the
server every time now interestingly in
nextjs you can also fix that to be able
to statically cach those pages by
referencing uh or using this is
something I'll make an update to using
generate static perams with that it's
similar to how you built static pages
with nextjs 12 and before with get
static props where you're defin defining
all of the routes for that Dynamic route
so all the individual routes for that
Dynamic route you define those and then
based on that it's going to generate
those pages at Bill time and cash them
and my assumption is I still have to
test this so don't don't take my word
from it is ISR incremental static
regeneration will work so that as I add
a new deal it will automatically build
that page as the user navigates to it
and then we'll cash that after the fact
that's my assumption but I do know if
you call this at build time it will
statically build all those pages under
that Dynamic route but now these are
static Pages all right still with me so
I did have an interesting thing and this
is something for you to know if you ever
want to know which of your pages is
actually built statically or dynamically
and there's something interesting that
you'll see in here you can run a build
of your site locally and it will
actually show you for each individual
page that it built you'll see static or
dynamic so we'll pause and let this
finish then I'll show you the results
and there is a couple in here that you
may not have expected that I didn't
expect at all that I have since learned
why they are the way they are but we'll
get to that in a second now while that's
building I want to give a shout out to
the sponsor of this video which is daily
dodev one of my favorite companies and
the world now I consume a ton of content
to stay up-to-dated to create the
YouTube videos that you see here I watch
videos listen to podcast and read a ton
of Articles a lot of which I find on
daily. deev so this is my homepage on
daily. deev where I can see a bunch of
different articles
on different topics that are interesting
to me based on preferences that I have
input for myself now you can search and
here by things like tags of JavaScript
this is something I do very often and
had I spent a little bit of time to look
up nextjs caching I could have found a
few resources in here to solve all the
time that I spent trying to figure that
out on my own now one last thing I want
to show you is the ability to bookmark
items so that you can come back and
check those out later which is really
really nice now the last thing I'll say
is is daily. deev is the only website
that I allow notifications inside of my
browser because I love it that much so
if you're looking for an easy way to
stay up to date with the latest content
in the industry JavaScript nextjs Etc
check out daily dodev daily dodev all
right cool so that just finished so the
key thing is at the bottom of this you
have uh an o or a circle and an f o or
circle is static it's pre-rendered AES
static content uh f is dynamic so if we
go back through and kind of talk about
what we've been looking at the homepage
is
static good that's what we expected
let's jump down the SL deals page static
all right what we expected this Dynamic
route for that includes ID is dynamic
have I been saying this right so
static and CA static and cached then
this one is dynamic and not cached so
this is always served rendered it's
always going to make a request to the
server and then we have a bunch of pages
that are also static then we have a
dynamic route which as you'd expect is
dynamic
but there are a couple different things
that stand out one all API in points are
Dynamic that totally makes sense they
are not cached and then we have these
random routes confirm and
preferences that are not Dynamic routes
but are somehow not statically built and
cach now the reason is and I'll I'll let
me actually pull this up let's open the
subscriber and the
confirm and our initial thought when we
were debugging this is because it's
under this group layout which group
layout shouldn't make any difference but
we we just didn't know why these two
were having that problem so I'm going to
scroll down to a little bit of
code and see if you can figure out why
this thing is not being cached and is
considered a dynamic route of some sort
pause go let me know in the comments did
you get it all right so if we come back
I think I've got a nexts documentation
Page open somewhere that I really liked
okay I had to dig to find this this is
in the api's chart on the documentation
for caching and if we scroll down you
can see there's a couple options in here
that opt out of what is called Full
route cache so there's a couple
different ways that nextjs is doing
caching there is router cache which is
on the client so as you go from one page
to another and on that first page you
query data you go away you come back it
doesn't uh it doesn't query that data
again it actually takes that data from
the cache and then you have full route
cache which is what I've been talking
about for full individual Pages or
routes and if you scroll down if you
access anything in the headers or the
search prams or cookies you're
automatically opted out of caching now
this makes total sense when you break it
down because if you reference some
something in search prams that page is
probably going to be based on that that
makes total sense
but that's so subtle like you have to
dig all the way down here to find this
out so I had these pages that were
rendering
as or not being statically built and I
was like I don't know why this is
happening and had to really dig down and
actually kind of experiment to figure
out why that was happening and here it
is so going through this documentation
and going through this chart one that's
a lot to to do but maybe it's essential
to figure out exactly when and where
things are happening now the other thing
I wanted to show you is all of the admin
routes so under admin under admin all of
these were considered uh how do they
even phrase this is it Dynamic yeah just
Dynamic pages so server rendered on
demand now the reason or the interesting
thing about this is if we go to the
layout for admin we're wrapping all this
stuff with the clerk provider and
there's two things or one question and
then one answer I'll give you one in the
documentation for Clerk and using the
clerk provider for
authentication we don't use use client
typically if you're using like a
provider in context API you have to have
used client this doesn't have it I'm
assuming clerk provider actually used
used client anyway like beh like behind
the scenes it uses it and we don't even
know it so we don't have to add it but I
feel like that's something that would be
worth knowing and then what we found is
inside of the clerk provider if you go
into the source code they're actually
referencing Header information which
then makes all of these routes under
admin let's see under admin all these
routes are Dynamic so there's this
incredible mix of uh statically built
Pages even though they're using server
components those two things combined
don't really make sense and I feel like
are overlooked so you need to know about
that and then you have these kind of
other intricate details of why you might
have things that are opting out of
caching and statically built Pages as
well now the one last thing or actually
two things I'm going to show you of ways
to handle this the last one will be
better and more efficient than the first
one I'll show you the first one is uh to
create an API endpoint called revalidate
and inside of here you can call the re
validate path with whatever path you
send it so in this case I went to like
Local Host and then API API revalidate
and then pass in a path like slash deals
or slash and then also pass in a secret
so that other people can't just call
this without actually matching up
secrets and that you can you can
specifically manually say revalidate
this page so that is one option I kind
of have this now as a fail safe in case
I need to manually go and do this I can
and then notice up here we're checking
this revalidate secret to make sure
again that people can't just add this
wherever they want so that's
good now the uh the other thing and this
is much better is what we're going to
implement is to be able to call
revalidate Path so we just saw that but
revalidate path in a different place so
revalidate path what we want to do is
anytime we're in the admin dashboard so
admin SL dasboard SL deals and we see
these list of deals anytime I approve
one of these I want that to show on the
slash deals page so we would do a
revalidation on slash deals to then have
it pull the latest information after
this thing is approved so that's one
thing the other thing is inside of this
dashboard we're going to build like a
full crud dashboard so anytime we make
updates to one of these deals whether we
make it featured or we change the title
or the image anytime we do any of that
we also then want to make sure we go and
revalidate the path that it might be
displayed on so if we then make it
featured to where it's going to be
featured on this homepage we then need
to re revalidate this homepage as well
as the deals page so all that stuff has
the most recent information so that is
like two hours of digging and searching
and trying and figuring out into like 10
or 15 minutes whatever this recording is
of nextjs caching and there's much more
to this I only talked about full page or
full route caching we didn't really talk
about the client side routing uh caching
and we didn't talk about data caching if
you're using a fetch API because they do
some things there so there's a lot more
to dig into but I think it was really
fun to dig into it and I've had a lot of
fun working on uh this deals for dev's
project so again this is built with
nextjs 14 we'll upgrade to 15 it's built
with clerk for authentication we're
using Zeta as a database again I think
Zeta is super cool it's got a UI built
in uh that I can go and do things if I
need to also we're using Prisma with it
to directly integrate with what is a
postgress database which is what Zeta is
and then Zeta also has a feature to uh
to if I do search in here Zeta also has
uh search apis to actually handle search
for us behind the scenes to pull up
relevance oh this is
still is that still wrong I'll have to
fix that but anyway all of this search
stuff is just powered by Zeta like they
just do all that stuff for us and we
just call the API so it's super cool as
well and then we're using Sentry for aor
tracking and alerting to be able to make
sure that hopefully you have a good
experience so do me a favor let me know
what your thoughts are on cashing in the
comments below check out deals for devs
if you have additional deals that you
know of that you've seen somewhere go
ahead and submit it if you have
something you want to submit for
yourself a course or whatever submit it
uh give me any feedback if you have any
in the comments below as well anyways I
hope this helps you on your journey in
nextjs and cashing it's a mess there's a
lot we'll figure it out together and
we'll get there hope you enjoyed the
video and I'll catch you next time
Browse More Related Video
Everything you need to know about HTTP Caching
Why I don't use React-Query and tRPC anymore
Spring Boot Cache Annotations || Cache Providers || Where to set Caching Policy || Green Learner
Next.js Fetch Data the Right Way (with a Data Access Layer!) (Security, Auth, Cache, DTO)
Caching demystified: Inspect, clear, and disable caches #DevToolsTips
What are Distributed CACHES and how do they manage DATA CONSISTENCY?
5.0 / 5 (0 votes)