SSR Cookies
Hi all,
I'm new to SSR and don't fully understand in the solidstart basic example which components are being rendered server side / client side.
I'm using tanstack solid-query and for testing I have a button that on press calls a /click route on my server and adds a row to the database consisting of:
- a deviceId cookie
- the current time
I then have a /clicks routes that gets the number of clicks for each deviceId (and i use createQuery to use it in solid)
Every time the routes /click and /clicks are called, the server checks if deviceId cookie exists and generates a new deviceId if not.
This works great if I have a button or something that forces the query to be done client side, since all the client side cookies are passed, however if I try to get the value of that query on the official page load, the cookies aren't passed and so the initial state always begins at 0
My question is is there a way to pass the client cookies when making server side requests?
26 Replies
I think setCookie and getCookie are useful for your scenario. Import them from vinxi/http rather than h3 because vinxi has wrapped them for better experience. Based on them, you could handle cookie within http request, and they work well with SSR of Solidstart.
what's more, if you wanna encrypt the cookie, you could try useSession which is a special cookie that encrypt in the server.
The example and documents plz check the following link:
https://h3.unjs.io/examples/handle-cookie
tip: import from vinxi/http rather than h3
Handle Cookie - h3
Use cookies to store data on the client.
Since my cookie is set server side (from a seperate api server) with set-cookie header, can I still use getCookie on it from the SSR context?
Also, when using setCookie and getCookie, is that something that needs to be done before each request? or is there a way to integrate that into fetch so it automatically loads the client cookies when making requests from SSR
Since you're calling
fetch
on both the client and the server, you'll need to manually provide the cookies on the server with your own wrapper or something
So on the client you don't need to do anything, but on the server use getHeader
or getCookie
and give the values to fetch
I've set up my api client (elysiajs eden treaty) to on each server request add headers from getHeaders() and that works great. To make sure response headers get back to my client, do I want to use
setHeaders
or setResponseHeaders
either one, they're the same function
Ah yeah I see, thanks so much
I have this now for setting up my api client, does it seem ok?
For some reason my client was displaying no content if I didn't add the "use server" directive in my getServerHeaders and setServerHeaders functions (even though I assumed checking isServer before doing a server only action would be enough)
i'd try avoid the
use server
if possible
those functions are publically exposed
maybe lazy import vinxi/http
?Like so?
const {getHeaders} = await import("vinxi/http")
Hm that still doesn't work, for some reason a suspense is not resolving when it's like that, I'm not sure exactly how to debug it
are the headers logging on the server properly?
Yeah
both when I use "use server" and when I don't they come through correctly from the SSR
I don't really understand how to figure out what triggers an error because there are no console logs (in the chrome dev console), I'm not quite sure why but I created an app to test from the
bare
template and I do get an error in console
Here's my bare app.tsx (setup like I originally had with "use server")
When I load the page ssr works correctly and I get the following output from the server console:
And the page loads correctly on the client side too, I get the following output in my devtools console
just a heads up,
before import
isn't actually running before the import. all top level imports get hoisted upOkay good to know, I noticed before import wasn't being called (but was with lazy importing)
Now if I change the testFunc to not use "use server"
I get the same output from the server console (working correctly):
But I get an error in the browser console
yeah that's expected
vinxi/http
only works on the serverBut I'm never calling testFunc()
vinxi/http
is importing node:async_hooks
which is bundled into the client
and produces that errorHow would I implement that here so that I only call it on the server without using use_server
i'd figure out how to make it work with lazy imports lol
Wait is the idea that the lazy imports are not top level
yeah
That makes a lot more sense lol
Wait and when I use "use server", is that making an endpoint the client can call?
yeah
I have it all working now, thanks so much :)
I'm still confused why my errors aren't being printed to console (Any error thrown inside a component shows an error on a screen but top level errors seem to just dissapear (and cause everything in that suspense to not render)
I have solid-devtools and tanstack query devtools so I'm not sure if one of those is changing error handling (or if it's somewhere else in my project)