diff --git a/server/src/responders/handlers.js b/server/src/responders/handlers.js
--- a/server/src/responders/handlers.js
+++ b/server/src/responders/handlers.js
@@ -13,6 +13,7 @@
   createNewAnonymousCookie,
 } from '../session/cookies';
 import type { Viewer } from '../session/viewer';
+import { type AppURLFacts, getAppURLFactsFromRequestURL } from '../utils/urls';
 import { getMessageForException } from './utils';
 
 export type JSONResponder = (viewer: Viewer, input: any) => Promise<*>;
@@ -41,10 +42,22 @@
         return;
       }
       const result = { ...responderResult };
-      addCookieToJSONResponse(viewer, res, result, expectCookieInvalidation);
+      addCookieToJSONResponse(
+        viewer,
+        res,
+        result,
+        expectCookieInvalidation,
+        getAppURLFactsFromRequestURL(req.url),
+      );
       res.json({ success: true, ...result });
     } catch (e) {
-      await handleException(e, res, viewer, expectCookieInvalidation);
+      await handleException(
+        e,
+        res,
+        getAppURLFactsFromRequestURL(req.url),
+        viewer,
+        expectCookieInvalidation,
+      );
     }
   };
 }
@@ -58,7 +71,12 @@
       viewer = await fetchViewerForJSONRequest(req);
       await responder(viewer, req, res);
     } catch (e) {
-      await handleException(e, res, viewer);
+      await handleException(
+        e,
+        res,
+        getAppURLFactsFromRequestURL(req.url),
+        viewer,
+      );
     }
   };
 }
@@ -73,7 +91,7 @@
     } catch (e) {
       // Passing viewer in only makes sense if we want to handle failures as
       // JSON. We don't, and presume all download handlers avoid ServerError.
-      await handleException(e, res);
+      await handleException(e, res, getAppURLFactsFromRequestURL(req.url));
     }
   };
 }
@@ -81,6 +99,7 @@
 async function handleException(
   error: Error,
   res: $Response,
+  appURLFacts: AppURLFacts,
   viewer?: ?Viewer,
   expectCookieInvalidation?: boolean,
 ) {
@@ -110,7 +129,13 @@
       viewer.cookieInvalidated = true;
     }
     // This can mutate the result object
-    addCookieToJSONResponse(viewer, res, result, !!expectCookieInvalidation);
+    addCookieToJSONResponse(
+      viewer,
+      res,
+      result,
+      !!expectCookieInvalidation,
+      appURLFacts,
+    );
   }
   res.json(result);
 }
@@ -121,7 +146,11 @@
   return async (req: $Request, res: $Response) => {
     try {
       const viewer = await fetchViewerForHomeRequest(req);
-      addCookieToHomeResponse(viewer, res);
+      addCookieToHomeResponse(
+        viewer,
+        res,
+        getAppURLFactsFromRequestURL(req.url),
+      );
       res.type('html');
       await responder(viewer, req, res);
     } catch (e) {
@@ -165,10 +194,21 @@
         return;
       }
       const result = { ...responderResult };
-      addCookieToJSONResponse(viewer, res, result, false);
+      addCookieToJSONResponse(
+        viewer,
+        res,
+        result,
+        false,
+        getAppURLFactsFromRequestURL(req.url),
+      );
       res.json({ success: true, ...result });
     } catch (e) {
-      await handleException(e, res, viewer);
+      await handleException(
+        e,
+        res,
+        getAppURLFactsFromRequestURL(req.url),
+        viewer,
+      );
     }
   };
 }
diff --git a/server/src/responders/website-responders.js b/server/src/responders/website-responders.js
--- a/server/src/responders/website-responders.js
+++ b/server/src/responders/website-responders.js
@@ -41,14 +41,10 @@
 import { setNewSession } from '../session/cookies';
 import { Viewer } from '../session/viewer';
 import { streamJSON, waitForStream } from '../utils/json-stream';
-import { getSquadCalURLFacts } from '../utils/urls';
+import { getAppURLFactsFromRequestURL } from '../utils/urls';
 
-const { basePath, baseDomain } = getSquadCalURLFacts();
 const { renderToNodeStream } = ReactDOMServer;
 
-const baseURL = basePath.replace(/\/$/, '');
-const baseHref = baseDomain + baseURL;
-
 const access = promisify(fs.access);
 const googleFontsURL =
   'https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=Inter:wght@400;500;600&display=swap';
