0

I’m facing an issue with my React frontend (built with rsbuild) and my Node.js REST API.

Setup

  1. Frontend: React (rsbuild)
  2. Backend: Node.js REST API (pm2)
  3. Server: Windows Server
  4. Proxy: Nginx (serves frontend and proxies API requests)

Local development

  1. Running npm run dev → everything works fine.
  2. API calls resolve correctly.

Production test on my PC

  1. Ran npm run build for frontend, served with nginx proxy (/api), backend running with pm2 → also worked fine.
  2. Other PCs on the same network could access it.

Production on the actual server

  1. Cloned both frontend and backend from git (instead of copying from dev).
  2. Ran npm run build for frontend, pm2 for backend.
  3. Backend is running fine at http://ip:8081/api/....
  4. Frontend is being served fine.

Problem: The frontend is not fetching my backend. Instead of hitting /api/..., the request URL looks like:

http://ip:8081/sales/undefined/api/reportqueries
http://ip:8081/undefined/api/query1

Notice the extra /sales and undefined.

I can only think that my .env.production is not working.

Here are some parts of the code (comment if you need more code for help)

rsbuild.config.ts

import { defineConfig } from "@rsbuild/core";
import { pluginReact } from "@rsbuild/plugin-react";

export default defineConfig({
    plugins: [pluginReact()],
    html: {
        title: "name",
        favicon: "public/favicon0.ico",
    },
    source: {
        define: {
            RSBUILD_API_BASE: JSON.stringify(process.env.RSBUILD_API_BASE),
        },
    },
});

.env.production

RSBUILD_API_BASE=/api also tested RSBUILD_API_BASE=

usage in code

const res = await fetch(`${RSBUILD_API_BASE}/api/reportqueries`);

Some are like

const res = await fetch(`${RSBUILD_API_BASE}/api/query/${queryCode}`, {
                signal: controller.signal
            });
    // queryCode is the endpoint like query1, query2 query3
// src/hooks/useApi.ts
import { useEffect, useState } from 'react';
import axios from 'axios';

export function useApiQuery<T = any>(url: string) {
    const [data, setData] = useState<T | null>(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<any>(null);

    useEffect(() => {
        axios.get(RSBUILD_API_BASE + url)
            .then((res) => setData(res.data))
            .catch(setError)
            .finally(() => setLoading(false));
    }, [url]);

    return { data, loading, error };
}
const { data: dataCard1, loading: loading1 } =
        useApiQuery<QC001Response[]>("/api/query/QC001");
    const dataCard3 = useApiQuery<QC003Response[]>("/api/query/QC006");

nginx.conf (simplified)

server {
    listen 8081;
    server_name localhost;

    root   C:/path/to/frontend/dist;

    location / {
        index index.html;
        try_files $uri /index.html;
    }

    location /api {
        proxy_pass http://127.0.0.1:4000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
    }
}

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.