-
Notifications
You must be signed in to change notification settings - Fork 30.2k
Description
Link to the code that reproduces this issue
https://github.com/lourd/descioli.com/tree/cache-components
To Reproduce
- Clone the application, install deps, run build
- See that the [slug[/opengraph-image routes are static
├ ● /[slug]/opengraph-image │ ├ /grove/opengraph-image │ ├ /mediated-matter/opengraph-image │ ├ /out-here-archery/opengraph-image │ └ [+4 more paths]
- Comment out either the date formatting, or font fetching. Run the build again.
- See that the [slug]/opengraph-image route is dynamic instead of static>
├ ƒ /[slug]/opengraph-image
Current vs. Expected behavior
I have a route handler for generating opengraph images for posts/pages on my blog. What I want to do is adopt cacheComponents and still statically generate the images. Despite using generateStaticParams, the opengraph image route is dynamic, whereas before adopting cacheComponents it was completely static. Before I was using a plain route handler with generateStaticParams. I switched to using the built-in opengraph-image feature, but the issue still remains, the route is dynamic instead of static.
Stepping through and figuring out what's making the route opengraph-image route dynamic:
- Anything
asyncother than awaiting theparams. If I use async methods for reading files from the file system, those opt out of static rendering and make the route dynamic. - Any calls to
fetch. I'm usingfetchto download some font data. There's not really a way around this aside from downloading the fonts ahead of time and reading synchronously from the filesystem. - Any code that uses the
Dateconstructor indirectly. I'm usingdate-fnsto format the publication date:
format(story.data.publication, "LLLL do, yyyy", { in: utc })This snippet alone changes the opengraph-image route from being statically generated to dynamic.
Note
As an aside, this type of date formatting also triggers an error when building static Pages with useCache. The build errors out that this must be in a client component in a Suspense boundary. This is confusing and unexpected when just trying to format a string that isn't relative to the current time.
These are all really opaque pitfalls. There's no warnings that get logged about the route being switched from static to dynamic or why.
What I would expect is for the route to stay static when explicitly using generateStaticParams.
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 25.1.0: Mon Oct 20 19:33:00 PDT 2025; root:xnu-12377.41.6~2/RELEASE_ARM64_T6020
Available memory (MB): 32768
Available CPU cores: 10
Binaries:
Node: 24.10.0
npm: 11.6.1
Yarn: 1.22.19
pnpm: 10.27.0
Relevant Packages:
next: 16.1.1 // Latest available version is detected (16.1.1).
eslint-config-next: N/A
react: 19.2.3
react-dom: 19.2.3
typescript: 5.9.3
Next.js Config:
output: N/AWhich area(s) are affected? (Select all that apply)
cacheComponents
Which stage(s) are affected? (Select all that apply)
next build (local)
Additional context
No response