diff --git a/.changeset/lucky-moths-nonce.md b/.changeset/lucky-moths-nonce.md new file mode 100644 index 000000000..27dd7be09 --- /dev/null +++ b/.changeset/lucky-moths-nonce.md @@ -0,0 +1,8 @@ +--- +"@solidjs/start": patch +--- + +Apply the configured `nonce` to the two script tags that were still missing it, so a strict `script-src` CSP no longer needs `unsafe-inline`: + +- The client-side redirect that streaming mode emits after the shell has already flushed (``) now carries the nonce. +- The SPA entry script tag now carries the nonce, matching the SSR entry script. diff --git a/packages/start/src/server/handler.ts b/packages/start/src/server/handler.ts index d4fb6e4b7..18f2ddca5 100644 --- a/packages/start/src/server/handler.ts +++ b/packages/start/src/server/handler.ts @@ -210,10 +210,20 @@ function handleStreamCompleteRedirect(context: PageEvent) { return ({ write }: { write: (html: string) => void }) => { context.complete = true; const to = context.response && context.response.headers.get("Location"); - to && write(``); + if (!to) return; + // The shell has already flushed, so the redirect has to happen client side. + // Carry the nonce so a strict `script-src` CSP doesn't block it. + const nonce = context.nonce ? ` nonce="${escapeAttribute(context.nonce)}"` : ""; + write( + `window.location=${JSON.stringify(to).replace(/`, + ); }; } +function escapeAttribute(value: string) { + return value.replace(/&/g, "&").replace(/"/g, """).replace(/