How to call React routes with Nodejs?

Asked

Viewed 127 times

1

I’m deploying a project that has Front in React and Back in Nodejs, but my host (Kinghost) asks me to deploy the Node app and within the same folder put the React Build, the FTP looks like this:

inserir a descrição da imagem aqui

Within Node index.js, I’m pulling the build index.html as follows:

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

And this works very well, the home screen is Login, I can log in and drop off, show information from the bank, the problem is that on a page I have a Register button, and this registration is on route

<Container maxWidth="lg">
        <Switch>
          { !currentUser &&
          <Route exact path={`${process.env.PUBLIC_URL}/`} component={Login} /> }
          { showCadastroBoard &&
          <div>
            <Route exact path={`${process.env.PUBLIC_URL}/cadastro`} component={BoardCadastro} />
            <Route exact path={`${process.env.PUBLIC_URL}/`} component={CompreBem} />
          </div> }
          { showComumBoard &&
          <Route exact path={`${process.env.PUBLIC_URL}/`} component={CompreBem} /> }
          { showAdminBoard &&
          <Route exact path={`${process.env.PUBLIC_URL}/`} component={BoardAdmin} /> }
          { showTesteBoard &&
          <Route exact path={`${process.env.PUBLIC_URL}/`} component={BoardTeste} /> }
        </Switch>
      </Container>

When I click on this button to go to the registration page, the following error appears in the console:

Failed to load resource: the server responded with a status of 404 (Not Found)

and is on a page with "cannot GET /register".

What I do?

3 answers

1

could show your file tree?

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

Stó will only send will send the index.html file, for statical files I advise you to use a middleware Static, express: gather all static files in a folder, and use the command: app.use(express.Static({path of your statics folder})) example to build:

app.use(express.static(path.join(__dirname, 'build')))

from what I noticed your address has no extension, so even if you use sendFile, you need to define mimetype in the answer... an easier approach would be to do the rewrite with middleware, the express executes the middlewares in the order in which they are inserted, so you need to set the rewrite middleware before Static, the Static will already receive the url with extension, and will correctly define the mimetype... example of middleware for rewrite (customize it in your favor):

app.use(function(req, res, next) {
   //se o nome da url da requisição não tiver um ponto depois do ultimo '/' (não tiver extensão)
   if (req.url.lastIndexOf('/') > req.url.lastIndeOf('.')) {
      //adicionar extensão de .html
      req.url += '.html';
   }
   //passa para o proximo middleware da pilha...
   next();
});

0

Hello,

He also had this problem in Kinghost. Local everything worked normal, host did not work.

After a while, I found this in the React documentation:

https://create-react-app.dev/docs/deployment -> Flap "Serving Apps with Client-Side Routing"

In short:

1 - Create a named file .htaccess in the briefcase public and include the following lines.

Options -MultiViews
 RewriteEngine On
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule ^ index.html [QSA,L]

2 - Then rotate npm run build

I hope I can help you or a next friend with the same problem.

0

I could solve it just by reading: https://create-react-app.dev/docs/deployment following only the topics: Other Solutions, Serving Apps with Client-Side Routing, Building for Relative Paths

Before doing the build I needed to adjust some things:

First NAY needed to add process.env.PUBLIC_URL on routes like @Agaka did:

<Route exact path={`${process.env.PUBLIC_URL}/cadastro`} component={BoardCadastro} />

defined the routes as usual:

<Provider store={store}>
      <Router>
        <GlobalStyles />
        <Route exact path='/' component={Home} />
        <Route exact path='/detalhe' component={Detalhe} />
        <Route exact path='/painel' component={Painel} />
        <Route exact path='/login' component={Login} />
      </Router>
    </Provider>

then created a file .htaccess in the briefcase public of my project with the following content:

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

At Kinghost, they ask you to separate the build from the static files (frontend - React), they must be in the folder www server and the build of the backend files in nodejs must be in the folder apps_nodejs and in this folder should have an initial file that you should set the name in your Kinghost Adm panel, in my case I left with name main.js and his decoration was like this:

const http = require('http');
const express = require('express');
const path = require('path');
const app = express();

const port = 21016;
const baseDir = '../www/'

app.use(express.static(path.join(__dirname, `${baseDir}`)));    

app.get('/*', function (req, res) {
  res.sendFile(path.join(__dirname, `${baseDir}`, 'index.html'));
});

app.listen(port);

In my package json. added the homepage attribute:

"homepage": "http://www.meudominio.kinghost.net/",

So I built the front, and then I built the back. I added the front build to the www folder of the king host server: inserir a descrição da imagem aqui

and added the back build to the apps_nodejs folder on the king host server: inserir a descrição da imagem aqui

and xazammm my routes worked properly! :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.