How to cache server actions correctly in order to have Static Pages?
Answered
Masai Lion posted this in #help-forum
Masai LionOP
I have a news website project where I need every page to be Statically generated. I have a singles file with all my requests encapsulated in server actions. This uses a custom db connection:
How do I cache this in order to get static data? I only want to revalidate it on the next build. Is unstable_cache the way to go?
import { payload } from '@/payload/lib/client';
import jsdom from 'jsdom';
// import { unstable_cache } from 'next/cache';
export async function get_global_config() {
'use server';
const global_config = payload.findGlobal({ slug: 'general-Website-Config' });
return global_config;
}
export async function get_steam_count() {
'use server';
const steam_counter = await fetchData()
return steam_counter;
}
[...]How do I cache this in order to get static data? I only want to revalidate it on the next build. Is unstable_cache the way to go?
62 Replies
unstable_cache persists even between builds (if the code doesnt change), so the best/easiest way to cache it would be just use route handler and then boring old fetch
@riský unstable_cache persists even between builds (if the code doesnt change), so the best/easiest way to cache it would be just use route handler and then boring old fetch
Masai LionOP
I guess I will migrate back to the pages router then
wait why
Masai LionOP
I can just call the db on the getStaticProps. It's less work
you can do that here too
im just answering your question... server actions shouldnt be cached
they are kinda designed for data mutating
and maybe fetching, but you should still cache yourself if needed (ie the unstable cache)
Masai LionOP
Ok, I got confused because I read about them under the
data fetching topic on the next docs.if this is on server, and your self hosting, you can just:
it will be the same no matter where imported
export const global_config = payload.findGlobal({ slug: 'general-Website-Config' });it will be the same no matter where imported
and then if you need server action for client, you can return that (but your just returning jsonable config?)
Is this function gonna be run at build time?
its going to "build" whenever its first accessed
and id assume something in build needs it
wait it prob would be once in build and then another when started
but shouldnt be multiple times per process (in theory)
@riský but shouldnt be multiple times per process (in theory)
Masai LionOP
The data is immutable. I only want it to be fetched again once the CMS updates. Once the CMS updates, I will trigger a new build on vercel through webhooks.
hmm in that case unstable_cache
and you shouldnt need to rebuild and in theory just
revalidate tags and necessary pagesMasai LionOP
But doesn't unstable_cache persists across builds?
yeah but arent you going to send notification to clear from CMS?
so it isnt much of an issue i would have thought
(means build is that one bit simpler)
@riský yeah but arent you going to send notification to clear from CMS?
Masai LionOP
I could, but I have no idea how to handle this new information flow you are describing
But that would be a new level of complexicity compared to the default static site generation next was capable using the
getStatisProps() from the pages router. Something similar to what Gatsby does.sorry, i have barly used pages dir, but how much is cached there and you can do that in app dir too
you can just use it in server component (and if thats static, then it will be too)
@riský you can just use it in server component (and if thats static, then it will be too)
Masai LionOP
Ok, even if they are server actions?
Common House-Martin
as long as you don't do revalidate path /tag data will be generated on build time
@Common House-Martin as long as you don't do revalidate path /tag data will be generated on build time
Masai LionOP
That's awesome, I was overthinking how it works
@Masai Lion Ok, even if they are server actions?
i dont understand how server actions are comparable to getstaticprops
server actions are a fancy api route for client to fetch
@riský i dont understand how server actions are comparable to getstaticprops
Masai LionOP
I just want to encapsulate logic, because I have a number of followers on steam, if I fetch it on servers components, it just gives me different numbers for each page. On some pages it is like 200,345, in another one it is 200,367
Because some people followed during the build process (I believe)
@riský server actions are a fancy api route for client to fetch
Masai LionOP
Ok, so I not using them correctly. They are mainly for client components and not server components
yeah
its really badly done
"use client" is client page
"use server" is not opposite
"use server" is not opposite
Answer
@Masai Lion I just want to encapsulate logic, because I have a number of followers on steam, if I fetch it on servers components, it just gives me different numbers for each page. On some pages it is like 200,345, in another one it is 200,367
Common House-Martin
that's probably because you're doing the db call on each page, if you use a single server action to fetch all the data and then use that action for all the pages you should have the same data on all of them i believe
if you call server action on server, your just calling function normally
but with added risk that its callable for anyone (so can be security risk)
@riský but with added risk that its callable for anyone (so can be security risk)
Masai LionOP
hmmmmmmmmmmmmmmmmmm that's another thing to think of. Thanks
i cant imagine how many people have exposed important things with this
@Common House-Martin that's probably because you're doing the db call on each page, if you use a single server action to fetch all the data and then use that action for all the pages you should have the same data on all of them i believe
Masai LionOP
Ok, I will try it and see if it updates after building the website
you can
import "server-only" to error if imported to client page tho :)@riský you can `import "server-only"` to error if imported to client page tho \:)
Masai LionOP
Awesome, that's great to know. I don't want client fetching these expensive endpoints.
well they wont work if you dont make server action (as env vars), but good built time error for you
@riský well they wont work if you dont make server action (as env vars), but good built time error for you
Masai LionOP
Got you, so I don't even need to worry about it ifthey are just functions, and not server actions
yeah
as long as you dont have the creds hard coded and dont have it in
NEXT_PUBLIC_, i see no way of it working (esp if your lib requires node to work)but basicly you shouldnt need to worry about it (esp if it wasnt an issue in pages dir)
@riský but basicly you shouldnt need to worry about it (esp if it wasnt an issue in pages dir)
Masai LionOP
Got you, I appreciate you help a lot
any more questions before i get side tracked again 😭
Masai LionOP
I've been doing stuff with next for a while and I was having a hard time understanding the StaticSG part. The ServerSG is awesome
@riský any more questions before i get side tracked again 😭
Masai LionOP
No, that's it, thank you a lot once again
yay nice
@Masai Lion I've been doing stuff with next for a while and I was having a hard time understanding the StaticSG part. The ServerSG is awesome
yeah, also think of client components as pages dir (as ssr still here), and as server components as new shiny thingy
also to mark this as solved, you can follow
Right click -> Apps -> Mark Solution on the best message!@riský also to mark this as solved, you can follow `Right click -> Apps -> Mark Solution` on the best message!
Masai LionOP
Will do, just need to find the correct one