SSR vs CSR modes
If using the SSR proxy you need to be careful you don't rely on accessing properties which are only available at the client. Examples being things like window.location. If you do, when you run the site in SSR mode these will error as window doesn't exist.
Package managers - changing the core libraries
If you are using the proxy, chances are you'll be consuming @sitecore-jss/sitecore-jss-proxy. But, what if you need to edit the core behaviour of the package? Either you could store a copy of the code in your local solution and edit directly or apply a patch to it.
We extended how the proxy worked to play nicely with site resolution, so patched in the changes via the npm package: patch-package. You store a transform in source control which the package helps create and then gets applied during npm install. This was favourable to storing a copy of the Sitecore code as any changes they make wouldn't be reflected in our codebase.
Let's assume you are performing blue/green deployments and you host your site out of more than one region in the cloud. Chances are users could route through either region and/or colour.
For debugging purposes, we include http headers to provide all this information - sharing information from the Sitecore application and the JSS proxy.
Site resolution and language resolution
Most of the complexity we encountered here was related to the URL structure we needed to adhere to, so this item might not be applicable to everyone. In summary, the current version of JSS doesn't have the concept of site resolution hence you need to roll this yourself.
We built a basic implementation of the <sites> logic you get in Sitecore which provides the ability to hot-swap the behaviour of the proxy and append on the sc_site=... querystring to any layout service call. One thing to note here if using the proxy, you will want this logic available in SSR and CSR mode.
This was patched into the core implementation of the proxy with the patch-package library. We also disabled the use of the sc_lang querystring when calling the layout service as we relied on sites for language instead.
The final change was to update dynamically the url that JSS calls for the layoutService. This was done in config.js in proxyOptions. We added the router property to adjust the core url to call.
The JSS team provide an OTB transition graphic that's visible when making a routing change. It's trivial to change, but don't forget to unless you want the JSS gif flashing every time a user changes page.