Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(nitro,nuxt,schema): add experimental SSR streaming with unhead v3#34411

Draft
danielroe wants to merge 7 commits intomainfrom
feat/ssr-streaming
Draft

feat(nitro,nuxt,schema): add experimental SSR streaming with unhead v3#34411
danielroe wants to merge 7 commits intomainfrom
feat/ssr-streaming

Conversation

@danielroe
Copy link
Member

πŸ”— Linked issue

resolves #4753

πŸ“š Description

one of the longest-standing nuxt issues...

this PR:

  • adds experimental.ssrStreaming to send an HTML shell (head, styles, preload hints) immediately + then stream the Vue app body via renderToWebStream
  • upgrades @unhead/vue to v3 beta for streaming head support
  • disables streaming for bot/crawler user agents
  • allows per-route opt-out via routeRules

@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@socket-security
Copy link

socket-security bot commented Mar 1, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​unhead/​vue@​2.1.4 ⏡ 3.0.0-beta.1110010010096 +2100

View full report

@danielroe danielroe force-pushed the feat/ssr-streaming branch from f020808 to 0e458df Compare March 2, 2026 07:53
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 2, 2026

Open in StackBlitz

@nuxt/kit

npm i https://pkg.pr.new/@nuxt/kit@34411

@nuxt/nitro-server

npm i https://pkg.pr.new/@nuxt/nitro-server@34411

nuxt

npm i https://pkg.pr.new/nuxt@34411

@nuxt/rspack-builder

npm i https://pkg.pr.new/@nuxt/rspack-builder@34411

@nuxt/schema

npm i https://pkg.pr.new/@nuxt/schema@34411

@nuxt/vite-builder

npm i https://pkg.pr.new/@nuxt/vite-builder@34411

@nuxt/webpack-builder

npm i https://pkg.pr.new/@nuxt/webpack-builder@34411

commit: 51c6ba5

@codspeed-hq
Copy link

codspeed-hq bot commented Mar 2, 2026

Merging this PR will not alter performance

βœ… 20 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing feat/ssr-streaming (51c6ba5) with main (017a493)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@harlan-zw
Copy link
Contributor

Added the IIFE client so tags can run as they're streamed in

&& !ssrError
&& !isRenderingPayload
&& !import.meta.prerender
&& !componentIslands
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was running into some issues here (this was if componentIslands was enabled not in the renderring context)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I would like this not to be a requirement - currently there's a string.replace call that we need to work around (cc: @huang-julien)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look this weekend or the next one

iifeScript = `<script async src="${buildAssetsURL(iifeChunkFileName)}"></script>`
} else {
// Dev: inline the IIFE code (Vite dev server transforms to ESM so script src won't work)
const { streamingIifeCode } = await import('unhead/stream/iife')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs to be @unhead/vue/stream/iife

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also ideally I'd like to import at the top level rather than dynamically

const headChunk = renderSSRHeadSuspenseChunk(ssrContext.head)
if (headChunk) {
controller.enqueue(encoder.encode(`<script>${headChunk}</script>`))
controller.enqueue(encoder.encode(`<script>${headChunk};document.currentScript.remove()</script>`))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoids hydration bug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SSR Streaming / improve Time to First Byte

3 participants