Search code examples
javascriptreactjsnode.jsexpressmern

Cannot GET / on page refresh with express


I'm running a little MERN stack project. I was able to deploy it on Vercel and get it to run. I can use the buttons in the browser to get to "/classes" and "/students", however when I reload on either of those pages, it says it cannot GET "/classes" or "/student"

This is the server backend

const express = require('express');
const mongoose = require('mongoose');
require('dotenv').config();

const app = express();
const classRoutes = require('./routes/classRoutes')

const PORT = process.env.PORT || 4000;

app.use(express.static(__dirname + "/dist"))

app.get('/', (req, res) => {
    res.send("Hello");
})

mongoose.connection.on('connected', () => {
    console.log('Connected to MongoDB Atlas');
});

app.use('/api', classRoutes)

const atlasConnectionUri = process.env.MONGODB_URL;
mongoose.connect(atlasConnectionUri, {
    dbName: 'subjects'
});

app.listen(PORT, () => {
    console.log(`Server is Running at ${PORT}`);
});

This is the App.jsx on frontend

import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import CoursePage from "./pages/CoursePage";
import Home from "./pages/Home";
import "./App.css";
import StudentPage from "./pages/StudentPage";

function App() {

  return (
    <BrowserRouter>

      <h1>MERN Stack Classes App</h1>

      <Routes>
        <Route
          path="/"
          element={<Home />}
        />
        <Route
          path="/classes"
          element={<CoursePage />}
        />
        <Route
          path="/students"
          element={<StudentPage />}
        />
      </Routes>

    </BrowserRouter>
  );
}

export default App

This is my folder structure for reference
enter image description here

I searched and from what I read, I'm not serving up my HTML as default for redirect. So I tried adding a redirect to HTML file using

app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});

But when i reload the domain, it says INTERNAL SERVER ERROR.


Solution

  • To start a FullStack MERN app you need to serve frontend built at the fallback route. i.e.

    app.get('*', (req, res) => {
        res.sendFile(path.join(__dirname, 'dist', 'index.html'));
    });
    

    But for this, you need to build the frontend first. npm run build will create a dist folder inside your frontend folder. Now you can serve these files.

    Assuming the fallback route is defined in index.js file. The relative path for the dist will be ../frontend/dist hence the fallback route should be.

    app.get('*', (req, res) => {
        res.sendFile(path.join(__dirname, '../frontend/dist', 'index.html'));
    });
    

    Now all the routes not defined in express will be redirected to the frontend.