So, Today I learned how to setup a proxy server on vite. I was tired of seeing this kind of lines over an over:
axios.get('localhost:5001/api/products/1234')
so, first approach was to create a
.env.local
and set there a env variable like this:
VITE_API_BASE_URL="localhost:5001"
this way my initial code would look like:
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL
axios.get(`${API_BASE_URL}/api/products/1234`)
Enter fullscreen mode
Exit fullscreen mode
let's say you would like to change that target prop based on the environment you are running the application.
You can do it by checking the command or the mode, but I recommend load the .env file and using the VITE_API_BASE_URL we already defined.
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
return {
plugins: ...,
server: {
proxy: {
'/api': {
target: env.VITE_API_BASE_URL,
changeOrigin: true,
secure: false,
Enter fullscreen mode
Exit fullscreen mode
Even if the request are succeding (by checking the network inspector) there is an error logged by vite on the terminal.
http proxy error ECONNRESET at TLSWrap.onStreamRead
for every single request which gets proxied.
So the answer posted here does the trick.
You will need first to add https as a dev dependency by doing: npm i -D https
and then importing on the top of vite.config.js:
import http from "https";
Enter fullscreen mode
Exit fullscreen mode
Good. It provides per-environment configuration, so you can configure your URL's there and even stop needing the proxy. You can make it so the development environment creates absolute URL's, but production environment creates relative URLs.
config.json
"api" : {
rootPath: "/api" ,
"resourceA" : {
"rootPath" : "/resourceA" ,
"getAll" : ""
"get" : "/{id}"
Enter fullscreen mode
Exit fullscreen mode
import wjConfig , { Environment } from ' wj-config ' ;
import mainConfig from ' ./config.json ' ;
// Define your environment names.
const env = new Environment ( window . env . APP_ENV , [
' development ' ,
' test ' ,
' preprod ' ,
' production '
const config = await wjConfig ()
. addObject ( mainConfig )
. name ( ' Main ' )
. includeEnvironment ( env )
. addPerEnvironment (( b , e ) => b . addFetchedConfig ( `./config. ${ e } .json` , false ))
. createUrlFunctions ( ' api ' )
. build ();
export default config ;
Enter fullscreen mode
Exit fullscreen mode
const getAllUrl = config . api . resourceA . getAll ();
console . log ( getAllUrl );
// development: http://localhost:3005/resourceA
// non-development (like production): /api/resourceA
const getResAByIdUrl = config . api . resourceA . get ({ id : 123 });
console . log ( getResAByIdUrl );
// development: http://localhost:3005/resourceA/123
// non-development: /api/resourceA/123
Enter fullscreen mode
Exit fullscreen mode
Built on Forem — the open source software that powers DEV and other inclusive communities.
Made with love and Ruby on Rails . DEV Community © 2016 - 2025.