'Deploying React app to production returns "You need to enable JavaScript to run this app"
Problem
I have an axios call at "/artists", that gets a list of artists returned as an array of JSON. It works in development. However, in production it outputs an HTML element that says You need to enable Javascript because the data returned from "/artists" is undefined (proof of it below):
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="./favicon.ico" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="./logo192.png" />
<link rel="manifest" href="./manifest.json" />
<title>React App</title>
<link href="./static/css/main.5eece21d.chunk.css" rel="stylesheet" />
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script>
!(function (e) {
function t(t) {
for (var n, f, i = t[0], l = t[1], p = t[2], c = 0, s = []; c < i.length; c++) (f = i[c]), Object.prototype.hasOwnProperty.call(o, f) && o[f] && s.push(o[f][0]), (o[f] = 0);
for (n in l) Object.prototype.hasOwnProperty.call(l, n) && (e[n] = l[n]);
for (a && a(t); s.length; ) s.shift()();
return u.push.apply(u, p || []), r();
}
function r() {
for (var e, t = 0; t < u.length; t++) {
for (var r = u[t], n = !0, i = 1; i < r.length; i++) {
var l = r[i];
0 !== o[l] && (n = !1);
}
n && (u.splice(t--, 1), (e = f((f.s = r[0]))));
}
return e;
}
var n = {},
o = { 1: 0 },
u = [];
function f(t) {
if (n[t]) return n[t].exports;
var r = (n[t] = { i: t, l: !1, exports: {} });
return e[t].call(r.exports, r, r.exports, f), (r.l = !0), r.exports;
}
(f.m = e),
(f.c = n),
(f.d = function (e, t, r) {
f.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: r });
}),
(f.r = function (e) {
"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(e, "__esModule", { value: !0 });
}),
(f.t = function (e, t) {
if ((1 & t && (e = f(e)), 8 & t)) return e;
if (4 & t && "object" == typeof e && e && e.__esModule) return e;
var r = Object.create(null);
if ((f.r(r), Object.defineProperty(r, "default", { enumerable: !0, value: e }), 2 & t && "string" != typeof e))
for (var n in e)
f.d(
r,
n,
function (t) {
return e[t];
}.bind(null, n)
);
return r;
}),
(f.n = function (e) {
var t =
e && e.__esModule
? function () {
return e.default;
}
: function () {
return e;
};
return f.d(t, "a", t), t;
}),
(f.o = function (e, t) {
return Object.prototype.hasOwnProperty.call(e, t);
}),
(f.p = "./");
var i = (this.webpackJsonpspotify = this.webpackJsonpspotify || []),
l = i.push.bind(i);
(i.push = t), (i = i.slice());
for (var p = 0; p < i.length; p++) t(i[p]);
var a = l;
r();
})([]);
</script>
<script src="./static/js/2.2cc1353a.chunk.js"></script>
<script src="./static/js/main.0515e6b9.chunk.js"></script>
</body>
This error appears because in my action creator:
export const fetchArtists = () => async (dispatch: Dispatch) => {
const response = await axios.get<Artist[]>("/artists");
console.log(response);
dispatch<FetchArtistsAction>({
type: ActionTypes.FETCH_ARTISTS,
payload: response.data,
});
};
console.log(response) output in production mode :
console.log(response) output in development mode:
My site
https://spotify-eight.vercel.app/
The page would load, then it will give you a blank page because of the /artists route call. It will you the production output above, causing the error.
Backend code
My src/backend/artistRoutes.ts
router.get("/", async (req: RequestWithBody, res: Response) => {
const artists = await Artists.find({});
res.send(artists);
});
My src/backend/index.ts, which generates the src/backend/build when compiled:
.....
.....
mongoose.connect(process.env.mongoURI, { useNewUrlParser: true });
//Models
require("./models/Artists");
//Routes
app.use("/artists", artistsRoutes);
const PORT = process.env.PORT || 5000;
//Production
const path = require("path");
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "../../../build")));
app.get("*", function (req, res) {
res.sendFile(path.join(__dirname, "../../../build"));
});
}
app.listen(PORT);
Overview of my project's folder structure:
I have set up my production environment variables in Vercel, my hosting site:
Other solutions I've tried from other posts with no avail:
I am getting error in console "You need to enable JavaScript to run this app." reactjs
Why won't React production build run on the browser?
- In package.json adding a
"homepage": ".",
- In manifest.json, Changing start URL
"start_url": ".",
to"start_url": "/",
- Adding a proxy server. I already have it enabled ever since I started deployment.
"proxy": "http://localhost:5000"
Solution 1:[1]
I assume you serve react static files using nginx or apache.
If so, try look in /etc/nginx/sites-enabled/the-config-file
, for react it usually has this line:
try_files $uri /index.html;
What it does is, if someone access https://spotify-eight.vercel.app/artists, try serve https://spotify-eight.vercel.app/artists/index.html, if not found serve rootPath/index.html. I think thats what is happening.
I suggest serve the api endpoint in another port other than :80 so static files and endpoints can be differentiate easily. Dont change the nginx config try_files directive because your react app wont serve paths correctly otherwise.
Solution 2:[2]
Have you tried:
app.get("*", function (req, res, next) {
if (req.url.startsWith("/artists")) return next();
res.sendFile(path.join(__dirname, "../../../build"));
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Nikko Khresna |
Solution 2 | Logan Sotelo |