@@ -116,6 +112,10 @@
   req: $Request,
   res: $Response,
 ): Promise<void> {
+  const { basePath, baseDomain } = getAppURLFactsFromRequestURL(req.url);
+  const baseURL = basePath.replace(/\/$/, '');
+  const baseHref = baseDomain + baseURL;
+
   const appPromise = getWebpackCompiledRootComponentForSSR();
 
   let initialNavInfo;
diff --git a/server/src/session/cookies.js b/server/src/session/cookies.js
--- a/server/src/session/cookies.js
+++ b/server/src/session/cookies.js
@@ -32,12 +32,10 @@
 import { clearDeviceToken } from '../updaters/device-token-updaters';
 import { updateThreadMembers } from '../updaters/thread-updaters';
 import { assertSecureRequest } from '../utils/security-utils';
-import { getSquadCalURLFacts } from '../utils/urls';
+import { type AppURLFacts } from '../utils/urls';
 import { Viewer } from './viewer';
 import type { AnonymousViewerData, UserViewerData } from './viewer';
 
-const { baseDomain, basePath, https } = getSquadCalURLFacts();
-
 function cookieIsExpired(lastUsed: number) {
   return lastUsed + cookieLifetime <= Date.now();
 }
@@ -534,11 +532,11 @@
   return viewer;
 }
 
-const domainAsURL = new url.URL(baseDomain);
 function addSessionChangeInfoToResult(
   viewer: Viewer,
   res: $Response,
   result: Object,
+  appURLFacts: AppURLFacts,
 ) {
   let threadInfos = {},
     userInfos = {};
@@ -566,7 +564,7 @@
   if (viewer.cookieSource === cookieSources.BODY) {
     sessionChange.cookie = viewer.cookiePairString;
   } else {
-    addActualHTTPCookie(viewer, res);
+    addActualHTTPCookie(viewer, res, appURLFacts);
   }
   if (viewer.sessionIdentifierType === sessionIdentifierTypes.BODY_SESSION_ID) {
     sessionChange.sessionID = viewer.sessionID ? viewer.sessionID : null;
@@ -721,6 +719,7 @@
   res: $Response,
   result: Object,
   expectCookieInvalidation: boolean,
+  appURLFacts: AppURLFacts,
 ) {
   if (expectCookieInvalidation) {
     viewer.cookieInvalidated = false;
@@ -729,31 +728,48 @@
     handleAsyncPromise(extendCookieLifespan(viewer.cookieID));
   }
   if (viewer.sessionChanged) {
-    addSessionChangeInfoToResult(viewer, res, result);
+    addSessionChangeInfoToResult(viewer, res, result, appURLFacts);
   } else if (viewer.cookieSource !== cookieSources.BODY) {
-    addActualHTTPCookie(viewer, res);
+    addActualHTTPCookie(viewer, res, appURLFacts);
   }
 }
 
-function addCookieToHomeResponse(viewer: Viewer, res: $Response) {
+function addCookieToHomeResponse(
+  viewer: Viewer,
+  res: $Response,
+  appURLFacts: AppURLFacts,
+) {
   if (!viewer.getData().cookieInsertedThisRequest) {
     handleAsyncPromise(extendCookieLifespan(viewer.cookieID));
   }
-  addActualHTTPCookie(viewer, res);
+  addActualHTTPCookie(viewer, res, appURLFacts);
 }
 
-const cookieOptions = {
-  domain: domainAsURL.hostname,
-  path: basePath,
-  httpOnly: true,
-  secure: https,
-  maxAge: cookieLifetime,
-  sameSite: 'Strict',
-};
-function addActualHTTPCookie(viewer: Viewer, res: $Response) {
-  res.cookie(viewer.cookieName, viewer.cookieString, cookieOptions);
+function getCookieOptions(appURLFacts: AppURLFacts) {
+  const { baseDomain, basePath, https } = appURLFacts;
+  const domainAsURL = new url.URL(baseDomain);
+  return {
+    domain: domainAsURL.hostname,
+    path: basePath,
+    httpOnly: true,
+    secure: https,
+    maxAge: cookieLifetime,
+    sameSite: 'Strict',
+  };
+}
+
+function addActualHTTPCookie(
+  viewer: Viewer,
+  res: $Response,
+  appURLFacts: AppURLFacts,
+) {
+  res.cookie(
+    viewer.cookieName,
+    viewer.cookieString,
+    getCookieOptions(appURLFacts),
+  );
   if (viewer.cookieName !== viewer.initialCookieName) {
-    res.clearCookie(viewer.initialCookieName, cookieOptions);
+    res.clearCookie(viewer.initialCookieName, getCookieOptions(appURLFacts));
   }
 }
 
diff --git a/server/src/utils/security-utils.js b/server/src/utils/security-utils.js
--- a/server/src/utils/security-utils.js
+++ b/server/src/utils/security-utils.js
@@ -2,11 +2,10 @@
 
 import type { $Request } from 'express';
 
-import { getSquadCalURLFacts } from './urls';
-
-const { https } = getSquadCalURLFacts();
+import { getAppURLFactsFromRequestURL } from './urls';
 
 function assertSecureRequest(req: $Request) {
+  const { https } = getAppURLFactsFromRequestURL(req.url);
   if (https && req.get('X-Forwarded-SSL') !== 'on') {
     throw new Error('insecure request');
   }