Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

108
Vistas
React rendering JSON instead of component on page reload

I've deployed my MERN app on Heroku and everything was fine until I realized an issue every time I refresh the page or try to access a route from the address bar. While navigation through React Router links is fine, trying to go directly to a route from URL address bar or refreshing the page is causing the app to break and sending server responses directly to the browser instead of rendering the component - to clarify: if a given route was supposed to make a GET request and display some data, the actual JSON is displayed on-screen.

As far as I've checked, this is happening only on components that make a GET request.

server.js

// INITIATE APP
const app = express();

// MIDDLEWARE
app.use(express.json());
app.use(cookieParser());
app.use(cors());
app.use(passport.initialize());

const isProduction = process.env.NODE_ENV === "production";

// Priority serve any static files
isProduction &&
  app.use(express.static(path.resolve(__dirname, "../client/build")));

// CONNECT TO DATABASE
// db config
const dbConnection = isProduction
  ? process.env.MONGO_URI_PROD
  : process.env.MONGO_URI_DEV;

mongoose.connect(dbConnection, () => {
  console.log("Successfully connected to database");
});

// ROUTES
const authRouter = require("./routes/auth");
const detailsRouter = require("./routes/details");
const diaryRouter = require("./routes/diary");
const resultsRouter = require("./routes/results");
const settingsRouter = require("./routes/settings");

app.use("/auth", authRouter);
app.use("/details", detailsRouter);
app.use("/diary", diaryRouter);
app.use("/results", resultsRouter);
app.use("/settings", settingsRouter);

// All remaining requests return the React app, so it can handle routing
isProduction &&
  app.get("*", function (request, response) {
    response.sendFile(path.resolve(__dirname, "../client/build", "index.html"));
  });

// DEFINE PORTS
const port = process.env.PORT || 5000;

// START SERVER
app.listen(port, () => {
  console.log(`Server started on port ${port}`);
});

By the end of the code above, right before Define ports, there is this statement that I included to fix a similar issue happening on other routes too. I thought this was going to prevent this error in any situation, but it seems that this isn't the case. You can try the app here (you can delete the account on /settings after testing).

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

I'd like to thank S. Elliott Johnson for the solution I'll post below to anyone running into the same issue in the future:

This sounds like intended behavior. Your server routes and your React Router routes SHOULD NOT conflict.

React Router isn't actually "routing" anywhere from a HTTP sense -- it's just rendering different JavaScript/HTML and storing its "location" in the URL.

When running a React app, the React app is typically only served from the root of your website (or some other "root", like mydomain.com/app). When you make a HTTP GET request to that route, the backend server sends all of the JavaScript, HTML, and CSS necessary to bootstrap your React app. Clicking around using React Router simply causes your React code to run on the client.

When you actually reload the page, your browser, as you know, makes a GET request back to the server for that route, so you just get whatever your server sends. Let's use a few examples where you have a React app that's served from my domain.com.

Example 1:

  • User makes a browser GET request to mydomain.com. They receive the React app back

  • User navigates to /auth/login - no HTTP requests, React simply running code

  • User navigates to /me to view their account -- again, same

  • User reloads the page using the browser - a HTTP GET request is sent to the backend, and they'll receive whatever the backend sends back -- whether that's JSON or something else

You really have two options here:

  1. Redirect all HTTP requests to root, meaning /, /something and /anything will serve /. Then host your API on another subdomain, like api.mydomain.com

  2. Choose a route to serve your API from, like mydomain.com/api. Forward all requests from any route EXCEPT /api and it's subroutes to the root.

What I ended up doing was option 2:

Renamed my API routes prepending /api to all of them on server.js. Then I renamed all API calls on React accordingly. That code excerpt

isProduction &&
  app.get("*", function (request, response) {
    response.sendFile(path.resolve(__dirname, "../client/build", "index.html"));
  });

on server.js took care of the GET requests executed on page refresh, making sure that Node always serves index.html to supply those requests.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda