I have a vue.js SPA which I want to deploy on different servers without recompiling the frontend for each deploy. The SPA connects to a backend, with a url yet unknown to the spa. Is there a way I can dynamically tell the frontend at runtime where the backend is?
Many articles and forum threads suggest to just use different config files for different environments and build them in at build time, but that is not an option for me because I simply don't know where the frontend/backend will be deployed when building it.
EDIT: The project is an open source project, so I can't really make an assumption about how people will deploy it. I've always kind of "assumed" it would be deployed on a seperate sub domain, with the frontend being reachable at / and the backend with a proxy at /api because that's how I set up my server.
However, I've seen people deploying the api at a totally different sub domain (sometimes even with different ports) than the frontend or on a sub path or even a mixture between the two.
Things I've considered so far:
- Putting the config in a
conf.jswhich would then expose the backend url viawindow.config.backendUrlor similar and load that file in myindex.htmlfrom a<script>tag - Slightly similar to 1.: Put the config in a
config.jsonand making a fetch request to it once the application loaded, then exposing the result of it inwindow.config.backendUrl - Inserting a
<script>window.config.backendUrl = 'http://api.example.com'</script>in myindex.html. - Serving the frontend with a custom made web server (based on
expressor similar) which parses either env or a different config file and then creates the<script>tag from 3. dynamically - Always "assuming" where the backend will be with some kind of list to work up, like "First look at
/apithen at./apithen atapi.current-host.cometc." - Bundling the frontend with the backend - that way I would always "know" where the backend relative to the frontend is.
Yet all of theses options seem to me a bit hacky, I think there has to be a better way.
My favourite is the third option because it is the best trade off between configurability and performance IMHO.