React build for static server gives 404 error - node.js

I have a React app which runs fine locally but when I try to build it on the static Node server serve (npm serve) using
serve -s build
the server returns a 404 The requested path could not be found page. My understanding is the issue has to do with the fact I am using BrowserRouter in the application. I put a .htaccess file in the root directory with the following code but it did not solve the issue.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]
</IfModule>
One suggestion I saw for a Node environment follows but I don't understand where to put the code.
app.get('*', function (req, res) {
res.send('index_path')
})
My index.js file is as follows.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { Route, Switch, BrowserRouter as Router } from 'react-router-dom';
import App from './App';
import Service from './javascript/Service';
import { PageNotFound } from './PageNotFound';
import * as serviceWorker from './serviceWorker';
const routing = (
<Router>
<Switch>
<Route exact path="/" component={App} />
<Route path="/Service/:serviceName" component={Service} />
<Route component={PageNotFound} />
</Switch>
</Router>
);
ReactDOM.render(routing, document.getElementById('root'));
serviceWorker.unregister();

you should first build your project with
npm run build (or yarn)
next install serve
npm install -g serve
and then run this code
serve -s build

Related

How to configure Node.js in Web hosting?

I made a website with create-react-app with a contact form that communicates with the backend (nodejs with nodemailer). In localhost works perfectly.
When I uploaded the website in a web hosting (wnpower.com/web-hosting is the hosting I bought) that supports nodejs apps, I can't use the contact form because I get "net::ERR_CONNECTION_TIMED_OUT" in the path "https://mywebsite.com/api/sendmessage". It seems the frontend can't find the backend router or something that I can't understand.
In the CPanel of the web hosting, in the terminal I installed Nodejs and ran a test app, works perfectly. But when I want to use node app across the frontend, doesn't work.
My configuration in the node app.js file:
require("./config"); // all process.env
const express = require("express");
const path = require('path');
const app = express();
const bodyParser = require("body-parser");
// ALL ROUTES
const contact_routes = require('./routes');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.listen(process.env.PORT, () => {
console.log("Server listening at port "+process.env.PORT);
});
// Configure Header HTTP
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method"
);
res.header("Access-Control-Allow-Methods", "GET, POST");
res.header("Allow", "GET, POST");
next();
});
app.use(express.static(path.join(__dirname, '../public_html')));
// CONNECT ROUTES WITH API
app.use(process.env.API_URL, contact_routes);
module.exports = {
app
};
public_html directory are the static files that I built with the command npm run-script build and the __dirname is the server folder. So:
Directory:
public_html -> static files frontend.
server -> node app, routes, controllers, etc.
And in the config.js file there is the process.env.PORT and the port is 3050.
In the routes.js:
var express = require('express');
var controller = require('./controller');
var router = express.Router();
router.post('/sendmessage', controller.sendMessage);
module.exports = router;
in the .htaccess file:
DirectoryIndex ""
RewriteEngine On
RewriteCond %{REQUEST_URI} ^.*/index.*
RewriteRule ^(.*)$ http://127.0.0.1:3050/ [P,L]
RewriteRule ^$ http://127.0.0.1:3050/ [P,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ http://127.0.0.1:3050/$1 [P,L]
I can't understand well, I have no experience in that.
My idea is
Run the node app with nohup in the terminal of cpanel so the Node app will always running. Checked!
Try the contact form in the frontend website. Fail! I get timeout connection and I get nothing.
In the node app.js I want to see the console.log() in the terminal cpanel when I use the contact form. It's for test and know thats all is ok, but I can't see anything in the terminal. How can I do that?
If any information is missing, tell me I'll share the code. I need to resolve this as soon as possible. Thank you for reading and sorry for my English.
Try using
https://mywebsite.com:3050/
instead of http://127.0.0.1:3050/
at all places in your .htaaccess file
You can get logs of nohup from tail command in its log file.

Why does my React Website Take 43 seconds to Load?

I'm not sure why my react website is taking so long to load. It takes 43 seconds
All I have is in index.jsx
import ReactDOM from "react-dom";
import React from "react";
import { HashRouter, Route } from "react-router-dom";
import Home from "./components/Home";
ReactDOM.render(
<HashRouter>
<div>
<Route exact path="/" component={Home} />
</div>
</HashRouter>,
document.getElementById("main")
);
Home.jsx: imports react and renders hi
webpack.config.js : https://pastebin.com/raw/zdUws0R8
package.json : https://pastebin.com/raw/VR6pSP44
index.html : https://pastebin.com/raw/9AVNBpTN
I checked your website and it seems to be working fine to me for now;
For more details, I have added a:
Website Request screenshot
You might want to have a look at your SSL certificate though.
All the best!
I think you need to reinstall your project via :
npx create-react-app YourProject
and use
BrowserRouter
instead of
HashRouter
in 'react-router-dom'
then start the development server after creating the components or editing it via
npm start

Page not found "/" route

