I have a main page which adds data to my database using a form and server actions. When I add a record and then navigate using a <Link> component to /history which just fetches and renders all the existing records (via await prisma.workday.findMany()) the data is stale and doesn't contain the newly added record. The data isn't stale after I refresh, but that's cumbersome. How can I fix this problem?
#Stale data on client-side navigation
82 messages · Page 1 of 1 (latest)
🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord
🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in <id:customize>
✅ You can mark a message as the answer for your post with `Right click -> Apps -> Mark Solution`
(if you don't see the option, try refreshing Discord with Ctrl + R)
use react query to refresh the stale data on mount
hard navigation only refresh their data after ~30 second on route change
I'd prefer not to change my components to be client ones
I thought that maybe dynamic = 'force-dynamic' or revalidate = 0 would do the trick but they don't, why is that?
they do, but hard navigation are cached for ~30 seconds :))
if you don't spam for ~ 30 seconds they will refetch
but if you spam it they wont get refreshed haha
So I've just tried waiting 30s after adding data to my db and after navigation the data is still old
export default async function History() {
const allWorktimes = await prisma.workday.findMany();
...
}
did you wait 30 second then move another route then back to the same route
or did you just wait 30 seconds and do nothing 🫠
I added data on my root page, I waited 30s and I navigated to /history using <Link />
hmmmm das weird, make sure you didn't hover it though since hovering it will prefetch the data ahead of time
interesting, didnt know this
where did you find out about this
i have a repro repo, wait a sec, testing it again to make sure im not insane 😶🌫️
this behaviour is documented and called 'soft navigation'
to force hard navigation i just use native <a> tags now
or call revalidatePath + force-dynamic + prefetch={false}
I've read about it a bit, but as I said later I tried using dynamic = 'force-dynamic' and revalidate = 0 in /history but it still didn't work
I also call revalidatePath('/') on the end of my server action
and prefetch={false} doesn't do anything in dev right? only prod
I might try the <a> tag approach
well this combo is working for me 
atleast the RSC is prerendered again, and awaits are awaited again, not sure about the data
Ok I'll try it one more time, but I think waiting 30s also just worked, but that's still not a good solution to me
30 seconds is such a random number so idt that is the case
without specialised configuration
it may have +-3 seconds since im using a windows clock timer lmao
i couldn't figure out where they store the cache so i didnt know the exact time
yeah nvm the waiting hasn't worked rn
you know what actually the prefetch={false} makes all the difference, I don't even need force-dynamic idk wtf that's used for then but well yeah it works now the data is always fresh
use all of them mwa ha ha ha
✅ Success!
This question has been marked as answered! If you have any other questions, feel free to create another post
Jump to answer
[Click here](#1119620757425762314 message)
what 💀
if you dont use force-dynamic how is it dynamic
I have no clue man
probably you used headers() or cookies() somewhere
no
💀
import prisma from '$lib/db/prisma';
import { formatWorktime, round } from '$lib/utils';
export default async function History() {
const allWorktimes = await prisma.workday.findMany();
const dateFormatter = Intl.DateTimeFormat('en-UK', { dateStyle: 'long' });
return (
<ol className="worktime-list">
{allWorktimes.map(worktime => (
<li key={worktime.id}>
<h2>{dateFormatter.format(new Date(worktime.date))}</h2>
<p>Worktime: {formatWorktime(worktime.worktime)}</p>
<p>Earned: {round(worktime.earned, 2)}zł</p>
</li>
))}
</ol>
);
}
well if it works it works
this is my entire page.tsx
that is likely the case
no I only have one layout.tsx
oh wait, if you did call revalidatePath probably that means the thing is revalidated
so no need of dynamic
hmm interesting
i think i have some code changes to do in my apps
where did you put revalidatePath?
but is it ok though to put revalidatePath on every user navigation. wouldn't it affect the server?
export default async function Home() {
async function addWorkday(data: FormData) {
'use server';
// ...
revalidatePath('/');
}
// ...
}
here
ohhhhhhhhhhhhhhhhhhhhhhhh
yeah ive done that too
no, i only use revalidatePath in server actions, like how it is supposed to be used
i thought you put it in server comps hah
do you have to do anything after the server action has finished running? like router.refresh or somethin
since mutation is released i can no longer claim i know how nextjs works anymore
hmm lemme check
ah no, i don't redirect after server actions
but i do revalidate all pages
and after that if i use next/link prefetch=false to navigate to any pages
it shows updated data
but then if I don't have revalidatePath() but I do have force-dynamic in /history it doesn't work again
what's the point of force-dynamic does it even work correctly
ok wait tf is it actually mandatory to wait that 30 or smthn seconds because I did that again out of curiosity and it worked
💀 umm
just next.js working in some black magic man, this is beyond humanity comprehension
this is obviously not my ideal solution I'm going back to the revalidatePath one, but it's interesting
make sure you also erase .next folder to be sure that it don't cache anything every time you change the dynamic/static of a route (?)
that's next level 💀
nextjs level? 
exactly