solid-start
solid-start copied to clipboard
[Bug?]: return json() in action is not SSR ready
Duplicates
- [x] I have searched the existing issues
Latest version
- [x] I have tested the latest version
Current behavior 😯
When an action returns json, it breaks compatibility with server-side rendering in cases where you have a classic form without javascript.
Expected behavior 🤔
I expect to remain on the same page if my action returns a JSON constructed with the SolidJSRouter method.
Steps to reproduce 🕹
Steps:
- Build a classic form <form action={myAction} method="post"
- Have myAction return
return json({test: true}) - And I am redirected to a page like http://localhost:3000/_server?id=src_app_routes_unauthenticated...
Context 🔦
I simply want it to be fully compatible without JavaScript.
my solution here (work) :
export type SubmissionSource = "form" | "useAction" | "unknown";
export const detectSubmissionSource = (): SubmissionSource => {
const event = getRequestEvent();
const headers = event?.request.headers;
if (!headers) return "unknown";
const secFetchDest = headers.get("sec-fetch-dest");
const secFetchMode = headers.get("sec-fetch-mode");
const secFetchUser = headers.get("sec-fetch-user");
const isUseAction =
secFetchDest === "empty" && secFetchMode === "cors" && !secFetchUser;
const isFormSubmission =
secFetchDest === "document" &&
secFetchMode === "navigate" &&
secFetchUser === "?1";
if (isUseAction) return "useAction";
if (isFormSubmission) return "form";
return "unknown";
};
export const jsonIsomorphic = <T>(data: T, init?: RouterResponseInit) => {
const source = detectSubmissionSource();
if (source === "useAction") {
return json(data, init);
}
return data;
};
A solution that almost works, but I can't retrieve the data from submission.result.
return json(
{
hello: "lzl",
},
{
headers: {
location: new URL(
getRequestEvent()?.request.headers.get("referer") || "",
).pathname, // or your location => "sign-up"
},
},
);