solid-start
solid-start copied to clipboard
[Bug?]: `set-cookie`s from server action's response `return` being overwritten with `flash` cookie
Duplicates
- [X] I have searched the existing issues
Latest version
- [X] I have tested the latest version
Current behavior 😯
Solid Start overwrites set-cookie's from my server action's returned response with flash cookie in no JS mode.
Expected behavior 🤔
For the client to receive my set-cookie headers.
Steps to reproduce 🕹
return redirect("/foo", { headers: { "set-cookie": "foo=bar" } })
in server action
Context 🔦
I'm trying to set a cookie from a server action.
Your environment 🌎
System:
OS: NixOS 24.05.5518.ecbc1ca8ffd6 (Uakari) x86_64
CPU: 12th Gen Intel(R) Core(TM) i5-12500 (12) @ 4.60 GHz
Binaries:
Node: 22.6.0
PNPM: 9.12.0
npmPackages:
@solidjs/meta 0.29.4
@solidjs/router 0.14.7
@solidjs/start 1.0.8
solid-js 1.9.1
For other people running into this issue, I am currently using this patch as a workaround:
diff --git a/dist/runtime/server-handler.js b/dist/runtime/server-handler.js
index 9f86080139b32ce71dcc27103ecd26549191cdbc..9aab397f46d729b2a6bc236c6b542018b407e364 100644
--- a/dist/runtime/server-handler.js
+++ b/dist/runtime/server-handler.js
@@ -207,28 +207,28 @@ async function handleServerFunction(h3Event) {
function handleNoJS(result, request, parsed, thrown) {
const url = new URL(request.url);
const isError = result instanceof Error;
- let redirectUrl = new URL(request.headers.get("referer")).toString();
let statusCode = 302;
- if (result instanceof Response && result.headers.has("Location")) {
- redirectUrl = new URL(result.headers.get("Location"), url.origin + import.meta.env.SERVER_BASE_URL).toString();
- statusCode = getExpectedRedirectStatus(result);
+ let headers;
+ if (result instanceof Response) {
+ headers = new Headers(result.headers)
+ if (result.headers.has("Location")) {
+ headers.set(`Location`, new URL(result.headers.get("Location"), url.origin + import.meta.env.SERVER_BASE_URL).toString())
+ statusCode = getExpectedRedirectStatus(result);
+ }
+ } else
+ headers = new Headers({ Location: new URL(request.headers.get("referer")).toString() })
+ if (result) {
+ headers.append("Set-Cookie", `flash=${JSON.stringify({
+ url: url.pathname + encodeURIComponent(url.search),
+ result: isError ? result.message : result,
+ thrown: thrown,
+ error: isError,
+ input: [...parsed.slice(0, -1), [...parsed[parsed.length - 1].entries()]]
+ })}; Secure; HttpOnly;`)
}
return new Response(null, {
status: statusCode,
- headers: {
- Location: redirectUrl,
- ...(result
- ? {
- "Set-Cookie": `flash=${JSON.stringify({
- url: url.pathname + encodeURIComponent(url.search),
- result: isError ? result.message : result,
- thrown: thrown,
- error: isError,
- input: [...parsed.slice(0, -1), [...parsed[parsed.length - 1].entries()]]
- })}; Secure; HttpOnly;`
- }
- : {})
- }
+ headers
});
}
let App;
This looks pretty good. I will add it in, but PR is more than welcome next time.