Issue
I ran into a cookie/auth issue when deploying my app.
- Local setup
- NestJS backend (HTTP)
- Next.js frontend (HTTP)
- Login worked correctly
- Deployed setup
- Backend deployed to Render (HTTPS)
- Frontend deployed to Netlify (HTTPS, Netlify subdomain)
- Login stopped working
Root cause
After debugging, I realized this was a cookie + SameSite issue, not a NestJS or CORS bug.
- *.netlify.app and *.onrender.com are different sites
- Because they are cross-site, cookies with SameSite=Lax are not sent on fetch / XHR requests
- As a result, the auth cookie was never included after login
This worked locally because:
- Both frontend and backend were running on localhost
- SameSite rules treated them as same-site
Important findings
- SameSite ≠ Same Origin “SameSite” is based on the registrable domain (eTLD+1), not the full origin. Examples:
a.letitcode.dev↔b.letitcode.dev→
same-sitea.onrender.com↔b.onrender.com→
same-sitea.netlify.app↔b.onrender.com→
cross-sitea.co.uk↔b.co.uk→
cross-site (co.ukis a public suffix)
- HTTP frontend cannot use cookies from an HTTPS backend Even if they are same-site:
- Secure cookies are never sent from HTTP pages
- If the backend is HTTPS, the frontend must also be HTTPS
- Cross-site cookies require strict settings To allow cookies across different sites:
- SameSite must be ‘none’
- Secure must be true (mandatory)
- Frontend and backend must both be HTTPS
Solution
I updated the backend cookie config to explicitly support cross-site usage:
import { CookieOptions } from 'express';
const cookieOptions: CookieOptions = {
httpOnly: true,
secure: true, // Required when SameSite=None
sameSite: 'none', // Required for cross-site (Netlify ↔ Render)
expires: new Date(Date.now() + 24 * 60 * 60 * 1000),
};
After this change (and with correct CORS + credentials: ‘include’ on the frontend), login worked as expected.
Summary
- Localhost hides many cookie issues
- Render + Netlify is a cross-site setup
- SameSite=Lax is not enough for cross-site fetch
- SameSite=None always requires Secure=true
- HTTPS frontend is mandatory when using Secure cookies
Hopefully this helps anyone hitting the same “works locally, breaks in prod” problem.