mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
Follow-up to #94957, which made cached `ImageResponse` routes statically prerenderable by serializing the constructor arguments through React Flight (to build a cache key and to run the element's async Server Components once). A custom font passed as a `Buffer` in the options was corrupted by that round-trip: Flight applies the `toJSON` method that Node's `Buffer` carries, so the font reached satori as a `{ type: 'Buffer', data: [...] }` plain object rather than binary, and satori's font parser threw `TypeError: First argument to DataView constructor must be an ArrayBuffer`. The crash happened even without a user `'use cache'` directive, because the serialization runs unconditionally during the prerender. We now serialize only the element through Flight, which is the only part that needs async resolution and dynamic-input detection, and pair the resolved element with the original in-memory options when handing the tree to satori. The font `Buffer` is therefore never serialized and reaches satori intact. The cache key no longer comes from the serialized arguments either; it is derived from a SHA-256 hash of the serialized element combined with a content hash of the options, with binary font data hashed by its bytes and everything else by a sorted, type-tagged walk. Besides fixing the crash, this keeps font bytes out of the cache key and removes the "Uint8Array objects are not supported" warning that the dev React runtime emitted during `next build --debug-prerender`. The custom-fonts documentation example now loads the font once at module scope. This keeps the route statically generated, since reading inside the component would be uncached I/O that Cache Components treats as dynamic, and it steers users away from wrapping the read in `'use cache'`, which would route the font `Buffer` through use-cache's own Flight serialization and reintroduce the same corruption upstream of `ImageResponse`, where this fix cannot reach it. A regression test loads a local font via a module-scope `readFile` and asserts the route prerenders statically.