revalidate cache not working
Answered
Netherland Dwarf posted this in #help-forum
Netherland DwarfOP
I have a function to get translation that will fetch from db to be used on Frontend and also have a cms to update the translation but after deploying to vercel preview; when I try to update the content it’s successful but the data is still stale 🤔
Can someone explain how the cache works? Altho I followed the docs but ya is still not working I need on demand revalidate
Can someone explain how the cache works? Altho I followed the docs but ya is still not working I need on demand revalidate
75 Replies
Netherland DwarfOP
export const getDictionary = cache(async (locale: Locale) => {
try {
const response = await fetch(
`${getBaseUrl()}/api/translations?locale=${locale}`,
{
// cache: 'no-store',x
next: {
// revalidate: 0,
tags: ["translation"],
},
}
);
// console.log(response)
if (!response.ok) {
throw new Error(
`Failed to fetch translations for locale: ${locale}`
);
}
const translationsArray: Translation[] = await response.json();
// Convert array to nested dictionary format
const dictionary: { [key: string]: any } = {};
translationsArray.forEach(({ key, translation }) => {
const keyParts = key.split(".");
let currentLevel: { [key: string]: any } = dictionary;
keyParts.forEach((part, index) => {
if (index === keyParts.length - 1) {
currentLevel[part] = translation;
} else {
currentLevel[part] = currentLevel[part] || {};
currentLevel = currentLevel[part];
}
});
});
return dictionary;
} catch (error) {
console.error(error);
// Handle the error or return a default/fallback dictionary
}
});then in pages that need
const dictionary = await getDictionary(lang);
const homePage = dictionary?.page?.home;then in my api ~
export const POST = async ({ json }: NextRequest) => {
try {
const body = await json();
const { id, key, locale, translation } = body.data;
await db
.insert(translationsTable)
.values({
id,
key,
locale,
translation,
})
.onConflictDoUpdate({
target: [translationsTable.id],
set: {
translation,
},
})
.execute();
revalidateTag("translation");
return new NextResponse(
JSON.stringify({ message: "Translation updated successfully" }),
{
headers: { "Content-Type": "application/json" },
status: 200,
}
);
} catch (error) {
return new NextResponse(
JSON.stringify({ message: "An error occurred" }),
{
headers: { "Content-Type": "application/json" },
status: 500,
}
);
}
};not sure if its the correct usage or not
any guidance will be appreciated
Netherland DwarfOP
this is so confusing, the behaviour build && start is not the same as preview/production deploy-ed ~
Alright so @Netherland Dwarf
1) dev mode doesn't have cache so it's different from what happens in prod
2) from an api route, for revalidatePath/revalidateTag to work, you need to also router.refresh() so simply add that at the end of your fetch call from the client(when you get a response)
From a server action this is not needed, it automatically updates
1) dev mode doesn't have cache so it's different from what happens in prod
2) from an api route, for revalidatePath/revalidateTag to work, you need to also router.refresh() so simply add that at the end of your fetch call from the client(when you get a response)
From a server action this is not needed, it automatically updates
Netherland DwarfOP
for #2 its stated in the docs?
I think so, not sure tbh
Netherland DwarfOP
cause i've been cracking at this for a few days, not sure whats going on
Did you try #2?
Netherland DwarfOP
trying now ~
Netherland DwarfOP
doesnt seem to make any diff
@Arinji Alright so <@1103973631496814692>
1) dev mode doesn't have cache so it's different from what happens in prod
2) from an api route, for revalidatePath/revalidateTag to work, you need to also router.refresh() so simply add that at the end of your fetch call from the client(when you get a response)
From a server action this is not needed, it automatically updates
Netherland DwarfOP
is your answer meant for server action, im not using actions ðŸ§
Netherland DwarfOP
seems like the data is cached and cant revalidate or get latest, tested everything but cant seem to see latest data being fetch
Tonkinese
i boohoo, i got the same prob and i try that https://discord.com/channels/752553802359505017/1007476603422527558/threads/1187015646651891803 , and it s work
Netherland DwarfOP
hi @Tonkinese cant seem to click the link
Netherland DwarfOP
@Ray sry for tagging you but i tried alot of things right now its even more weird that dev is working and after deploy to prod its still the same as before
@Netherland Dwarf <@743561772069421169> sry for tagging you but i tried alot of things right now its even more weird that dev is working and after deploy to prod its still the same as before
so you have one GET endpoint for querying the data from db and a POST endpoint for updating?
can you show the code for the GET endpoint
Netherland DwarfOP
export const dynamic = "force-dynamic";
export async function GET(req: NextRequest) {
const path = req.nextUrl.searchParams.get("path");
try {
const url = new URL(req.url);
const locale = url.searchParams.get("locale");
const key = url.searchParams.get("key");
let query = db.select().from(translationsTable);
if (key) {
// @ts-ignore
query = query.where(eq(translationsTable.key, key));
}
if (locale) {
// @ts-ignore
query = query.where(eq(translationsTable.locale, locale));
}
const translations = await query.execute();
if (path) {
revalidateTag("translation");
revalidatePath(path);
return Response.json({ revalidated: true, now: Date.now() });
}
return new Response(JSON.stringify(translations), {
headers: { "Content-Type": "application/json" },
status: 200,
});
} catch (error) {
return new Response(JSON.stringify({ message: "An error occurred" }), {
headers: { "Content-Type": "application/json" },
status: 500,
});
}
}export const dynamic = "force-dynamic";
....
export const getDictionary = async (locale: Locale) => {
try {
const response = await fetch(
`${getBaseUrl()}/api/translations?locale=${locale}`,
{ cache: "no-store" }
// next: { tags: ["translation"] }
);
if (!response.ok) {
throw new Error(
`Failed to fetch translations for locale: ${locale}`
);
}
const translationsArray: Translation[] = await response.json();
// Convert array to nested dictionary format
const dictionary: { [key: string]: any } = {};
translationsArray.forEach(({ key, translation }) => {
const keyParts = key.split(".");
let currentLevel: { [key: string]: any } = dictionary;
keyParts.forEach((part, index) => {
if (index === keyParts.length - 1) {
currentLevel[part] = translation;
} else {
currentLevel[part] = currentLevel[part] || {};
currentLevel = currentLevel[part];
}
});
});
// console.log(dictionary);
return dictionary;
} catch (error) {
console.error(error);
// Handle the error or return a default/fallback dictionary
}
};@Ray so you have one GET endpoint for querying the data from db and a POST endpoint for updating?
Netherland DwarfOP
correct!
can you use
unstable_cache instead of fetching the GET endpoint on getDictionary?Netherland DwarfOP
let me try but yknow right now on my dev.xx its working but on production its not
purged on vercel also doesnt make any diff
because all are dynamic in dev
try
next build && next startNetherland DwarfOP
as in preview too?
what preview?
Netherland DwarfOP
im not testing locally, im pushing to vercel
you said its working on dev
so I ask you to test it in production build locally
export const getDictionary = async (locale: any) => {
return unstable_cache(
async (locale) => {
let query = db.select().from(translationsTable);
if (locale) {
// @ts-ignore
query = query.where(eq(translationsTable.locale, locale));
}
const translations = await query.execute();
return translations;
},
["translation"],
{
tags: ["translation"],
}
)(locale);
};Netherland DwarfOP
oh, i meant
@Ray ts
export const getDictionary = async (locale: any) => {
return unstable_cache(
async (locale) => {
let query = db.select().from(translationsTable);
if (locale) {
// @ts-ignore
query = query.where(eq(translationsTable.locale, locale));
}
const translations = await query.execute();
return translations;
},
["translation"],
{
tags: ["translation"],
}
)(locale);
};
Netherland DwarfOP
this seems to repalce the previous function but idk if its working or not
preview : https://dev.onetaptutor.com/en/become-a-tutor
prod : https://onetaptutor.com/en/become-a-tutor
cause on prod, its still the same as before, cause i also have a cms to update the translations.
preview : https://dev.onetaptutor.com/en/become-a-tutor
prod : https://onetaptutor.com/en/become-a-tutor
cause on prod, its still the same as before, cause i also have a cms to update the translations.
the text still not showing on prod
well, like I said test it on local with
next build && next startNetherland DwarfOP
its showing on local ~
so i update
its not updated
so its not working?
have you refresh the page after you update
Netherland DwarfOP
yup normal refresh and hard refresh
@Ray ts
export const getDictionary = async (locale: any) => {
return unstable_cache(
async (locale) => {
let query = db.select().from(translationsTable);
if (locale) {
// @ts-ignore
query = query.where(eq(translationsTable.locale, locale));
}
const translations = await query.execute();
return translations;
},
["translation"],
{
tags: ["translation"],
}
)(locale);
};
are you trying with this or still fetching the GET endpoint
Netherland DwarfOP
well, the cache is defo working 

