-
Notifications
You must be signed in to change notification settings - Fork 27.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
getStaticPaths re-imports node modules preventing caching remote data in memory #10933
Comments
Hi, we run If you would like to cache data between calls to The filesystem cache approach works pretty well on the Notion blog example and helps prevent re-fetching of data that has already been fetched. |
Oh man, this is a shame, makes my use case much more complicated (assumed state in a "store" class would be preserved in a single client side session as you navigate between pages, but actually the store gets recreated when you navigate to a page generated by |
Actually, am I doing something wrong here? My site can be entirely run as SSR, and if I browse the exported site (just served from a web server, no Next.js server), I can see that when I navigate between non- |
I was doing something wrong heh, dynamic links need both |
Is it safe to store those data in Edit: maybe we can get some unique build ID to check against? |
@ijjk This is still a frequently requested feature. Your answer basically say "find/implement your own solution". What the community is asking is for a built-in way to do something like this. One of my main issue crafting my own solution is that it should be called during or before webpack runs, and it makes it hard to use the same programming language version, because Webpack script (in next.config.js) doesn't use the TypeScript/ESXXX version my code usually use, so I can't reuse the code I've already written in my app but need to duplicate it. It feels wrong, and even if duplicated code was fine (it's not) it's still not clear to me about how I should implement it to make those data accessible for The "best" (not tested) solutions I've found so far are from #18550:
Last time I checked they weren't fitting my needs, I'll check again but I really need the framework needs to come up with a proper built-in solution. |
I used https://github.com/ricokahler/next-plugin-preval to prefetch Locize API (i18n) to fetch all translations during Webpack bundling phase, and make them statically accessible to all components, pages and API routes. The journey wasn't so easy, though. I encountered several Webpack bugs (related to the plugin's implementation), see ricokahler/next-plugin-preval#26 and overall the Developer Experience has decreased (although performances have increased). It's clearly better than nothing, and clearly not as good as what the Next.js team does -- hence the need for a built-in way to do something like this. Nobody likes to mess with Webpack, and the Next.js Webpack config is highly sophisticated. @leerob @timneutkens Some dev feedback regarding this long-lasting issue (I wanted to do this a year ago) |
I've implemented the file-based cache solution here if anyone is interested. I needed it for my own project: It's in Typescript with build-time type generation and caching calls between |
@jrandeniya nice! We (@stackbit) have sponsored a similar project that solves similar issues with Contentful and other CMSes. Check it out at: https://github.com/contentlayerdev/contentlayer Also, we have created a utility package that enable "Hot Content Reloads" for page props while working locally with Next.js: https://github.com/stackbit/nextjs-hot-content-reload |
@smnh - this looks great. I'll check it out later and see if I can contribute 😄 |
If anyone wants to follow @ijjk's approach, here's a function where you can cache data on SSG.
|
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
For folks landing here from Google -> https://github.com/vercel/examples/tree/main/solutions/reuse-responses |
Bug report
Describe the bug
When running
next dev
and requesting a page having thegetStaticPaths
method, node modules required by the page are re-imported, thus preventing caching headless CMS remote data in memory.Same happens when running
next build
- modules required by page component that havegetStaticPaths
method are re-imported for every pre-rendered page. Making it impossible to fetch the whole remote data in a single API request and use it for all pre-rendered pages.Important Note:
Headless CMS services may limit number of API requests per month and may apply charges when this limit is passed. The development and build of statically generated sites should minimize the usage of headless CMS API and re-fetch the data only when it is changed. The caching and data invalidation logic might be implemented by CMS clients. Additionally headless CMS services have endpoints to fetch the whole data in a single request. Therefore, to decrease the API usage and support caching, I think Next.js should allow importing modules that cache their data in memory and not re-import them every time page is pre-rendered, while running dev server or when building the site.
To Reproduce
Create simple page
pages/[...slug].js
Implement simple singleton CMS client that fetches CMS data and caches it in memory:
Navigate to any page rendered by
[...slug].js
, for example/about
.Following logs will be printed on server::
[...slug].js
module was loaded for the first time it is OK.[...slug].js
callsgetStaticPaths
- OK according to Runs on every request in developmentgetStaticPaths
of the CMS client is invoked, it does not have the cached data because the client was just constructed therefore thegetData
is called for the first time - OK.[...slug].js
callsgetStaticProps
- OK according to Runs on every request in developmentgetStaticPropsForPath
of the CMS client is invoked, it already has cached data sogetData
returns early returning the cached data - OKRefresh the page or click a link
<Link href="/[...slug]" as="/about"><a>About</a></Link>
.Following logs will be printed on server:
As it can be seen the CMS client is constructed again, and every time a page is requested (even thought it uses the same page module), and the same steps related to fetching and caching the data are repeated. This behavior suggest that when page is requested and
getStaticPaths
is called, it re-imports all modules.Note: When using
getStaticProps
withoutgetStaticPaths
, the client is not constructed on every request and therefore cached data is used as expected. See link to demo repository below.Expected behavior
When running
next dev
server (ornext build
), the modules imported by a page component should be imported only once and reused to allow them cache remote data in memory.System information
Additional context
I've setup an example repository that I've used to reproduce this issue. It uses Sanity as Headless CMS. The README file has all the info needed to setup Sanity account and import the initial data used by this example site.
https://github.com/stackbithq/azimuth-nextjs-sanity/tree/nextjs-ssg-api
(use
nextjs-ssg-api
branch)Note, when loading the root page '/' (
pages/index.js
) which has only thegetStaticProps
method and does not havegetStaticPaths
, the CMS client is not constructed on every request and therefore data cached in memory of the CMS client module is used as expected.The text was updated successfully, but these errors were encountered: