The docs (https://remix.run/docs/en/1.15.0/guides/envvars#browser-environment-variables) mention:
Instead we recommend keeping all of your environment variables on the server (all the server secrets as well as the stuff your JavaScript in the browser needs) and exposing them to your browser code through window.ENV. Since you always have a server, you don't need this information in your bundle, your server can provide the client-side environment variables in the loaders.
The issue is that, in SPA mode, there is not server and loaders cannot be used.
I understand that Vite supports replacing variables in Html at build time (https://vitejs.dev/guide/env-and-mode#html-env-replacement) but I suspect that the index.html file in SPA mode is generated after building the app (so Vite doesn't have a chance to replace the vars):
The index.html is generated from the HydrateFallback component in your root.tsx route. The initial "render" to generate the index.html will not include any routes deeper than root. This ensures that the index.html file can be served/hydrated for paths beyond / (i.e., /about) if you configure your CDN/server to do so.
What is the recommended way to implement this in SPA?
The use case is bundling the API server url the app should use.