79739575

Date: 2025-08-19 07:20:39
Score: 1
Natty:
Report link

Answer:

The problem is exactly what you identified: when you hit /login directly, the server looks for a file named /dist/login and returns 404 before React Router ever runs.

The fix is to make Express always serve index.html for any non-API route. That way, React Router in the browser takes over routing.

Here’s the typical setup:

import express from 'express'
import path from 'path'

const app = express()

// Serve static files from Vite build output
app.use(express.static(path.join(__dirname, 'dist')))

// API routes go here, *before* the catch-all
app.use('/api', require('./api'))

// Catch-all: send index.html for any other route
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist', 'index.html'))
})

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000')
})

Important things to check:

  1. Correct dist path If you’re using Vite, the build output defaults to dist/. In Express (running from build or dist folder), you might need:

    path.join(__dirname, '../dist')
    

    instead of just __dirname/dist. Use console.log(path.join(...)) to verify.

  2. Order matters

    • app.use(express.static(...)) → serves real files (CSS, JS, images).
    • app.get('*', ...) must come after your API routes, otherwise it will catch those too.
  3. Windows/IIS hosting If you’re behind IIS, make sure your reverse proxy points all unknown paths to Express and doesn’t intercept /login. Otherwise IIS itself might be returning the 404.


TL;DR

With that setup, https://site:port/login will load index.html, React Router will boot, and the login page will render just like locally.


✅ This is the same pattern used by CRA, Vite, Next.js custom servers, etc.


Do you want me to also show you how to configure the Vite build output (vite.config.ts) to make sure Express finds the files correctly in your dist folder?

Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • Ends in question mark (2):
  • Low reputation (0.5):
Posted by: Chetan Singhal