Next 20 will include playing the Nextjs theme song on every page load but you can opt out using unstable_loadjQuery to load jQuery into the page which will disable the song.
All of this should be opt-in, or at least give us a next.config.js option to disable caching all over the app. Default caching behaviour that is so aggressive, that it decides to make fetch calls in your API routes static at build time, it's mind-boggling.
Exactly. I don't even understand this framework is trying to accomplish. If I want static pages I would just set cache-control and stale while revalidate. Let me opt out of in-memory caching and static pages.
That's what I was about to write. Instead of several different methods all over the place to opt out, the caching should be entirely opt in. What a mess, eh?
Especially when you realise that monkeypatching fetch impacts all the third party libraries lol. Any SDK npm you use gets severe caching without you onowing or being able to prevent it. Meanwhile its still unclear how to cache non fetch-based stuff.
@@MrManafon While I agree that monkeypatching fetch is a bad call, you are commenting on a video that tells you how to cache a non fetch-based API call. It's at 7:37.
+1. Nextjs caching drove me to Remix and, looking back, great decision. Nextjs caching is over-engineeried, and that this video is needed is yet another proof point.
I said it once and I ll say it again. Caching should be opt in by default since it is an intentional performance optimization tool and not some magic thing that should be applied based on what is used where. The intention is good but sometimes trying to automatically optimize everything causes more issues than it helps - the amount of bugs that resulted from this complexity should be very telling. Focus the energy to educate the users how they can cache data and pages for optimization instead of trying to explain the default complex caching behavior that requires a lot of research for new users. If the users need to keep asking why things behave the way they do, then there is a major flaw with the design.
I love next but the decisions around caching rank among the worst. You should have just left the fetch API alone (tRPC and anything else that used it immediately had issues) and caching by default was always going to something that many Devs struggled with. The new unstable cache function is how it always should have been done. That all being said, it's great to see people's feedback being taken seriously and things changing to reflect this 👍
Completely agree. Optimization should be one of the last steps to do, not the first one. Many pages will not need cache at all (or very limited by time), unless we are doing a Wordpress blog 😀
Am at 6:40 now at the video. And I really would like to have much more tools to debug caching. Especially, when deployed. Because IMO the defaults are good and the idea behind the caching strategies of Next.js too. It's just lacking transparency, what's happening at any given time. One idea would be to have a secure API route where we can inspect, what asset is currently cached for a given active deployment, what pages depend on it, etc.
Yeah if they could extend the logging to cover all cache use cases and provide an option to run it during full builds (or even better make the cache behavior in dev mirror build) it would go a long way in clarifying what exactly is going on.
imo it would be better if it does not cache by default and u need to explicitly specify this kinda of doCache(). Idk it feels more natural to me this way then always getting confused by all stuff.
it would be good if we could get an entire video for how to create a nextjs app like its meant to from the vercel team something like a real world application like ecommerce or anything else would be great
Next.js's default-on caching is so good, that I need monkey patching scripts on several projects for 3rd party libraries using fetch to fix the bugs it's causing. At this point, I don't care, it's just yet another hack/workaround I need to do while using Next.
Hey there, do you have a GitHub issue for the bug you're seeing? We can take a look. If you want to opt-out of caching for fetch, I talk about this @7:03 in the video.
With app router? You can create a root layout with cookies() or headers(), and render children as usual. I think it will prevent creating static pages.
@@AmirLatypov you can pass server components as children/props of client components (thats the basis of context/providers in next app router). So turning the layout to client component should not make its children into client components
Great job in the first part of the video to highlight that caching does not work (as usual) when we are on a dev server, I remember that this got me scratching heads for quite sometime when I started with the App Router.
@@leerob yeah! I'm trying to really learn it because I like react, next and your videos. Thank you for them. Those two imports seemed crazy to me while watching and learning.
Happy to see more deep-dive explainers on how caching on Next.js works. I'm one of the few people that actually don't mind having caching on by default. The only thing I dislike from the current behavior is patching fetch to work differently to how users and library authors currently use it. I'm looking forward to the improvements the Next.js Team will be making in this regard.
Ha, the interesting thing that it doesn’t work, because it’s still unstable 😀. Without unstable functions, it’s easier to say - just use headers() or cookies() inside your code, or it will be cached as a static page. Done.
@@AmirLatypovworks for me though. I took a while to get used to...just like useEffect() but I like the simplicity now. It's more complicated but simple.
@@AmirLatypov As I mentioned in the video, the functionality is stable, it's just acknowledging that the API will likely change to become simplier. But yeah can use cookies instead!
@leerob Thanks for the reply! A couple of issues, though: 1) The function name doesn't make it clear if it's stable. 😅 2) You said it'll change over time, which sounds like extra work for us. So, my team's going with a third-party cache package that's already stable
Great video like always Lee. But i have some feedback around caching. Right now we have a lot of ways on how to handle caching in Nextjs App Router, but i think you guys should simplify that to a single function + single page/layout/route-handler config. Let me explain. //Function/Component cache config Instead noStore() or revalidateAfter(), what about a single configCache() or noCache() function that you can use to wrap any Component/Function and config cache of that. //you could change the name, it's not the point. configCache(async ()=>{ // config cache everything here for example a fetch call or db query }, { time: 100 or 0 //others config if you want }) I really don't like the noStore() approach of a random function on my component that break the cache. And in my opinion everything could be easy if you start with no cache and allow cache everything with functions like this. But i also find that the current approach could work, but with better and less APis around caching and config. //Page/Layout/Route-Handler cache config Instead of const dynamic = 'force-dynamic'; const revalidate = 0; what about export config: NextConfig = { cache: { dynamic: "force-dynamic", revalidate: 0, // or
serverCache: 10, clientCache: 5, } } The point it's a single object with a type provided by Nextjs, right now route-segment-config have 7 config objects all of them with they own values, so it's really hard to remember all those. I really thing you guys should unifed all in one single object, with a Type + JSDocs with explanations. Also it's a single object that people can learn easly and autocomplete they way, instead of learning two or more config. Yeah, i know you could remove the need of the type with Typescript Plugins, but you should always provide them because what about people don't wanna use ts plugins or wanna be more explicit. For example IntelIJ don't work well with Typescript Plugins. All of this it's only feedback, you could change it like you want. But my point it's that if you should reduce the learning curve byproviding to the developers less API's to learn.
I love this style of complete transparency by vercel and their openness to feedback. I'm just learning Next.js right now and these videos are very helpful explaining the more tricky bits. Thank you and keep up the good work.
@@ИмяФамилия-х4в1еyes but it shouldn’t be the default behavior. Caching is a very specific and intentional action and not a general thing. The comparison with the pages directory is also not ideal since you explicitly had to tell what is static and what is dynamic data before at one specific place. The same concept can’t just be transferred to the App directory. It just doesn’t work out if too much 🪄 magic is involved and you first need to explain your users why things behave the way they do. It should be self explanatory.
Do you guys really think that they don't know how to opt out? The point is that caching is never expected to be opt-out. For the last 30 years of the web, it's always been opt-in. It's not surprising that this has been a huge point of contention.
I think visually showing that there's a cache hit would go a long way to determine why something isn't doing what it's supposed to. For me at least this would be enough to go and read up what happens. The caching by default is disruptive for many it seems, but I happen to like the idea - performance is key these days and you get unintentional benefits from this compared to the opt-in approach.
The development of NextJs is just super confusing. Seeing a video like this makes it super clear. It's just a lot of "we've added some custom magic here, ah and this part is also just some custom magic, ah and this part is custom magic ...". I've been doing react for years and I have to watch and read everything 5x before things start to make sense. What's the big win to be had by adding all this complexity? Marginally more control compared to the 'pages' router? I really applaud everyone who is trying to make sense of all this complexity ... I'm just shaking my head over this ...
After using next for years I recently started using the app router, but the feature I was hoping to understand the most is how to revalidate pages in SSG after a set period of time when using app router. This feature is great for projects using quota based apis and services for example.
Would it be possible to explain why the defaults were set so ‘aggressively’ for lack of a better word? Do more complex apps benefit in a way I’m not seeing? Or does it have something to do with how Vercel hosts NextJS apps perhaps? I’d love to know!
It seems that Next.js is listening to the community. Indeed the fetch override is a red flag, but you seems that have listen to the community which is great. It should be removed because core function should not change. Also, yes indeed cache is agreessive, probably to much. We understand why you did that, it's super performant , but not easy to work with as dev. Its easier to add cache optim when we need it than removing it when we don't. Otherwise we are forced to understand all the default cache mechanism even if we don't need them. I think the community is pretty much unanimous about that. We count on you to keep this framework amazing and easy to work with 👍 Thank you for this very well explained video
Love Next and even more the new functionalities that App Router introduces but with the time has been clear that you choose the wrong default related to caching, I mean have caching in the framework is great but It should have the opposite defaults, no caching and then when adding revalidate = false -> static, revalidate = # -> ISR, etc… same for other apis like fetch. And for other promises rely on react.cache or next/cache -> cache() wrappers. Or should be just possible to select default behavior on next.config. That unstable_noStore is a really ugly API that shows how wrong default was selected; also being forced to think almost everywhere if you need or not revalidatePath / revalidateTag functions (which are great but shouldn’t be the default) is counterintuitive, you should be using them only if you are consciously caching. For code readability would be more clear and intuitive that if a function is wrapped with cache then is cached if not is not. Same for fetch, etc. now we are in a strange mix where fetch and many other things are is cached but for others you have to manually cache e.g. db queries (which is clear but fetch is not). I know the purpose was good but the end result creates more issues for the dev that what resolves, if I don’t add caching my app might consume more resources but stills working just as expected, them on the analytics tools, profiler or whatever tool you check what happens, but the other way as is now is really hard to know why something doesn’t work. Also many apps already has caching layers with Redis or so and as caching is default now you have two caches to manage and is hard to know which is causing the issue. Also makes hard to use other “frameworks” on the API routes, is great all the WebAPI WinterCG Request/Response things but if I want to mount a Hono / Elysia / Hattip / HeadlessCMS /Proxy-Server instance on them you’re never going to be sure if Next cache is interfering with them.
Hi Lee. I am not really professional, but next js's caching feature seems like changing a lot of stuff for me (especially avoid using bunch of libraries like redis). However, I am still didn't fully understand the caching yet. In my case, I have CMS kind of admin dashboard with landing page website (all in one next js project. no APIs). there is no external source to change data from database. Can I use caching everywhere and just revalidate when there data changes or adds new data? Am I right?
You wouldn’t cache everywhere. For dashboards, caching makes little sense unless you want to cache some common data that you fetch from your database for all users which is expensive to do. Keep in mind if you are self hosting with multiple instances, the entire caching and revalidating becomes a joke and you need to implement the cache handler/storage urself, see docs. With partial prerendering (beta) you could render a shell of the page and everything else that is static and keep the rest dynamic.
@@ashdaily7640 Assuming you want to use some of the caching features: if you have multiple instances running which is usual, e.g. multiple pods in a k8s cluster, then you will have multiple applications running that will have different caching states since they can’t share the cache when you revalidate something, without a custom cache config. Thus you can have stale data when reloading the page depending on which instance is serving you.
Very interesting! Two questions come to mind about partial pre-rendering. #1 How do we deal with nounces? #2 If we want to pre-render pages that are not accessible to all users, is there a hook to run a security check before serving the page? Thank you
@@carlosagsmendes middleware applies for all routes, but you can filter it depends on url: request.nextUrl.pathname Don't know how the cache will work with middlewares though
amazing work guys I really love nextJS and what you do so keep it up and don't change the app router in the feature let the base change it a little maybe but don't mess with it i love it
I will love to see a video about resusable client and server action validation/error handling pattern. That's where some of these server action patterns falls apart when I'm developing and I haven't found a better solution.
(unstable_)cache is only necessary if you need to dedupe a request, right? E.g. between the Page and generateMetadata. It is not required to cache a page statically. That happens automatically at build time even if you don't wrap your DB calls.
This is super helpful! I would love an expanded discussion on how caching works with authentication. Can I cache resource data that is behind authorization? Then, by extension, if two people have access to that same data, can they both be made to hit the same cache?
NextJS has not clearly communicated WHY the framework does what it does. It's not that the APIs haven't been explained sufficiently well, or that there isn't enough documentation on the way caching works. It's that most of us adopted this tool early on, without having a true understanding of SPAs or MPAs, and now we're rushing headlong into deep-MPA territory without knowing what it gives us besides "less javascript" and "faster load times". I've produced a summary, rough around the edges, which is more for myself than anyone, and I'm putting it out here. Bear with me, if you've been struggling so far --- this is the missing bit of the NextJS explanation: MPAs are all about first-load UX and SEO optimization. To understand this, let's imagine that NextJS operates a "route rendering engine" for each route, which is a kind of expensive black box: your server-side React code. Each rendering engine has inputs and outputs. If a route is fully static, that means that whenever NextJS runs the engine for this route, whether at build time (Static Generation) or at first-request time (Incremental Static Generation), it knows that it can cache the output *because all the inputs have become known*. Next time anyone requests the route, they could receive the cached output from a CDN or from NextJS's "Full Route Cache". Either way the rendering engine doesn't run and the server has to do less work. Also, because static pages are meant to be served from anywhere, including a CDN, you can't access any request-time data (cookies, headers, searchParams, etc) when you want static generation, even in layouts. This is a good thing. It enables your partially rendered code to be served instantly to web-crawlers as well as users switching from other websites to yours. You may need to do client-side data-fetching to get personalized data and complete the rendering, but the most important, contentful components of the page will already be there, b/c previous non-unique rendering work is being shared across visitors. Partial prerendering (PPR) turns the expensive black box opaque, through some clever static analysis. NextJS can know which outputs depend on which inputs, but if an input changes and some output depends on it, the entire engine still has to run again in order to produce the new output. The cost of running the engine is still incurred, but the user gets to see the independent, static outputs before the engine runs, and then only later do the dynamic, dependent outputs stream in. That's why the page seems "partially static" (it is still dynamic). Do this if you really need the speed gains from parallel streaming, or security guarantees from the server (e.g. accessing personal data), just remember that it will again cause all your code to run server-side on each request. Finally, the inputs have to be cached as much as possible to make this model work. Otherwise, compared to SPAs, the cost of hosting would just go up. Relative to the old Next semi-MPAs with SSR, the current model is definitely cheaper. NextJS wants your pages to be static, for your sake. So engineer thoughtfully, ignore the noise that claims server-side is all better or all worse than client-side, and implement the right trade-offs for your product.
Amazing video, Lee! Coming from PHP world, I really like the idea of React having RSC and moving to server more simply because there will be less thing to keep track on. I also appreciate Next.js and React team focus more on stability for this past months, keep up the good work!
Could you make a video explaining the difference between React cache, and Next unstable_cache? Found that part a bit confusing... Is React cache something that Next uses under the hood and I should stay away from, or are there cases where I should prefer React cache over Next unstable_cache? 🤔
React cache is somewhat comparable to useMemo but is obviously used differently in the context of server components. You can perform an expensive operation (get some data from the db, do some calculations, check the authentication of the user etc.) and only perform it once for the full rendering/request even if you call it from 5 different components. E.g.: You get user details from the DB in the layout to check if they are authenticated, additionally you get the user on a specific page to check for authorization. If you warp the function to get the data from DB with cache, you will only perform one DB call instead of two. At the end of the render, this cache is emptied. The nextjs cache can be used if you want to cache some general data that will persist over different requests, users etc.
If I have a website that can pull and push data from a MongoDB server and another separate website that just pulls the data from the server how do I get the second website to update during production and know that new data has been added? It works great on a development server cause there is not caching but my only option right now is to rebuild and push the production app everytime the database is modified to get the most up to date information because without it I can see it just hits nextjs-cache that never updates. It is so frustruitng cause there is not way to even add a way to refresh the cache every hour or something.
I like this framework and have been using it for almost 5 years. Caching and the way how to fetch data is probably the worst thing on the latest versions for me. The whole concept of putting duplicate API requests to several places and "fixing it" by caching feels just wrong. I have been building apps for 15 years and this was always a sign that you are doing something wrong, now you are teaching people the exact opposite. Mental battle.
Really tough having dev behave different than production build. I'd hope they'd always be the same behavior as far as caching goes. Enjoyed the video though thank you for explaining
Is there a way to implement a polling system directly using Next.js that could be combined also with revalidate function to get fresh data every certain amount of time?
I just want to ask for adding setting that disables all cashing and gives apportunity to add cashing where I want. It is strange to disable cash everywhere. All peaple in comments ask you to change it.
The no-store route/component example is pretty confusing. If I understand correctly, you *are* caching that (ie: it doesn't contain noStore() etc), but its name suggests otherwise.
awesome video! thank you. i have a question though... i think i can see the fetch cache and unstable_cache as alternatives for getServerSideProps and getStaticProps by setting the config like cache: 'no-store' and revalidate: x. i can using them to cache data between requests. also i can use react cache to dedupe running functions and ... in a single request. it seem like memoization. so what if i want using react cache and nextjs cache altogether??
If I'm building a page that is mostly a "dashboard" for logged in users, is there any point in using the App router? Should I use Nextjs 13 instead? Or something else entirely..?
Next.js caching is so non-intuitive 😵💫I think it's time for the Vercel dev team to acknowledge the mostly negative feedback regarding caching mechanisms in app router, and simply allow for an opt-out option via the config file. No idea why you'd ever want this behaviour out of the box.
I wish you make another film deeply explaining foundations of caching - for both static and dynamic routes. We have 4 different cache parts (1 for client and 3 for server) and I think Router Cache (client side) is the most frustrating one. It's easy to manually reload the page, everything works fine but no one uses the internet like that and for me Router Cache causing problems when navigating through different routes.
Great examples. how would you recommend to go about caching when there are cookies in the request specific to a user? Currently if you cache an endpoint that has headers, it memorizes with the headers specific to a users session. Would you recommend to still cache? Which would be the best pattern?
Have to use a webhook to invalidate the cache so that my database query executes and returns new data when an external source updates my data? Wow how did something so simple get so complex? Defaulting to static pre-rendering even though my server component had a db query in it was really surprising. At least with getServerSideProps and getStaticProps you knew how your page was going to be built, I would like more control over how pages get rendered and have it decoupled from the caching mechanism. Forcing this caching in app router adds so much more complexity and makes simple things like issuing a db query way more complicated than they need to be. Caching needs to be an opt-in feature instead of something that requires using an unstable API to bypass.
Also, I think people are most frustrated with the 30 second router cache... i.e when navigating to a new Page via a component, always call the async fetch fns on render. Where is an example of this?
The problem is that we are unable to control the caching in depth. Router cache just does what it wants. A granular control over cashing will make everything better imo.
2 questions: in the docs it says fetch is auto opted out if you use the Authorization header and some other criteria I don’t fully understand. Is there a way to turn this off and stay opted in to caching while using the Authorization header? Imagine a private API you need a token for. The token doesn’t change, but all the fetch reqs are auto opted out. The other, by using partial pre rendering, can you use the dynamic function “cookies” and NOT have the entire route be opted in to dynamic rendering? An example, a static page of products, with a singular component that fetches the products a user has “liked”. The products don’t change, but reading the cookie to show the products the user has liked would opt the entire route into dynamic rendering. Can this be avoided?
I have made a nextjs fulstack app that runs all its pages as "use client", those client pages call the nextjs api that calls directly an external api. But the external api responses seem to be cashed in next js app because they are always the same. For example I upcate an object in a list, the list returned is the last state of the list after last app deployment. If I call the external api, the real response is the updated state, but nextjs ignores it and prioritize its cached value. This happens only on deployed apps, I don't have this behaviour in local, I don't understand why I never had that issue before
I created GET and PATCH API endpoints. They work perfectly fine on my localhost, but when I deploy the app, the response is always cached. Is there a way to disable caching on Vercel for specific routes?
when the unstable_cache from next becomes stable, both react and next cache wrappers will be imported as "cache"? if so, whats the best practice there, in case you need to use both cache functions? Or is it better to use next's version? :c
I think I understand the unstable_cache() function but does this only apply on a dynamically rendered page? What if you have a statically generated page on a production build that uses a database call wrapped in unstable_cache() with the tag 'page'. If a server action is run that calls revalidateTag('page'), will that statically generated page be rerendered?
How do you configure a CDN to work with Next.JS caching? Or best, how do you configure Next.JS to work with CDN caching. Are there any gotchas or configurations we need to consider on the CDN or Next.js level?
We are using Nextjs 14 App router and when we are trying to enable caching in Cloudfront, all assets are getting duplicated. All images on page is replaced by one image. Is this a nextjs issue or Cloudfront ? Appreciate any help.
13:20 this is great but you had to Hard Reload to get the browser cache to break the cache on the browser side... This is still difficult to me when I revalidatePath its great because if I hard reload the static page is rebuilt but how can I stop the browser from showing its cached version of the page without hard reloading. I am also using the Link component and this component skips hard reloads when navigating between pages.
At 12:32 isn't it a problem that we would need to keep track of every tag that needs to be revalidated when data changes? I have not finished the video so maybe you will address this but it doesn't seem intuitive.
going from React to Next.js the complexity in learning used to be just a bit more challenging, Now with RSC, it's 10 times more difficult. Discussion with my teammates always end up with what about in RSC? what about the case in client components? Moreover I just use React-Query for all my Get request, it would be nice if fetching was noStore by default, if I understood it correctly.
How can I update the cache for a specific tag manually? I want to update DB Data with fetch POST, and use the returned data to update the cache for the corresponding get requests, so I don't have to fetch it with revalidateTag and make a redundant request, since I already have the data.
When your seeing the cache hit at 06:30 is that in a development mode. All i seem to get is Cache missed reason: (auto cache) and i cannot work out why.
Nextjs pages should be typed with typescript so we can see changes to the api. Something like this: type NextPage = { (props: T): JSX.Element | Promise revalidate?: boolean | number dynamic?: 'force-dynamic' metadata?: Metadata generateMetaData?: () => {} }
Those functions like you suggested (`revalidateAfter(10)` for example) would be perfect for decorators, no? They look very out of place and separate from the context inside a function.
I have one question when we work in next js and node js then nodejs devloper send token in response then we can get it in client side then how we can protect page in middleware using server side because next js middleware run on server
why at min 9:40 (the request) of the direct call of the database not cached, while at min 18:15 (the request) is cached, is it because of the pure SQL vs ORM ?
Next 20 will include playing the Nextjs theme song on every page load but you can opt out using unstable_loadjQuery to load jQuery into the page which will disable the song.
Sounds dope, I love jQuery
Jared the man to provide criticism without saying it
He said it alright.
🤣🤣🤣
Hahahahahahaha
All of this should be opt-in, or at least give us a next.config.js option to disable caching all over the app. Default caching behaviour that is so aggressive, that it decides to make fetch calls in your API routes static at build time, it's mind-boggling.
Exactly. I don't even understand this framework is trying to accomplish. If I want static pages I would just set cache-control and stale while revalidate. Let me opt out of in-memory caching and static pages.
That's what I was about to write. Instead of several different methods all over the place to opt out, the caching should be entirely opt in. What a mess, eh?
Especially when you realise that monkeypatching fetch impacts all the third party libraries lol. Any SDK npm you use gets severe caching without you onowing or being able to prevent it. Meanwhile its still unclear how to cache non fetch-based stuff.
@@MrManafon While I agree that monkeypatching fetch is a bad call, you are commenting on a video that tells you how to cache a non fetch-based API call. It's at 7:37.
+1. Nextjs caching drove me to Remix and, looking back, great decision. Nextjs caching is over-engineeried, and that this video is needed is yet another proof point.
I said it once and I ll say it again. Caching should be opt in by default since it is an intentional performance optimization tool and not some magic thing that should be applied based on what is used where. The intention is good but sometimes trying to automatically optimize everything causes more issues than it helps - the amount of bugs that resulted from this complexity should be very telling.
Focus the energy to educate the users how they can cache data and pages for optimization instead of trying to explain the default complex caching behavior that requires a lot of research for new users.
If the users need to keep asking why things behave the way they do, then there is a major flaw with the design.
I love next but the decisions around caching rank among the worst. You should have just left the fetch API alone (tRPC and anything else that used it immediately had issues) and caching by default was always going to something that many Devs struggled with. The new unstable cache function is how it always should have been done.
That all being said, it's great to see people's feedback being taken seriously and things changing to reflect this 👍
Completely agree. Optimization should be one of the last steps to do, not the first one. Many pages will not need cache at all (or very limited by time), unless we are doing a Wordpress blog 😀
I think for v15, with the stable release of partial pre-rendering, fetch is gonna switch to being uncached by default.
@@jfedererj yeah I believe most of the defaults will now be uncached by default
Am at 6:40 now at the video. And I really would like to have much more tools to debug caching. Especially, when deployed.
Because IMO the defaults are good and the idea behind the caching strategies of Next.js too. It's just lacking transparency, what's happening at any given time.
One idea would be to have a secure API route where we can inspect, what asset is currently cached for a given active deployment, what pages depend on it, etc.
Right, just overall we need to have more ways to see things versus just assuming things.
Yeah if they could extend the logging to cover all cache use cases and provide an option to run it during full builds (or even better make the cache behavior in dev mirror build) it would go a long way in clarifying what exactly is going on.
imo it would be better if it does not cache by default and u need to explicitly specify this kinda of doCache(). Idk it feels more natural to me this way then always getting confused by all stuff.
i'd rather choose to opt-in instead of opt-out too
it would be good if we could get an entire video for how to create a nextjs app like its meant to from the vercel team
something like a real world application like ecommerce or anything else would be great
Next.js's default-on caching is so good, that I need monkey patching scripts on several projects for 3rd party libraries using fetch to fix the bugs it's causing. At this point, I don't care, it's just yet another hack/workaround I need to do while using Next.
Hey there, do you have a GitHub issue for the bug you're seeing? We can take a look. If you want to opt-out of caching for fetch, I talk about this @7:03 in the video.
@@leerob Tried to post a Github link but TY doesn't let me in any form...
@@wintercounter2 You could write it like "user/repo". Then people may substitute the user and repo in the actual github link
Let me know what questions y'all have, hope this helps!
this much changes this often is mind fuck to be honest.
Amazing stuff! Love this kind of content. 💖
Maybe video on llms and next.js ?
Hi Lee, thanks for this video. I was stuck on App Router yesterday. Will try revalidateTag. Can you specify revalidate along with it?
Good idea @@kasper369 !
I kinda like to control caching on my own, so I want to entirely disable caching by NextJs... can I do that?
With app router? You can create a root layout with cookies() or headers(), and render children as usual.
I think it will prevent creating static pages.
You cant
use pages router
@@AmirLatypov you can pass server components as children/props of client components (thats the basis of context/providers in next app router). So turning the layout to client component should not make its children into client components
export const fetchCache ='force-no-store'
Great job in the first part of the video to highlight that caching does not work (as usual) when we are on a dev server, I remember that this got me scratching heads for quite sometime when I started with the App Router.
Really helpful to see some official examples in video form explained!
Wow, the importing cache from react and noStore from next seems like a mind boggling amount of complexity
Have you tried it out yet?
@@leerob yeah! I'm trying to really learn it because I like react, next and your videos. Thank you for them.
Those two imports seemed crazy to me while watching and learning.
Happy to see more deep-dive explainers on how caching on Next.js works. I'm one of the few people that actually don't mind having caching on by default. The only thing I dislike from the current behavior is patching fetch to work differently to how users and library authors currently use it. I'm looking forward to the improvements the Next.js Team will be making in this regard.
Ha, the interesting thing that it doesn’t work, because it’s still unstable 😀.
Without unstable functions, it’s easier to say - just use headers() or cookies() inside your code, or it will be cached as a static page. Done.
I suppose that no one wants to use unstable functions on their prods.
@@AmirLatypovworks for me though. I took a while to get used to...just like useEffect() but I like the simplicity now. It's more complicated but simple.
@@AmirLatypov As I mentioned in the video, the functionality is stable, it's just acknowledging that the API will likely change to become simplier. But yeah can use cookies instead!
@leerob Thanks for the reply!
A couple of issues, though:
1) The function name doesn't make it clear if it's stable. 😅
2) You said it'll change over time, which sounds like extra work for us. So, my team's going with a third-party cache package that's already stable
Is there a difference between using “noStore()/cookies()/headers()” and “export const dynamic = ‘force-dynamic’;” ?
it´s so confusing
Great video like always Lee.
But i have some feedback around caching.
Right now we have a lot of ways on how to handle caching in Nextjs App Router, but i think you guys should simplify that to a single function + single page/layout/route-handler config. Let me explain.
//Function/Component cache config
Instead noStore() or revalidateAfter(), what about a single configCache() or noCache() function that you can use to wrap any Component/Function and config cache of that.
//you could change the name, it's not the point.
configCache(async ()=>{
// config cache everything here for example a fetch call or db query
}, {
time: 100 or 0
//others config if you want
})
I really don't like the noStore() approach of a random function on my component that break the cache. And in my opinion everything could be easy if you start with no cache and allow cache everything with functions like this. But i also find that the current approach could work, but with better and less APis around caching and config.
//Page/Layout/Route-Handler cache config
Instead of
const dynamic = 'force-dynamic';
const revalidate = 0;
what about
export config: NextConfig = {
cache: {
dynamic: "force-dynamic",
revalidate: 0,
// or
serverCache: 10,
clientCache: 5,
}
}
The point it's a single object with a type provided by Nextjs, right now route-segment-config have 7 config objects all of them with they own values, so it's really hard to remember all those. I really thing you guys should unifed all in one single object, with a Type + JSDocs with explanations. Also it's a single object that people can learn easly and autocomplete they way, instead of learning two or more config.
Yeah, i know you could remove the need of the type with Typescript Plugins, but you should always provide them because what about people don't wanna use ts plugins or wanna be more explicit. For example IntelIJ don't work well with Typescript Plugins.
All of this it's only feedback, you could change it like you want. But my point it's that if you should reduce the learning curve byproviding to the developers less API's to learn.
Good idea on the config object. Those magic variables are indeed always hard to remember
I love this style of complete transparency by vercel and their openness to feedback. I'm just learning Next.js right now and these videos are very helpful explaining the more tricky bits. Thank you and keep up the good work.
Get ready for hell then
"What if you have a fetch, but you don't want it cached?" Do you mean like 98% of all use cases people would use Next for?
Nice one :)
You can pass cache: 'no-store' to fetch, to opt out the default behavior
Or set revalidate to 0, which also disables caching
@@ИмяФамилия-х4в1еyes but it shouldn’t be the default behavior. Caching is a very specific and intentional action and not a general thing. The comparison with the pages directory is also not ideal since you explicitly had to tell what is static and what is dynamic data before at one specific place. The same concept can’t just be transferred to the App directory. It just doesn’t work out if too much 🪄 magic is involved and you first need to explain your users why things behave the way they do. It should be self explanatory.
Do you guys really think that they don't know how to opt out?
The point is that caching is never expected to be opt-out. For the last 30 years of the web, it's always been opt-in. It's not surprising that this has been a huge point of contention.
I think visually showing that there's a cache hit would go a long way to determine why something isn't doing what it's supposed to. For me at least this would be enough to go and read up what happens.
The caching by default is disruptive for many it seems, but I happen to like the idea - performance is key these days and you get unintentional benefits from this compared to the opt-in approach.
Did you see the logging config in the video?
That was so helpful! Would love a weekly video series like this to help people out with intermediate/advanced 13/14 stuff. You guys are amazing.
The development of NextJs is just super confusing. Seeing a video like this makes it super clear. It's just a lot of "we've added some custom magic here, ah and this part is also just some custom magic, ah and this part is custom magic ...". I've been doing react for years and I have to watch and read everything 5x before things start to make sense. What's the big win to be had by adding all this complexity? Marginally more control compared to the 'pages' router? I really applaud everyone who is trying to make sense of all this complexity ... I'm just shaking my head over this ...
After using next for years I recently started using the app router, but the feature I was hoping to understand the most is how to revalidate pages in SSG after a set period of time when using app router. This feature is great for projects using quota based apis and services for example.
Would it be possible to explain why the defaults were set so ‘aggressively’ for lack of a better word? Do more complex apps benefit in a way I’m not seeing? Or does it have something to do with how Vercel hosts NextJS apps perhaps? I’d love to know!
this cache API is fantastic - big fan of it! Agree that the cache key + tags are a bit confusing, I'm a big fan!
wow you are here !
It seems that Next.js is listening to the community. Indeed the fetch override is a red flag, but you seems that have listen to the community which is great. It should be removed because core function should not change.
Also, yes indeed cache is agreessive, probably to much. We understand why you did that, it's super performant , but not easy to work with as dev. Its easier to add cache optim when we need it than removing it when we don't.
Otherwise we are forced to understand all the default cache mechanism even if we don't need them.
I think the community is pretty much unanimous about that. We count on you to keep this framework amazing and easy to work with 👍
Thank you for this very well explained video
Love Next and even more the new functionalities that App Router introduces but with the time has been clear that you choose the wrong default related to caching, I mean have caching in the framework is great but It should have the opposite defaults, no caching and then when adding revalidate = false -> static, revalidate = # -> ISR, etc… same for other apis like fetch.
And for other promises rely on react.cache or next/cache -> cache() wrappers. Or should be just possible to select default behavior on next.config.
That unstable_noStore is a really ugly API that shows how wrong default was selected; also being forced to think almost everywhere if you need or not revalidatePath / revalidateTag functions (which are great but shouldn’t be the default) is counterintuitive, you should be using them only if you are consciously caching. For code readability would be more clear and intuitive that if a function is wrapped with cache then is cached if not is not. Same for fetch, etc. now we are in a strange mix where fetch and many other things are is cached but for others you have to manually cache e.g. db queries (which is clear but fetch is not).
I know the purpose was good but the end result creates more issues for the dev that what resolves, if I don’t add caching my app might consume more resources but stills working just as expected, them on the analytics tools, profiler or whatever tool you check what happens, but the other way as is now is really hard to know why something doesn’t work. Also many apps already has caching layers with Redis or so and as caching is default now you have two caches to manage and is hard to know which is causing the issue.
Also makes hard to use other “frameworks” on the API routes, is great all the WebAPI WinterCG Request/Response things but if I want to mount a Hono / Elysia / Hattip / HeadlessCMS /Proxy-Server instance on them you’re never going to be sure if Next cache is interfering with them.
Hi Lee. I am not really professional, but next js's caching feature seems like changing a lot of stuff for me (especially avoid using bunch of libraries like redis). However, I am still didn't fully understand the caching yet. In my case, I have CMS kind of admin dashboard with landing page website (all in one next js project. no APIs). there is no external source to change data from database. Can I use caching everywhere and just revalidate when there data changes or adds new data? Am I right?
You wouldn’t cache everywhere. For dashboards, caching makes little sense unless you want to cache some common data that you fetch from your database for all users which is expensive to do.
Keep in mind if you are self hosting with multiple instances, the entire caching and revalidating becomes a joke and you need to implement the cache handler/storage urself, see docs.
With partial prerendering (beta) you could render a shell of the page and everything else that is static and keep the rest dynamic.
@@BBxx19 what do you mean by self hosting with multiple instances? Why would it affect caching?
@@ashdaily7640 Assuming you want to use some of the caching features: if you have multiple instances running which is usual, e.g. multiple pods in a k8s cluster, then you will have multiple applications running that will have different caching states since they can’t share the cache when you revalidate something, without a custom cache config. Thus you can have stale data when reloading the page depending on which instance is serving you.
@@BBxx19 that makes a lot of sense. Thank you. In such cases, we would have to use a shared place for caching like Redis, right?
Yes, Redis would be a good choice
unstable_cache just saved my life, thank you, kind vercel dev of the tube
Very interesting! Two questions come to mind about partial pre-rendering. #1 How do we deal with nounces? #2 If we want to pre-render pages that are not accessible to all users, is there a hook to run a security check before serving the page? Thank you
#2 Yep, just use cookies(). Or use a middleware.
Btw I wonder, if I use cookies() only in a middleware, will it prevent page to be static cached?
Thank you. Does it have middleware per route? Can we make rest requests from the API?
@@carlosagsmendes middleware applies for all routes, but you can filter it depends on url: request.nextUrl.pathname
Don't know how the cache will work with middlewares though
Would be great to see these demos when doing self hosting instead of vercel because caching/on-demand ISR is a mess when self hosting.
That next config option for logging is very useful, thanks!
Love your content. Next Js team is so awesome! Keep it up!
amazing work guys I really love nextJS and what you do so keep it up and don't change the app router in the feature let the base change it a little maybe but don't mess with it i love it
Stable app router caching, brushing over all the unstable APIs
The video we all wanted, thanks and great job!
I will love to see a video about resusable client and server action validation/error handling pattern. That's where some of these server action patterns falls apart when I'm developing and I haven't found a better solution.
Amazing video. All my confusion is gone now
(unstable_)cache is only necessary if you need to dedupe a request, right? E.g. between the Page and generateMetadata. It is not required to cache a page statically. That happens automatically at build time even if you don't wrap your DB calls.
This is super helpful! I would love an expanded discussion on how caching works with authentication. Can I cache resource data that is behind authorization? Then, by extension, if two people have access to that same data, can they both be made to hit the same cache?
I like the logging feature in 6:30 so much!!!
NextJS has not clearly communicated WHY the framework does what it does. It's not that the APIs haven't been explained sufficiently well, or that there isn't enough documentation on the way caching works. It's that most of us adopted this tool early on, without having a true understanding of SPAs or MPAs, and now we're rushing headlong into deep-MPA territory without knowing what it gives us besides "less javascript" and "faster load times".
I've produced a summary, rough around the edges, which is more for myself than anyone, and I'm putting it out here. Bear with me, if you've been struggling so far --- this is the missing bit of the NextJS explanation:
MPAs are all about first-load UX and SEO optimization. To understand this, let's imagine that NextJS operates a "route rendering engine" for each route, which is a kind of expensive black box: your server-side React code.
Each rendering engine has inputs and outputs. If a route is fully static, that means that whenever NextJS runs the engine for this route, whether at build time (Static Generation) or at first-request time (Incremental Static Generation), it knows that it can cache the output *because all the inputs have become known*. Next time anyone requests the route, they could receive the cached output from a CDN or from NextJS's "Full Route Cache". Either way the rendering engine doesn't run and the server has to do less work.
Also, because static pages are meant to be served from anywhere, including a CDN, you can't access any request-time data (cookies, headers, searchParams, etc) when you want static generation, even in layouts. This is a good thing. It enables your partially rendered code to be served instantly to web-crawlers as well as users switching from other websites to yours. You may need to do client-side data-fetching to get personalized data and complete the rendering, but the most important, contentful components of the page will already be there, b/c previous non-unique rendering work is being shared across visitors.
Partial prerendering (PPR) turns the expensive black box opaque, through some clever static analysis. NextJS can know which outputs depend on which inputs, but if an input changes and some output depends on it, the entire engine still has to run again in order to produce the new output. The cost of running the engine is still incurred, but the user gets to see the independent, static outputs before the engine runs, and then only later do the dynamic, dependent outputs stream in. That's why the page seems "partially static" (it is still dynamic). Do this if you really need the speed gains from parallel streaming, or security guarantees from the server (e.g. accessing personal data), just remember that it will again cause all your code to run server-side on each request.
Finally, the inputs have to be cached as much as possible to make this model work. Otherwise, compared to SPAs, the cost of hosting would just go up. Relative to the old Next semi-MPAs with SSR, the current model is definitely cheaper. NextJS wants your pages to be static, for your sake. So engineer thoughtfully, ignore the noise that claims server-side is all better or all worse than client-side, and implement the right trade-offs for your product.
Amazing video, Lee! Coming from PHP world, I really like the idea of React having RSC and moving to server more simply because there will be less thing to keep track on. I also appreciate Next.js and React team focus more on stability for this past months, keep up the good work!
Going from straight forward concepts you can learn and study like SSG, ISR, SSR, CSR to this intrinsic knowledge caching hurts my brain
I would like to see a video this about error handling too.
At the end there is a flash from 5d ago to 7d ago close to the article date
we're going back to pages router with this one 🔥🔥🔥
Great video, could you talk about layout components as well ? As far as i know the fetching and caching behavior is a bit different.
love those little demos .... really valuable
Could you make a video explaining the difference between React cache, and Next unstable_cache? Found that part a bit confusing... Is React cache something that Next uses under the hood and I should stay away from, or are there cases where I should prefer React cache over Next unstable_cache? 🤔
React cache is somewhat comparable to useMemo but is obviously used differently in the context of server components. You can perform an expensive operation (get some data from the db, do some calculations, check the authentication of the user etc.) and only perform it once for the full rendering/request even if you call it from 5 different components.
E.g.: You get user details from the DB in the layout to check if they are authenticated, additionally you get the user on a specific page to check for authorization. If you warp the function to get the data from DB with cache, you will only perform one DB call instead of two.
At the end of the render, this cache is emptied.
The nextjs cache can be used if you want to cache some general data that will persist over different requests, users etc.
If I have a website that can pull and push data from a MongoDB server and another separate website that just pulls the data from the server how do I get the second website to update during production and know that new data has been added? It works great on a development server cause there is not caching but my only option right now is to rebuild and push the production app everytime the database is modified to get the most up to date information because without it I can see it just hits nextjs-cache that never updates. It is so frustruitng cause there is not way to even add a way to refresh the cache every hour or something.
Here is what the API looks like atm:
export const GET = async (req: Request, res: NextResponse) => {
try {
await connectDB();
const post = await prisma.post.findMany();
return NextResponse.json({message: "Data fetched successfully", post}, {status: 200})
} catch (err) {
return NextResponse.json({message: "Error fetching data", err}, {status: 500})
} finally{
await disconnectDB();
}
};
I like this framework and have been using it for almost 5 years. Caching and the way how to fetch data is probably the worst thing on the latest versions for me. The whole concept of putting duplicate API requests to several places and "fixing it" by caching feels just wrong. I have been building apps for 15 years and this was always a sign that you are doing something wrong, now you are teaching people the exact opposite. Mental battle.
Really tough having dev behave different than production build. I'd hope they'd always be the same behavior as far as caching goes. Enjoyed the video though thank you for explaining
This is the REALL problem, I wish more people talked this.
Instead of unstable_cache I've been using (and teaching) React's cache
Is there a way to implement a polling system directly using Next.js that could be combined also with revalidate function to get fresh data every certain amount of time?
thank you
legit video
we are still here and AI has not replaced us yet
I just want to ask for adding setting that disables all cashing and gives apportunity to add cashing where I want. It is strange to disable cash everywhere. All peaple in comments ask you to change it.
The no-store route/component example is pretty confusing. If I understand correctly, you *are* caching that (ie: it doesn't contain noStore() etc), but its name suggests otherwise.
awesome video! thank you. i have a question though... i think i can see the fetch cache and unstable_cache as alternatives for getServerSideProps and getStaticProps by setting the config like cache: 'no-store' and revalidate: x. i can using them to cache data between requests. also i can use react cache to dedupe running functions and ... in a single request. it seem like memoization. so what if i want using react cache and nextjs cache altogether??
If I'm building a page that is mostly a "dashboard" for logged in users, is there any point in using the App router? Should I use Nextjs 13 instead? Or something else entirely..?
Great video! where can i find the static pages after building?
how to enable that logging which shows that a route was dynamically built?
Yes - having same issue
More terminal tooling and indication would be great. I feel like we should have better tooling for all these new concepts, specially during runtime.
Next.js caching is so non-intuitive 😵💫I think it's time for the Vercel dev team to acknowledge the mostly negative feedback regarding caching mechanisms in app router, and simply allow for an opt-out option via the config file. No idea why you'd ever want this behaviour out of the box.
Can we use "force-dynamic" route segment to opt into dynamic routing? It looks much cleaner than calling noStore
You should basically never need the route segment options, those are the eject button - I'll try to make this more clear in the docs!
@@leerob we had to use it because of CSP headers :(. Is there a better way to support CSP without using "eject" button?
@@samithafernando6432 noStore should achieve the same thing. Does it not for you?
revalidateTag looks promising, but still has a confusing invocation signature, should i create a "tag" and re-use later?
You add tags onto your fetches, so the tag is part of the cache key to invalidate.
In the case of fetches directly with server actions, how do I define a tag to revalidate later?
I wish you make another film deeply explaining foundations of caching - for both static and dynamic routes. We have 4 different cache parts (1 for client and 3 for server) and I think Router Cache (client side) is the most frustrating one. It's easy to manually reload the page, everything works fine but no one uses the internet like that and for me Router Cache causing problems when navigating through different routes.
Yes 100% same
Thanks! Awesome video! I want more content like this about next.js
When the framework you're investigating has more (code) smells than a locker room.
Thank you Lee, these are so helpful
Great examples. how would you recommend to go about caching when there are cookies in the request specific to a user? Currently if you cache an endpoint that has headers, it memorizes with the headers specific to a users session. Would you recommend to still cache? Which would be the best pattern?
Have to use a webhook to invalidate the cache so that my database query executes and returns new data when an external source updates my data? Wow how did something so simple get so complex? Defaulting to static pre-rendering even though my server component had a db query in it was really surprising. At least with getServerSideProps and getStaticProps you knew how your page was going to be built, I would like more control over how pages get rendered and have it decoupled from the caching mechanism. Forcing this caching in app router adds so much more complexity and makes simple things like issuing a db query way more complicated than they need to be. Caching needs to be an opt-in feature instead of something that requires using an unstable API to bypass.
Is there any difference between getStaticProps(), and doing an static fetch?
Also, I think people are most frustrated with the 30 second router cache... i.e when navigating to a new Page via a component, always call the async fetch fns on render. Where is an example of this?
The problem is that we are unable to control the caching in depth. Router cache just does what it wants. A granular control over cashing will make everything better imo.
Insightful and helpful explanation, Lee!
2 questions: in the docs it says fetch is auto opted out if you use the Authorization header and some other criteria I don’t fully understand. Is there a way to turn this off and stay opted in to caching while using the Authorization header? Imagine a private API you need a token for. The token doesn’t change, but all the fetch reqs are auto opted out.
The other, by using partial pre rendering, can you use the dynamic function “cookies” and NOT have the entire route be opted in to dynamic rendering? An example, a static page of products, with a singular component that fetches the products a user has “liked”. The products don’t change, but reading the cookie to show the products the user has liked would opt the entire route into dynamic rendering. Can this be avoided?
@leerob For the `unstable_cache` method, is it possible to turn on logging to see when the cache is being hit?
I have made a nextjs fulstack app that runs all its pages as "use client", those client pages call the nextjs api that calls directly an external api. But the external api responses seem to be cashed in next js app because they are always the same. For example I upcate an object in a list, the list returned is the last state of the list after last app deployment. If I call the external api, the real response is the updated state, but nextjs ignores it and prioritize its cached value.
This happens only on deployed apps, I don't have this behaviour in local, I don't understand why I never had that issue before
I created GET and PATCH API endpoints. They work perfectly fine on my localhost, but when I deploy the app, the response is always cached. Is there a way to disable caching on Vercel for specific routes?
when the unstable_cache from next becomes stable, both react and next cache wrappers will be imported as "cache"?
if so, whats the best practice there, in case you need to use both cache functions? Or is it better to use next's version? :c
I think I understand the unstable_cache() function but does this only apply on a dynamically rendered page? What if you have a statically generated page on a production build that uses a database call wrapped in unstable_cache() with the tag 'page'. If a server action is run that calls revalidateTag('page'), will that statically generated page be rerendered?
I like it, your starting to match the features of RTK. Do you have any plans to allow transforming the response?
Great video and well explained thanks.
Lee. Is caching worth for small to medium project?
for any size project that needs cashing
How do you configure a CDN to work with Next.JS caching? Or best, how do you configure Next.JS to work with CDN caching. Are there any gotchas or configurations we need to consider on the CDN or Next.js level?
Hello, how does revalidate tag/path affect pagination
How can cache pages with dynamic routes? Like I have a page (app/[lng]/product/[id]/page.tsx). Is there any provision to cache such pages?
Feels a bit complicated for now. But i guess it's just me since Iliterally just started to wrap my head around nextjs a few days ago.
We are using Nextjs 14 App router and when we are trying to enable caching in Cloudfront, all assets are getting duplicated. All images on page is replaced by one image. Is this a nextjs issue or Cloudfront ? Appreciate any help.
13:20 this is great but you had to Hard Reload to get the browser cache to break the cache on the browser side... This is still difficult to me when I revalidatePath its great because if I hard reload the static page is rebuilt but how can I stop the browser from showing its cached version of the page without hard reloading. I am also using the Link component and this component skips hard reloads when navigating between pages.
At 12:32 isn't it a problem that we would need to keep track of every tag that needs to be revalidated when data changes? I have not finished the video so maybe you will address this but it doesn't seem intuitive.
going from React to Next.js the complexity in learning used to be just a bit more challenging, Now with RSC, it's 10 times more difficult. Discussion with my teammates always end up with what about in RSC? what about the case in client components? Moreover I just use React-Query for all my Get request, it would be nice if fetching was noStore by default, if I understood it correctly.
For newer devs just use the pages router, you'll be 10x more productive right now.
do weekly videos on intermediate/advanced topics that are most common use cases in next 13/14
How can I update the cache for a specific tag manually? I want to update DB Data with fetch POST, and use the returned data to update the cache for the corresponding get requests, so I don't have to fetch it with revalidateTag and make a redundant request, since I already have the data.
When your seeing the cache hit at 06:30 is that in a development mode. All i seem to get is Cache missed reason: (auto cache) and i cannot work out why.
In the fetch chapter, GETs are cached, but is this Data Cache, or is Data Cache enabled even though it is not deployed in Vercel?
Nextjs pages should be typed with typescript so we can see changes to the api. Something like this: type NextPage = {
(props: T): JSX.Element | Promise
revalidate?: boolean | number
dynamic?: 'force-dynamic'
metadata?: Metadata
generateMetaData?: () => {}
}
Those functions like you suggested (`revalidateAfter(10)` for example) would be perfect for decorators, no? They look very out of place and separate from the context inside a function.
I have one question when we work in next js and node js then nodejs devloper send token in response then we can get it in client side then how we can protect page in middleware using server side because next js middleware run on server
why at min 9:40 (the request) of the direct call of the database not cached, while at min 18:15 (the request) is cached, is it because of the pure SQL vs ORM ?
How can I opt-out of client side caching?
Looking though the docs and I just found you can't opt-out of client side cache... wtf bro