i updated the dict ~
export const getDictionary = async (locale: any) => {
return unstable_cache(
async (locale: Locale) => {
let query = db.select().from(translationsTable);
if (locale) {
// @ts-ignore
query = query?.where(eq(translationsTable.locale, locale));
}
const translations = await query.execute();
// Convert array to nested dictionary format
const dictionary: { [key: string]: any } = {};
translations.forEach(({ key, translation }) => {
const keyParts = key.split(".");
let currentLevel: { [key: string]: any } = dictionary;
keyParts.forEach((part, index) => {
if (index === keyParts.length - 1) {
currentLevel[part] = translation;
} else {
currentLevel[part] = currentLevel[part] || {};
currentLevel = currentLevel[part];
}
});
});
console.log(dictionary);
return dictionary;
},
["translation"],
{
tags: ["translation"],
}
)(locale);
};its getting the data from ^
not from GET endpoint
@Netherland Dwarf so i update
Netherland DwarfOP
only this is using get/post on cms
Netherland DwarfOP
i didnt change anything for backend stuff, the getDictionary is being call on the page that requires the translation
const dictionary = await getDictionary(lang);
const findATutor = dictionary?.page?.findATutor;
<HeroSection lang={lang} translation={findATutor?.hero} />
for example ^
const findATutor = dictionary?.page?.findATutor;
<HeroSection lang={lang} translation={findATutor?.hero} />
for example ^
Netherland DwarfOP
even after setting up tags for revalidation, it doesnt seem to work
is your project on github or something?
also, is there any error when you run
next build@Ray is your project on github or something?
Netherland DwarfOP
yup, i can add you in?
added ~
i pm you the env?
wait let me see the code first
which page?
Netherland DwarfOP
dictionary is in /src/lib
for landing page using it is : src/app/[lang]/(landing)/(home)/page.tsx
other then that is the api routes
the cache is not working at all
got lot of error when building
there should be a
fetch-cache folderNetherland DwarfOP
hmm, i dont see the webpack thingy when i build
change to
unstable_cache workAnswer
Netherland DwarfOP
okay, let me try to change back and rerun build
but i can't test update
Netherland DwarfOP
err, pm you