Vue in Production: How to call (or proxy) APIs
If you plan to use Vue.js for site production and you happen to have a separate backend, then very likely you will bump into a problem: How to properly call my APIs?
In development stage, this wouldn’t be a problem. If you have been reading the Vue.js documentation carefully, you will find this nice trick here:
By using a devServer proxy, you don’t have to include any domain name, IP address or localhost. Just axios.get(“/api/blablabla”)
will do.
However, this devServer proxy only lives in vue.config.js
, which won’t be compiled into production static folder /dist
when you run npm build
.
So, what to do in production?
Here’s the problem that leads to me writing this article, the Vue.js documentation does not specify what to do when you need something like “productionServer proxy” and there aren’t many good solutions you can find by googling. I’ve been doing a lot of researching & digging, and now I have 2 acceptable solutions.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
First solution :
If you don’t mind mixing your Vue frontend & whatever backend together in production, just follow this video and feel free to close this article now.
Otherwise, if you are like me who want to deploy frontend & backend separately while still solving the proxy problem, you have found the right article.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
Second solution :
If you don’t have time to read my explanation, you can go straight to my repository to set-up and get it running. This is a configured production-ready template.
The trick here is to make good use of the production-grade web server, in this case, Nginx.
The good part about Nginx is that it doesn’t matter whether the request is coming from the browser or the code that it is serving. When a user request comes in, it handles it. When you do something like axios.get("/api/blablabla")
in your Vue code, it can also handle it!
nginx.conf:
......
http {
......
server {
location / {
root /YOUR_VUE_DIST_FOLDER
index index.html;
try_files $uri $uri/ /index.html;
}
location /api/* {
proxy_pass http://YOUR_API_ENDPOINT;
}
......
}
......
}
The first location
block is where your Vue production code /dist
resides. This is the default handler as denoted by the /
path. This is where the usual user request is handled.
The second location
block is where you specify your backend domain/IP. It would only be triggered when the request URL matches the /api/*
regex, and this request is coming from your own Vue.js code.
Note that in nginx.conf
, if multiple server
blocks or multiple location
blocks are present (as in this case), the most explicit path takes the highest priority and only one block will be matched. In this case, although http://example.server.com/api/someapi
matches both /
& /api/*
, only the second location
block will take effect since /api/*
is more explicit than /
.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
The complete template code is here
I’m using Docker as a production environment, but feel free to use any other environment if you are not familiar with Docker, just delete Dockerfile
& .dockerignore
these 2 files will do. So long as your own production environment has Nginx
installed, my solution will work.
If you find my solution helpful, please give me a star at my Github repository above! Thank you for reading!