diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index fcb56a73f75..828aec1a84f 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -1,4 +1,4 @@ -import { createRenderer } from 'vue-bundle-renderer/runtime' +import { createRenderer, renderResourceHeaders } from 'vue-bundle-renderer/runtime' import type { RenderResponse } from 'nitropack' import type { Manifest } from 'vite' import { appendHeader, getQuery } from 'h3' @@ -100,7 +100,10 @@ const getSPARenderer = lazyCachedFunction(async () => { return Promise.resolve(result) } - return { renderToString } + return { + rendererContext: renderer.rendererContext, + renderToString + } }) const PAYLOAD_CACHE = (process.env.NUXT_PAYLOAD_EXTRACTION && process.env.prerender) ? new Map() : null // TODO: Use LRU cache @@ -150,6 +153,14 @@ export default defineRenderHandler(async (event) => { // Render app const renderer = (process.env.NUXT_NO_SSR || ssrContext.noSSR) ? await getSPARenderer() : await getSSRRenderer() + + // Render 103 Early Hints + if (!isRenderingPayload && !process.env.prerender && event.res.socket) { + const { link } = renderResourceHeaders({}, renderer.rendererContext) + // TODO: use https://github.com/nodejs/node/pull/44180 when we drop support for node 16 + event.res.socket!.write(`HTTP/1.1 103 Early Hints\r\nLink: ${link}\r\n\r\n`, 'utf-8') + } + const _rendered = await renderer.renderToString(ssrContext).catch((err) => { if (!ssrError) { // Use explicitly thrown error in preference to subsequent rendering errors