revalidatepath doesnt work for dynamic routes
Answered
Asari posted this in #help-forum
AsariOP
im using
nextjs app 14.2.7. with next-intl
also i have routes like that
"app/(main)/[locale]/blog/[blogSlugName]/page.tsx"
(main is route groups)
(locale-> is lang )
(blogSlugName is blog post url path)
final url is like that -> www.domain.com/en/blog/test-blog-1
im trying to revalidate path for specific blog post ,
/////
this function working for revalidate blog list page
but the for specific post revalidation doesnt work
nextjs app 14.2.7. with next-intl
also i have routes like that
"app/(main)/[locale]/blog/[blogSlugName]/page.tsx"
(main is route groups)
(locale-> is lang )
(blogSlugName is blog post url path)
final url is like that -> www.domain.com/en/blog/test-blog-1
im trying to revalidate path for specific blog post ,
console.log("revalidate " ,`/(main)/[locale]/blog/${updatedBlogPost.urlPath}`)
revalidatePath(`/(main)/[locale]/blog/${updatedBlogPost.urlPath}/page`, 'page');
revalidatePath(`/(main)/[locale]/blog/${updatedBlogPost.urlPath}/`, 'page');
revalidatePath(`/(main)/[locale]/blog/${updatedBlogPost.urlPath}`, 'page');
revalidatePath(`/[locale]/blog/${updatedBlogPost.urlPath}/`, 'page');
revalidatePath(`/(main)/[locale]/blog`, 'page');/////
revalidatePath(`/(main)/[locale]/blog`, 'page');this function working for revalidate blog list page
but the for specific post revalidation doesnt work
Answered by joulev
you must use the file system path, which revalidates all pages that correspond to
or use the full url path, which revalidates only that specific url, so only that specific locale and slug. so you need to fetch the list of all locales and run several
/(main)/[locale]/blog/[slug] (i.e. all articles),or use the full url path, which revalidates only that specific url, so only that specific locale and slug. so you need to fetch the list of all locales and run several
revalidatePath functions.46 Replies
AsariOP
pages are ssg*
AsariOP
revalidatePath(`/(main)/[locale]/blog`, 'layout');
also this revalidate all the blog posts but i want to revalidate specific blog post
can you make a minimal reproduction repository?
AsariOP
hmm its huge project, also it should connect database to get data
now i tested this
well but without a minimal reproduction repo i can't even make a bad guess
AsariOP
revalidatePath("/en/blog/test3");this is working
but the problem is the language path is dynamic , the customer/client can add new lang to their website
so i should revalidate like
[locale]/blog/test3
[locale]/blog/test3
you can have access to the list of all locales right?
AsariOP
I think this issue is a bug of nextjs, it does not revalidate a specific path in dynamic path
for (const locale of availableLocales) {
revalidatePath(`/${locale}/...`);
}@joulev you can have access to the list of all locales right?
AsariOP
yes i can get all locales with extra database request
@Asari I think this issue is a bug of nextjs, it does not revalidate a specific path in dynamic path
no i don't think so. you either give the filesystem path (
/(main)/[locale]/blog) or you give the specific url in full (/fr/blog/hello-world). you can't do in between (/[locale]/blog/hello-world)@joulev tsx
for (const locale of availableLocales) {
revalidatePath(`/${locale}/...`);
}
AsariOP
But this extra database request will create a performance problem, it doesn't seem like a logical solution.
@Asari But this extra database request will create a performance problem, it doesn't seem like a logical solution.
but still, you can't do in between, so...
@joulev no i don't think so. you either give the filesystem path (`/(main)/[locale]/blog`) or you give the specific url in full (`/fr/blog/hello-world`). you can't do in between (`/[locale]/blog/hello-world`)
AsariOP
but its work in 1 dynamic path and specific path
im pretty sure
/(main)/[locale]/blog and /fr/blog/hello-world are handled separately and there is no way for next to know what to do with /[locale]/blog/hello-world@Asari but its work in 1 dynamic path and specific path
what do you mean?
AsariOP
hmm wait a sec
revalidatePath(`/(main)/[locale]/homepage`, 'page');this will revalidate all the locales like
/en/homepage
/fr/homepage
.....
yes because
/(main)/[locale]/homepage falls into the filesystem case and is handled accordinglyAsariOP
revalidatePath(`/(main)/[locale]/blog/blog-post-1`, 'page');then this should revalidate all the
/en/blog/blog-post-1
/fr/blog/blog-post-1
in your case here, since you want to revalidate a specific url slug, you cannot go into the filesystem case because the same filesystem path corresponds to all blog articles
@Asari javascript
revalidatePath(`/(main)/[locale]/blog/blog-post-1`, 'page');
then this should revalidate all the
/en/blog/blog-post-1
/fr/blog/blog-post-1
AsariOP
What exactly do you think I don't understand about this part?
@Asari javascript
revalidatePath(`/(main)/[locale]/blog/blog-post-1`, 'page');
then this should revalidate all the
/en/blog/blog-post-1
/fr/blog/blog-post-1
you don't have
/(main)/[locale]/blog/blog-post-1/page.tsx so it doesn't workAsariOP
hmm
there is a structure like this,
but you say that since there is no file path like this, it does not understand what to revalidate
/(main)/[locale]/blog/[blogSlugName]/page.tsxthere is a structure like this,
but you say that since there is no file path like this, it does not understand what to revalidate
ok let me explain it again for you.
each page in nextjs corresponds to one tag based on the file system path.
and it will revalidate all cache instances of the pages corresponding to this filesystem path.
each url in nextjs also corresponds to another tag based on the full url. so you also have
that's all that nextjs has. it doesn't have
each page in nextjs corresponds to one tag based on the file system path.
/(main)/[locale]/blog/[slug] corresponds to /(main)/[locale]/blog/[slug]. so you canrevalidatePath("/(main)/[locale]/blog/[slug]")and it will revalidate all cache instances of the pages corresponding to this filesystem path.
each url in nextjs also corresponds to another tag based on the full url. so you also have
/en/blog/foo-bar for the /en/blog/foo-bar page. so you can also revalidate this specific url byrevalidatePath("/en/blog/foo-bar")that's all that nextjs has. it doesn't have
/(main)/[locale]/blog/foo-bar because that doesn't correspond to either a file system path or a full url. so it doesn't work. nextjs doesn't know this tag.you must use the file system path, which revalidates all pages that correspond to
or use the full url path, which revalidates only that specific url, so only that specific locale and slug. so you need to fetch the list of all locales and run several
/(main)/[locale]/blog/[slug] (i.e. all articles),or use the full url path, which revalidates only that specific url, so only that specific locale and slug. so you need to fetch the list of all locales and run several
revalidatePath functions.Answer
AsariOP
So you're saying that the only way to solve this problem is to revalidatePath for all languages one by one like this:
revalidatePath("/en/blog/foo-bar")
revalidatePath("/fr/blog/foo-bar")If there is no other way I will update my codes this way
AsariOP
But having to make an extra database query for this situation did not seem very efficient or logical.
the thing is, nextjs only assigns two tags for a given page, one from the file system path and one from the url. you can not have the "in between"
AsariOP
Thank you so much for your help. I had spent a long time trying to solve this issue without making an extra database query. If I had known from the beginning that it was necessary, I wouldn’t have wasted hours of my time.
Thank you so much for saving me the extra time I would have spent on this issue 😄
AsariOP
I believe this information should be included in the Next.js revalidatePath documentation to help inform other users about this
i think
Either a string representing the filesystem path associated with the data you want to revalidate (for example, /product/[slug]/page), or the literal route segment (for example, /product/123).is clear enough though, it quite clearly specifies that only two strings can be used to revalidate any given page
AsariOP
Can I ask you another question about next js standalone build?
please open a new post, also i doubt i will be able to help with that one since i don't use standalone build
AsariOP
I think this question is not only about standalone build,
When I was building a project, I was trying to fetch data from the /api/getdata/route.ts API on an ISR page. However, during the build process, I couldn't get data from this API. I believe that Next.js builds pages before it builds APIs.
After running a few tests on this, I noticed that if I rendered that page once using npm run dev, the build would succeed because it cached the API data. But if I cleared the cache within the project and then tried to build again, I couldn't retrieve data from this API.
When I was building a project, I was trying to fetch data from the /api/getdata/route.ts API on an ISR page. However, during the build process, I couldn't get data from this API. I believe that Next.js builds pages before it builds APIs.
After running a few tests on this, I noticed that if I rendered that page once using npm run dev, the build would succeed because it cached the API data. But if I cleared the cache within the project and then tried to build again, I couldn't retrieve data from this API.
This happened to me in Nextjs 14.2.5. I switched to serverAction instead of API. I don't know if this problem persists in other versions.
@Asari I think this question is not only about standalone build,
When I was building a project, I was trying to fetch data from the /api/getdata/route.ts API on an ISR page. However, during the build process, I couldn't get data from this API. I believe that Next.js builds pages before it builds APIs.
After running a few tests on this, I noticed that if I rendered that page once using npm run dev, the build would succeed because it cached the API data. But if I cleared the cache within the project and then tried to build again, I couldn't retrieve data from this API.
this is expected behaviour.
* you are not supposed to fetch your own api routes. https://nextjs-faq.com/fetch-api-in-rsc
* but the data cache persists across deployments so if you cache the data, you can access it again after a
* you are not supposed to fetch your own api routes. https://nextjs-faq.com/fetch-api-in-rsc
* but the data cache persists across deployments so if you cache the data, you can access it again after a
npm run dev run without the api server running.server action is not needed here. you just put the logic there directly. no need of
use server. it should just work.