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.js
which would then expose the backend url viawindow.config.backendUrl
or similar and load that file in myindex.html
from a<script>
tag - Slightly similar to 1.: Put the config in a
config.json
and 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
express
or 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
/api
then at./api
then atapi.current-host.com
etc." - 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.