Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: Unclear how to serve static assets generated during ISR #74264

Open
kirill-konshin opened this issue Dec 24, 2024 · 0 comments
Open

Docs: Unclear how to serve static assets generated during ISR #74264

kirill-konshin opened this issue Dec 24, 2024 · 0 comments
Labels
Documentation Related to Next.js' official documentation.

Comments

@kirill-konshin
Copy link
Contributor

kirill-konshin commented Dec 24, 2024

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:

  • 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?

Save file to public folder

  • Can't set caching and middleware is not utilized during ISR
  • 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

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

@kirill-konshin kirill-konshin added the Documentation Related to Next.js' official documentation. label Dec 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation Related to Next.js' official documentation.
Projects
None yet
Development

No branches or pull requests

1 participant