I'm trying to setup a VueJS app using Nuxt for server side rendering. However after deployment to my server the index.vue is return a 404 Page not found error.
This doesn't happen when run on my development machine, and still happens even if run in Development mode on my server.
All other routes work, and getting to the index route from within the app itself works fine. It just doesn't load when refreshed. Eg:
http://myapp.com/ Doesn't work
http://myapp.com/login Works fine
My pages folder currently looks like this:
- pages
-- index.vue
-- login.vue
I have nothing fancy set up within my nuxt.config file and have pretty much the same setup as is described in the Auth0 example
On my server I'm running nuxt with the command pm2 start npm --name "my-app" -- start Which runs fine without any errors, and I have the following .htaccess config:
RewriteCond %{HTTP_HOST} ^my-app\.com$ [OR]
RewriteRule ^(.*) "http\:\/\/127\.0\.0\.1\:3000\/$1" [P,L]
This is the error screen I get:
The page itself is very basic at the moment, it did have far more on it however I've cut it down to the following trying to debug this issue:
<template>
<v-container grid-list-md>
<v-layout row wrap>
<h1>Test index, trying to fix the 404</h1>
<h2>Hello, {{ loggedUser ? loggedUser : 'friend' }}!</h2>
</v-layout>
</v-container>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: mapGetters([
'isAuthenticated',
'loggedUser'
])
}
</script>
I seem to have managed to fix this. However, I'm not completely sure on the cause the fix involved modifying my .htaccess. I started playing with the settings and ended up with the following which works well (for now at least).
RewriteCond %{HTTP_HOST} ^my-app\.com$
RewriteRule "(.*\.(jpg|gif|png|svg|js|css))$" "http://127.0.0.1:3000/$1" [P,NC]
RewriteRule ^(.*) "http\:\/\/127\.0\.0\.1\:3000\/$2" [P,L]
The rule for jpg|gif etc is required as they don't load when using the second rule.

React Router v4 URL issue

Ours react app works in dev mode (localhost) perfectly, but when we put it onto the Heroku server we cannot access routes directly. When we do history.push({ }) to our path we get a 404 page.
You can see the page here: placemate.herokuapp.com
Steps to reproduce: go to the above URL, see it load. Then add /login to the URL bar and you will see that a 404 page appears. However, clicking a login from the header will direct you properly.
Here is our router code:
import React from 'react'
import { Switch, Route, Redirect } from 'react-router-dom'
import '../../App.css'
import Home from '../../scenes/general/home/Home'
import Login from '../../scenes/general/login/Login'
import Register from '../../scenes/general/register/Register'
import GuestHeader from '../../components/general/header/Header'
const Main = () => (
<main className='main_app'>
<GuestHeader />
<Switch>
<Route exact path='/' component={Home}/>
<Route path='/login' component={Login}/>
<Route path='/register' component={Register}/>
</Switch>
</main>
);
export default Main;
index.js file:
ReactDOM.render(<BrowserRouter><App /></BrowserRouter>, document.getElementById('root'));
registerServiceWorker();
Why 404 Not Found
This is because when you put up any path in your address bar its request is sent to the web server not react. As you know the react-router we are using is responsible to display the correct component based on the route, but since you pass the route to nginx / apache server not react-router; hence your web server tries to find www.example.com/login which actually does not exist. Hence you get 404 not found.
Solution
Try to create a .htaccess file on your web server public HTML root directory. Create some rules so that the request is always forwarded from the root path. This will let the react come into the picture, hence the react-router can grab the path and render the appropriate component.
For example, you can create something like this
For Apache server
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
#RewriteCond %{SERVER_PORT} 80
#RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]
RewriteRule ^ - [L]
# If the requested resource doesn't exist the serve index.html
RewriteRule ^ ./index.html
For Node.js
Sample code for node.js express server can be like this (present in file for server implementation, conventionally named as server.js)
const express = require('express');
const path = require('path');
const app = express();
if(process.env.NODE_ENV!== 'production'){
//do something if you are in development environment
//below lines only if you are using webpack based deployment
const webpackMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');
app.use(webpackMiddleware(webpack(webpackConfig)));
}
else{
// in production env do following thing
app.use(express.static('public_html_folder'));//give user access to public assets
//redirect all request to index.html for compatibality with react router
app.get('*',(req,res)=>{
res.sendFile(path.join(__dirname,'public_html_folder/index.html'));
});
}
app.listen(process.env.PORT || 3050, () => console.log('Listening'));
I hope this solves your problem or at least give you an idea of what to do if there is a different backend server.

React.js website build works on one host, but not another

I am new to react.js . I have created a react website using create-rect-app. I have run: npm run build in git and got my static site files. Everything works on the test host, however when i moved hosts only index page works and navigating to other page gives 404 error. For routing im using react-router-dom.
How can i get my page to work on the other host?
Working host: http://000webhost.com/
Badly working host is some local provider
Edit: Basically i have pages such as /Home and /Contact.
Im using react-router-dom.
code:
import React, { Component } from 'react';
import { BrowserRouter as Router, Route} from 'react-router-dom';
import logo from './logo.svg';
import './App.css';
import Home from './pages/Home.jsx';
import Contacts from './pages/Contacts.jsx';
import Our_products from './pages/Our_products.jsx';
class App extends Component {
render() {
return (
<Router>
<div>
<Route exact path ="/" component={Home}/>
<Route exact path ="/Home" component={Home}/>
<Route exact path ="/Contacts" component={Contacts}/>
<Route exact path ="/Our-products" component={Our_products}/>
</div>
</Router>
);
}
}
export default App;
My index is linked to /Home as you can see from code. i have uploaded Build folder to public_html on both hosting platforms. On one site works normaly, on the other only /Home page shows up.
So, you can ignore this, but what helped is changing
<a href="/" />
to
<Link to="/" />
. Basically one hosting provider could render links as
<a />
other only as
<Link />

Resources