@@ -45,7 +45,11 @@ export async function useOgImageBufferCache(ctx: OgImageRenderEventContext, opti
4545 secret ?: string
4646} ) : Promise < void | H3Error | { cachedItem : false | BufferSource , enabled : boolean , update : ( image : BufferSource | Buffer | Uint8Array ) => Promise < void > } > {
4747 const maxAge = Number ( options . cacheMaxAgeSeconds )
48- const intentionallyEnabled = ! import . meta. dev && maxAge > 0
48+ // Skip the runtime buffer cache during prerender. The output is written to a static
49+ // file served via the `/_og/s/**` route rule (which sets its own immutable caching),
50+ // and the configured backend may not exist in the Node build environment — e.g. a
51+ // Cloudflare KV binding is only bound at runtime in the Worker, not during prerender (#613).
52+ const intentionallyEnabled = ! import . meta. dev && ! import . meta. prerender && maxAge > 0
4953 let enabled = intentionallyEnabled
5054 const cache = prefixStorage ( useStorage ( ) , withTrailingSlash ( options . baseCacheKey || '/' ) )
5155 const key = ctx . key
@@ -111,8 +115,9 @@ export async function useOgImageBufferCache(ctx: OgImageRenderEventContext, opti
111115 }
112116 }
113117 }
114- if ( ! enabled ) {
115- // add http headers so the file isn't cached
118+ if ( ! enabled && ! import . meta. prerender ) {
119+ // add http headers so the file isn't cached — but not during prerender, where the
120+ // static output is meant to be cached and its headers come from the route rule.
116121 setHeader ( ctx . e , 'Cache-Control' , 'no-cache, no-store, must-revalidate' )
117122 setHeader ( ctx . e , 'Pragma' , 'no-cache' )
118123 setHeader ( ctx . e , 'Expires' , '0' )
0 commit comments