You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Looks like the topic "how to correctly serve static assets that were generated during ISR, how to save them, etc" is not quite covered in Next.js docs.
Vercel Blob is probably the best way**, might need some more explanation in the docs, especially in conjunction with ISR, especially in regards to cleanup upon page invalidation.
Is there any context that might help us understand?
In my case I use Next.js ISR as facade for Notion DB. Per Notion's policy links to images will expire in 1 hour, but since page content can live much longer and won't be changed, it makes sense to cache it for longer than 1 hour, along with images. But same will be applied to any assets, that are not publicly hosted, and stored in some kind of expensive-to-fetch storage (bare S3 w/o Cloud Front included).
I searched Google but haven't found any definitive answer what's the best practice here...
Some considerations:
These images/assets may never expire, so they can be cached for way longer than page content
But they can be invalidated when page changes (but not always, only if they become unused, e.g. stop appearing on the page)
This ticket also raises more general concern, how to clean up things cached by route when route is invalidated
Trigger for cleanup could be both external event (Notion calling Route Handler when page is edited) or internal, when Next.js revalidates the stale page
Possible solutions (including some various trickery):
Vercel Blob is probably the best way, might need some more explanation in the docs.
put does not support supplemental metadata like keys to efficiently find and invalidate blobs
Purge Cache (Delete the entire contents of the Data Cache) won't affect blobs, so custom cleanup is needed
Upload these assets to an S3 bucket and serve via Cloud Front, with full control over deletion, expiration, etc.
Obvious drawback is that this requires a lot of coding and external service
Supports metadata
But what if no blob storage, just out of curiosity, or to adhere to "Next.js-only solution"?
Simply fetch these files with force-cache during build time, and use Route Handler to return cached result, since URL won't change until next build, we're good, but:
Route Handler is an overkill for static files both for cost and performance
Will bloat the cache if expiration will be set to months
Hard to invalidate manually upon incremental build, even with tags: revalidateTag is not allowed during render (Error: Route / used "revalidateTag xxx" during render which is unsupported. To ensure revalidation is performed consistently it must always happen outside of renders and cached functions.), and middleware.ts approach won't have access to ISR cache: Error: Invariant: static generation store missing in revalidateTag"
Feature request: It would be great if along with tags we could supply route to fetch calls, so that when route is revalidated, all subsequent fetches are revalidated also
Feature request: some simple callback like export const onRevalidate(params) { ... } to perform manual cleanup when page is revalidating
These two probably deserve another ticket, should I create one?
Will incremental build have access to previous artifacts (Only assets that are in the public directory at build time will be served by Next.js.), or will FS be properly merged between increments?
Break convention and fs.write files to .next/cache and then serve via Route Handler
Feels awkward
Will Purge Cache (Delete the entire contents of the Data Cache) clean everything?
Requires to use dynamic route to serve, which will cause extra load
What is the documentation issue?
Looks like the topic "how to correctly serve static assets that were generated during ISR, how to save them, etc" is not quite covered in Next.js docs.
it's the only directory used to serve static assets
but docs don't cover how to work with generated static assets... might be misleading.Vercel Blob is probably the best way**, might need some more explanation in the docs, especially in conjunction with ISR, especially in regards to cleanup upon page invalidation.
Is there any context that might help us understand?
In my case I use Next.js ISR as facade for Notion DB. Per Notion's policy links to images will expire in 1 hour, but since page content can live much longer and won't be changed, it makes sense to cache it for longer than 1 hour, along with images. But same will be applied to any assets, that are not publicly hosted, and stored in some kind of expensive-to-fetch storage (bare S3 w/o Cloud Front included).
I searched Google but haven't found any definitive answer what's the best practice here...
Some considerations:
Possible solutions (including some various trickery):
Vercel Blob is probably the best way, might need some more explanation in the docs.
keys
to efficiently find and invalidate blobsPurge Cache (Delete the entire contents of the Data Cache)
won't affect blobs, so custom cleanup is neededUpload these assets to an S3 bucket and serve via Cloud Front, with full control over deletion, expiration, etc.
But what if no blob storage, just out of curiosity, or to adhere to "Next.js-only solution"?
Simply
fetch
these files withforce-cache
during build time, and use Route Handler to return cached result, since URL won't change until next build, we're good, but:tags
:revalidateTag
is not allowed during render (Error: Route / used "revalidateTag xxx" during render which is unsupported. To ensure revalidation is performed consistently it must always happen outside of renders and cached functions.
), andmiddleware.ts
approach won't have access to ISR cache:Error: Invariant: static generation store missing in revalidateTag"
tags
we could supplyroute
tofetch
calls, so that when route is revalidated, all subsequent fetches are revalidated alsoexport const onRevalidate(params) { ... }
to perform manual cleanup when page is revalidatingSave file to
public
folderOnly assets that are in the public directory at build time will be served by Next.js.
), or will FS be properly merged between increments?Break convention and
fs.write
files to.next/cache
and then serve via Route HandlerPurge Cache (Delete the entire contents of the Data Cache)
clean everything?Some links to prior similar issues & questions:
Does the docs page already exist? Please link to it.
https://nextjs.org/docs/app/building-your-application/optimizing/static-assets
The text was updated successfully, but these errors were encountered: