appwrite-ssr-next-js
appwrite-ssr-next-js copied to clipboard
How to make it work on localhost
So it seems that to make SSR work we need to make appwrite API a subdomain of our SSR server. I made it work, but it's only for hosted websites. Is there a way to make it work locally while developing? In that case the cookie domain for SSR is going to be localhost, which will not work with the appwrite cloud. Should I be setting up some sort of proxy?
Yes, a proxy can help here. Another solution could be to edit /etc/hosts and add definition for appwrite.localhost to point to Appwrite Cloud.
Finally, having a local instance of Appwrite can help too. There might also be some browsers for developers that allow such insecure cookies, but I haven't tired that.
Any other solution to this?
I don't want to have to install locally.
But wait, what's the main reason for having to make the appwrite server a subdomain of the SSR server? Isn't it to make sure that browsers send the cookies to appwrite's servers when calling the appwrite APIs from the client? When the login request is proxied, we're essentially only rewriting the set-cookie header so that the browser sends it to both the SSR server, and the appwrite server when used directly on the client (provided the appwrite server is on a subdomain).
If we're not using appwrite directly on the client, is there still a need to make the appwrite server on a subdomain of the SSR host?
Also, since the web client sdk send X-Fallback-Cookies read from localStorage, could a potential solution to this be to manually add the X-Fallback-Cookies storage item to localStorage after redirecting back to the client from the proxy API? This way, the web sdk when used on the client will read it and use it when making requests.
Will that work?
This would mean that on localhost, the session will be stored in storage, and in production, it'll use the cookies... Something like that
Based on the following line: https://github.com/appwrite/sdk-for-web/blob/7b37a2bec1dbe47b55e2c962996046f56b763192/src/client.ts#L426
It looks like the web client writes to the cookieFallback localStorage item whenever it's used to make a request, and the request returns a valid X-Fallback-Cookie header. If you look some live above that (374), it reads the item, sets it to the X-Fallback-cookies header and sends it along with other headers when used to make a request. So, if we can write that item to Storage, using Appwrite on the Client will also work, hopefully. What do you think?
Also @Meldiron, I'll like to know why you had include the Auth cookies in an object and then use JSON.stringify on it before setting it on the client here:
https://github.com/Meldiron/appwrite-ssr-next-js/blob/32cbcd586be3d63423d8bfc7a3a7e958dad00eba/src/app/AppwriteService.ts#L29-L31
I managed to get it to work using proxy, although it's a bit clunky. I hadn't realized that hosting locally was an option, though now it seems obvious :D Hosting the backend locally is fine for me for development.
Can you share some details of what you implemented?
I've not yet implemented SSR using the technique in this repo, but I will be doing that, and that's why I'm following this. I'm just curious, @vincaslt what exactly was the error you ran into when trying to get it to work on localhost?
Local Appwrite Instance
So if you have a local instance of NextJS AND Appwrite, all you need to do is update:
https://github.com/Meldiron/appwrite-ssr-next-js/blob/32cbcd586be3d63423d8bfc7a3a7e958dad00eba/src/app/AppwriteService.ts#L3-L7
to:
export const SsrHostname: string = "localhost";
export const AppwriteHostname: string = "localhost";
export const AppwriteEndpoint =
"http://localhost/v1";
Appwrite Cloud
If you have a local instance of NextJS and are connecting to Appwrite Cloud, connecting will be trickier because of browsers will block cookies from an HTTP page going to an HTTPS server. To get around this, you'll need to put a HTTPS proxy in front of your app (as well as all the other hostname configurations:
- update your hosts file to add:
127.0.0.1 example.com
157.230.79.70 appwrite.example.com # assuming cloud.appwrite.io still points to 157.230.79.70
- update the following:
https://github.com/Meldiron/appwrite-ssr-next-js/blob/32cbcd586be3d63423d8bfc7a3a7e958dad00eba/src/app/AppwriteService.ts#L3-L7
to:
export const SsrHostname: string = 'example.com';
export const AppwriteHostname: string = "appwrite.example.com";
export const AppwriteEndpoint =
"https://appwrite.example.com/v1";
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0";
- start up nextjs (
npm run dev) - start an HTTPS proxy (
npx local-ssl-proxy --source 3001 --target 3000assuming NextJS is running on port 3000) - open a browser
- browse to https://appwrite.example.com and proceed to the page to accept the self-signed certificate warning
- browse to https://example.com:3001 (assuming you set the HTTPS source port to 3001) and proceed to the page to accept the self-signed certificate warning
Thanks for this. I actually tried some things too very similar to what you shared. I first updated my hosts file and set appwrite to subdomain appwrite.myapp.local pointing to an an appwrite cloud IP, but then I figured out that they have load balancing in place and that won't always work.
I then decided to settle for a local DNS server that would allow me set up cname records so I won't be affected by appwrite cloud's load balancing. I settled for technitium DNS server which does a really good job.
The last thing that was left to figure out though was the SSL thing. I got hit by 500 internal server error whenever I tried to access appwrite cloud from the domain I had configured. It turns out that I had to have SSL enabled, but I was running out of time, so I didn't bother anymore, and decided to switch to client side rendering.
Anyways, thanks for sharing.