React Routes not working on Server but work locally - reactjs

I can go to the site index www.mysite.com and from there use the app navigation to go to www.mysite.com/login but I can't go directly to www.mysite.com/login as it gives a 404 message.
However this is working in localhost, where I can go straight to https://localhost:3000/login and it will load up the app with the login page route.
How can I get this to work on my Nginx server as-well?

You need to redirect all requests to index.html.
Refer to this for server configuration or you could redirect using server side like node or whatever server side you are using.

Try this in your server.js file
app.use("/users", require("./routes/users")); app.use("/groups", require("./routes/groups")); app.use(express.static(__dirname + "/client/build")); app.get("/*", (req, res) => { res.sendFile(path.join(__dirname, "client", "build", "index.html")); });

Related

Page reload or pasting url gives 404 with MERN stack

I am building a simple website that uses MERN stack running on apache.
There is a proxy (& reverse proxy) settings on /api to route to ip:port/api
At some point in the last couple of months, any page refresh or pasting urls causes a 404. I cannot identify what causes this.
It is using client side routing (based and it was working. It is still working on localhost only breaks on the server.
Now when I put the old code that used to work on the server, it breaks the same way. This suggests that a change in the environment is causing/contributing.
One developer I was working added this piece of code to try to address it.
if (process.env.NODE_ENV === "production") {
// Set static folder
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
}
It doesn't seem to have any effect even if I remove the if condition. I did a little test.
I added an image with name 'register'
If I go to my website and click on register it works
If I visit domain/register, it is showing the image, so even with the code snippet above it is treating it as a request for static file and not letting it pass on and resolve to the index.html
About the server
Ubuntu with Apache with proxy on /api to node server
Uses a self signed certificate but it breaks on http or https.
This seems to be a common problem. If anyone has seen this before or can give pointers on where to debug this, I would appreciate it.
Trying this code worked for me. And refer this for the difference between path.resolve and path.join
if (process.env.NODE_ENV === 'production') {
const root = path.join(__dirname, 'client', 'build');
app.use(express.static(root));
app.get('*', (req, res) => {
res.sendFile('index.html', { root });
})
}

Problem serving index.html from Express server, but not when I run client separately

I have an app that is made using ReactJS and ExpressJS. The Express server is responsible for getting data, and ReactJS for displaying it. When I run them separately, meaning, I go into the root folder and start the server, and then go into client and start the React app, everything works fine, but when I try to serve the static index.html file I get an error.
Uncaught TypeError: Cannot read properties of undefined (reading 'regular')
This is how I'm serving the static file:
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client". "build", "index.html"));
});
If your file structure is:
|root
|client
|build
-server.js
then you need to specify the path as __dirname, "client", "build", "index.html" and use join instead of resolve.

live reload when running express with CRA

I have my create react app setup similar to this setup. https://www.newline.co/fullstack-react/articles/using-create-react-app-with-a-server/
All is working great so far.
when I'm running on localhost:3000 i'm seeing hot reloading as CRA dev server is taking care of that for me.
Now when I run my app using my express server localhost:8081 i'm loading my html file and assets from CRA build folder which obviously means I'm only going to get the built files.
What i'd like to do is when running in port localhost:8081 I can get a reload of development changed files and not just the static build files.
The reason for this is let's say I'm using an authentication setup where I need to check if user is logged in before I allow the * route to proceed otherwise redirect to another route in express. I want to be able to check for this when working in development.
If I run the dev server localhost:3000 then I no longer get the route change loading my html files from express. Only the api call would work from express.
Here is my setup in express:
const express = require("express");
const path = require("path");
const PORT = process.env.PORT || "8081";
const app = express();
const indexPath = path.join(__dirname, "../build/index.html");
app.use(express.static(path.resolve(__dirname, "../build"), { index: false }));
app.get("/test", (req, res) => {
res.json({ message: "welcome to backend" });
});
app.get("*", (req, res) => {
console.log("sending index.html");
res.sendFile(indexPath);
});
app.listen(PORT, () => console.log(`listing on port ${PORT}`));
This express route will only work when using in localhost:8081 which is getting the build files.
app.get("*", (req, res) => {
console.log("sending index.html");
res.sendFile(indexPath);
});
But this never runs when working in dev server localhost:3000 so I can not do any authentication on this route when working in development mode. This would mean to test this I would have to keep rebuilding the build folder which is crazy.
I'm running my client in one terminal and my server in another. I also restarted both multiple times. The proxy as I said works in my package file for the /test route when called using fetch .
This a similar unanswered question I found:
create-react-app + nodejs (express) server

