Skip to content

[Bug] replace hardcoded API base URL with Vite env variable + proxy config #18

@OmanshiRaj

Description

@OmanshiRaj

Description

Type of Change

  • Bug fix
  • Enhancement / Developer Experience improvement

Problem

frontend/src/api/api.js hardcodes the backend URL:

const songApi = axios.create({
  baseURL: 'http://localhost:3000/songs',
});

This creates three real problems:

Problem 1 — CORS errors in development by default

The frontend runs on http://localhost:5173 (Vite default) and calls
http://localhost:3000. This is a cross-origin request. The backend's
app.use(cors()) with no options allows all origins in development, but in any
staging or production environment with a stricter CORS policy this breaks
silently. The underlying issue is that the frontend should not be making
cross-origin requests at all during development — Vite's dev proxy handles this.

Problem 2 — The URL is wrong in the README

README.md says the backend starts at http://localhost:5000, but server.js
hardcodes port 3000, and api.js uses 3000. Any contributor following the
README gets a broken setup. This mismatch exists because the URL is scattered
across files with no single source of truth.

Problem 3 — Impossible to deploy without editing source code

To deploy to any environment (staging, production), a developer must manually
edit api.js. There is no way to inject the backend URL at build time. This
is a violation of the 12-factor app principle
and a common source of accidental production commits with dev URLs.


Fix

1. Add a Vite proxy in vite.config.js

During development, Vite proxies /api/* requests to the backend. The frontend
never makes cross-origin requests — no CORS issues.

// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  plugins: [react(), tailwindcss()],
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },
});

2. Update api.js to use an env variable with /api fallback

// frontend/src/api/api.js
import axios from 'axios';

const songApi = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL ?? '/api/songs',
});

export default songApi;

In development: requests go to /api/songs → Vite proxy → http://localhost:3000/songs (no CORS)
In production: set VITE_API_BASE_URL=https://your-backend.com/songs in the build environment

3. Add frontend/.env.example

# Backend API base URL
# In development, leave this unset — Vite proxy handles it automatically
# In production, set this to your deployed backend URL:
# VITE_API_BASE_URL=https://api.yourapp.com/songs

4. Update frontend/.gitignore to exclude .env

# already present:
.env
.env.local
.env.*.local

Vite's default .gitignore already excludes these — just confirming it's in place.


Files Changed

File Change
frontend/vite.config.js Add server.proxy for /api → backend
frontend/src/api/api.js Use import.meta.env.VITE_API_BASE_URL with /api/songs fallback
frontend/.env.example New file — documents env variable for contributors
README.md Correct backend port from 50003000, document the env variable

How to Test

Development (proxy path)

  1. Start backend on port 3000
  2. Run npm run dev in frontend — no .env changes needed
  3. Open the app, click "Detect face" — confirm songs load with no CORS errors
    in the browser console
  4. In DevTools Network tab, confirm requests go to /api/songs not localhost:3000

Production env path

  1. Create frontend/.env with VITE_API_BASE_URL=http://localhost:3000/songs
  2. Run npm run build && npm run preview
  3. Confirm requests go to the URL specified in the env variable

Checklist

  • No hardcoded localhost URLs in source code
  • CORS errors eliminated in development via Vite proxy
  • Production deployable via environment variable
  • .env.example added for contributor onboarding
  • README port mismatch corrected
  • No new runtime dependencies (Vite proxy is zero-cost)

PLEASE ASSIGN THE ISSUE TO ME UNDER SSoC'26

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions