Repository navigation
Conversation
When `experimental.ssrStreaming: true` (Nuxt 4.5+), the body / bodyAppend sections are flushed to the wire before the `render:html` hook can mutate them, so scripts injected there (notably `window.__NUXT__` and `__NUXT_DATA__`) reach the browser without a nonce and are blocked by a strict CSP, breaking hydration. Add a `render:html:chunk` hook alongside the existing `render:html` hook. The new hook patches script/style/link tags on their way out via a negative-lookahead regex, so tags already noncified via `render:html` (head / bodyPrepend, which still work in streaming mode) are not re-stamped. In buffered mode the hook simply never fires, so non-streaming behavior is unchanged. Fixes #757
|
@nguyengg is attempting to deploy a commit to the Baroshem's projects Team on Vercel. A member of the Team first needs to authorize it. |
Author
|
Closing at author's request — will revisit later. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Types of changes
Description
Fixes #757.
When
experimental.ssrStreaming: true(Nuxt 4.5+), the body / bodyAppend sections are flushed to the wire before therender:htmlhook can mutate them, so scripts injected there — notablywindow.__NUXT__config and<script id="__NUXT_DATA__">— reach the browser without a nonce and are blocked by a strict CSP, breaking hydration entirely (blank page, TypeError in console).Fix
src/runtime/nitro/plugins/40-cspSsrNonce.tsgains arender:html:chunkhook alongside the existingrender:htmlhook:render:htmlcontinues to handle head / bodyPrepend (which still work in streaming) plus the whole document in buffered mode — unchanged.render:html:chunkfires once per streamed chunk and patches script / style / link tags on their way out.The chunk hook uses a negative-lookahead regex (
<script(?![^>]*\snonce=)...) so tags already noncified viarender:htmlare not re-stamped when they appear in a streamed chunk. In buffered mode the new hook simply never fires — non-streaming behavior is unchanged.The
'render:html:chunk' as 'render:html'cast on the hook name is because the hook is only declared in Nitro'sNitroRuntimeHookson newer versions; the cast is a no-op at runtime and lets the module compile against the currently-pinned Nitro without a type augmentation.Verification
yarn lint— clean.npx vitest run test/ssrNonce.test.ts— 7 pass, 1 skipped (baseline unchanged; no regression to the buffered code path).Testing note
The repo currently pins
nuxt@^4.2.1, which predatesexperimental.ssrStreaming. A full integration test that boots a fixture withexperimental.ssrStreaming: trueand asserts every<script>in the response carries a nonce would need a devDep bump to Nuxt ≥ 4.5. Happy to submit that as a follow-up PR if the maintainers would like it — I kept this PR narrowly scoped to the runtime fix so it can be reviewed and released quickly.The regex + Buffer conversion in the new hook mirrors the workaround the reporter validated in production (see the issue's "Workaround" block), just moved inside the module so consumers don't have to write a server plugin.
Checklist:
Existing
ssrNonce.test.tsstill passes (verifies buffered-mode behavior is untouched). A streaming-mode integration test requires bumping the pinnednuxtdevDep to ≥ 4.5; deferred to a follow-up so this PR stays surgical.