Shopify App Proxy - How to include my asset files in the request response | React / JS / Heroku

I'm building a Shopify App with React & Express, deployed via Heroku, which I'm trying to embed into my storefront using an Application Proxy.
When I finally load the proxied URL on my store - I get a blank screen and a bunch of 404's in the console for my .css and .js chunk files. The request was sent, authenticated, and my API's response is (200) - it just won't render anything.
Finally, after much research, I realized that Shopify has changed the path to these CSS and JS files to be my-store.myshopify.com/hash.chunk.js etc. instead of the reference to my Heroku server.
It appears this problem has been encountered before in this thread: Shopify app - how to include assets using an app-proxy with ruby on rails However, I can't seem to find a node/react/heroku equivalent to the Ruby solution presented here.
Any guidance or help would be greatly appreciated!
I begin by serving my React App through express with:
app.use(express.static(path.join(__dirname, 'client/build')));
and then when my proxy URL is hit I send back the index file within the client/build folder:
router.get('/proxy', (req, res) => {
res.set('Content-Type', 'application/liquid').sendFile(path.join(__dirname, '../client/build/index.html'));
});
I've managed to find a working solution to my problem after much trial and error.
The homepage in package.json is important. I had it set to just my Heroku address when it should actually be set to herokuaddress.com/YOURPROXYROUTE (i.e. /app/my-app)
Some additional middleware is required as well - for those interested I have the following routes set up to field requests from Shopify's app proxy.
This is set up above any of my route imports in server.js:
app.use(express.static(path.join(__dirname, 'client/build')));
and these routes are imported below that from a /shopify-routes.js file:
router.get('/proxy', (req, res) => {
res.set('Content-Type', 'application/liquid').sendFile(path.join(__dirname, '../client/build/index.html'));
});
router.get('/proxy/static/css/:file', (req, res) => {
res.set('Content-Type', 'text/css').sendFile(path.join(__dirname, `../client/build/static/css/${req.params.file}`));
});
router.get('/proxy/static/js/:file', (req, res) => {
res.set('Content-Type', 'text/javascript').sendFile(path.join(__dirname, `../client/build/static/js/${req.params.file}`));
});
Though this may be a bit heavy-handed, it has solved the problem and the app is loading within the Shopify storefront now.

Issue after remove (#) hashbangs from routing in angular-ui-router

I have remove (#) hashbangs by $locationProvider.html5Mode(true) in ui-route.
and set <base href="/public/">
when I have tried to localhost:59940/public/#/home url # is remove and url look localhost:59940/public/home and getting home view.
but when I have tried localhost:59940/public/home url. I have getting 404 Not Found error.
help me for getting home view when try to access localhost:59940/public/home in browser.
The problem is that the browser resolves urls before your angular app responds, and indeed the resource for that route is not there. The solution I have used is to make your 404 route return the index.html page and use ui-router to handle real 404 cases. But another idea is to match all of the client routes to routes on your server which return the index.html.
To enable $locationProvider.html5Mode in angular, you also need to some side server changes.
Other then your static assets and apis path, all other routes should server index.html(your main SPA page) only.
See below code.
This is how you can do it in node.js using express server.
var app = require('express')();
app.configure(function() {
// Static files - all js, css, images, etc go into the static path
app.use('/static', express.static('/static'));
// If a static file is invalid so we send 404
app.use('/static', function(req, res, next) {
res.send(404);
});
// This route deals enables HTML5Mode by forwarding missing files to the index.html
app.all('/*', function(req, res) {
res.sendfile('index.html');
});
});
app.listen(3000);

Resources