S
SolidJS10mo ago
knpwrs

Setting cookies (or headers in general) from `createServerData$`

Is it possible to set cookies (or any other headers) from the fetcher passed to createServerData$? I have the following code:
export function routeData() {
const user = createServerData$(async (_, { request }) => {
const client = await createAuthenticatedClient(request);

return client.request<MeQuery>(gql`
// ...
`);
});

const success = createServerData$(async (_, { request }) => {
const session = await getSession(request);

return session.get('success');
});

return { user, success };
}
export function routeData() {
const user = createServerData$(async (_, { request }) => {
const client = await createAuthenticatedClient(request);

return client.request<MeQuery>(gql`
// ...
`);
});

const success = createServerData$(async (_, { request }) => {
const session = await getSession(request);

return session.get('success');
});

return { user, success };
}
getSession is just a wrapper around the cookie session storage that's built in to solid-start. When I call useRouteData<typeof routeData>() in my component I can get success from the session. success was set on a previous route as such:
session.flash('success', 'Your email has been verified!');

return redirect('/', {
headers: { 'Set-Cookie': await storage.commitSession(session) },
});
session.flash('success', 'Your email has been verified!');

return redirect('/', {
headers: { 'Set-Cookie': await storage.commitSession(session) },
});
Now I would like to commit the session with the flash message deleted. How can I do this from within createServerData$? It doesn't seem that I'm able to return a Response or anything like that, and redirect wouldn't make sense either.
2 Replies
knpwrs
knpwrs10mo ago
I came across this post: https://discordapp.com/channels/722131463138705510/1057288732555878530/1057384833497714688 Which lead me to do the following: Inside routeData()
const successData = createServerData$(async (_, { request }) => {
const session = await getSession(request);

return json(session.get('success') ?? '', {
headers: { 'Set-Cookie': await commitSession(session) },
});
});

return { user, successData };
const successData = createServerData$(async (_, { request }) => {
const session = await getSession(request);

return json(session.get('success') ?? '', {
headers: { 'Set-Cookie': await commitSession(session) },
});
});

return { user, successData };
And then inside the component:
const [success] = createResource(successData, (s) => s.json());
const [success] = createResource(successData, (s) => s.json());
And then I can use it in my tsx!
<main>{success()}</main>
<main>{success()}</main>
Carlo Nyte
Carlo Nyte10mo ago
Thank you for sharing this. I'm currently facing the same issue and thought I was going crazy. I'm still confused why the data from createServerData$ isn't accessible to the component