Reputation: 141
I am new to react, and I am trying to build a chat-app with it. I used react-router to load different components according to the url. In my react project foler (client/src/index.js), the code is as follows:
import {BrowserRouter as Router, Route} from 'react-router-dom';
...
ReactDOM.render(
<Router>
<div>
<Route exact path='/' component={App} />
<Route path='/customer' component={CustomerPage} />
<Route path='/support/:support_id' component={SupportPage} />
</div>
</Router>,
document.getElementById('root')
);
...
It works find when I start it in the react folder with "npm start". But when I run "npm run build" and serve the static files with express server, it can only serve the App page in the '/' path, while for '/customer' and '/support/:support_id" path, it loads nothing.
In the express server folder, I load the static files in the following way:
server/app.js:
...
var indexRouter = require('./routes/index');
app.use('/static', express.static(path.join(__dirname, '../client/build//static')));
app.use('/', indexRouter);
...
server/routes/index.js:
...
router.get('/', function(req, res) {
res.sendFile('index.html', {root: path.join(__dirname, '../../client/build/')});
});
...
Any help will be appreciated!
Upvotes: 14
Views: 17587
Reputation: 1
I finally found the full solution to serve a React Router App on Express server. Here's the code:
Front End Side
router.tsx
import { createBrowserRouter } from "react-router-dom";
import routes from "./routes";
export const appRouter = createBrowserRouter(routes, { basename: "/" });
Build your React project:
npm run build OR yarn build
Back End Side
app.ts
import express, { Application } from "express";
import path from "path";
const app: Application = express();
// Rest of your code if needed (CORS,api,etc...)
const root = path.join(__dirname, "build");
app.use(express.static(root));
app.use("/*", (req, res) => {
res.sendFile(path.join(__dirname, "build", "index.html"));
});
export default app;
server.ts
require("dotenv").config();
import http from "http";
import app from "./app";
const server = http.createServer(app);
server.listen(process.env.PORT, async () => {
console.log(`HTTP Express server listening on port: ` + process.env.PORT);
});
root:
babel-node server.ts
, go to http://yoururl, it works !Upvotes: 0
Reputation: 3
app.get("/get/data/from/store", (req, res) => {
your sql codes here
});
// You must place all your above REST API Calls before the below codes. // Otherwise all urls '*' will be forwarded to index.html
// wildcard handles any requests that don't match the ones ABOVE
app.use(express.static(path.join(__dirname, '/build')))
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname+'/build/','index.html'));
});
app.listen(port, () => {
console.log("Server running on port ", port);
});
put the wildcard app.get('* call at the end. Just before the app.listen.
Upvotes: 0
Reputation: 54
Getting rid of this block helped me
app.use(function(req, res, next) {
next(createError(404));
});
Upvotes: 0
Reputation: 341
You must serve the static files and handle any request in your index.js:
const express = require('express');
const path = require('path');
const app = express();
// Serve the static files from the React app
app.use(express.static(path.join(__dirname, 'client/build')));
// Handles any requests that don't match the ones above
app.get('*', (req,res) =>{
res.sendFile(path.join(__dirname+'/client/build/index.html'));
});
const port = process.env.PORT || 5000;
app.listen(port);
console.log('App is listening on port ' + port);
Upvotes: 1
Reputation: 111
*
worked instead of using /
in app.get() otherwise it'll always show cannot get. Thanks @basse
Upvotes: 0
Reputation: 112787
React Router does all the routing in the browser, so you need to make sure that you send the index.html
file to your users for every route.
This should be all you need:
app.use('/static', express.static(path.join(__dirname, '../client/build//static')));
app.get('*', function(req, res) {
res.sendFile('index.html', {root: path.join(__dirname, '../../client/build/')});
});
Upvotes: 55