Express and React js: deal with api request, proxy? - node.js

My situation:
I'm using Express and passport.js as my backend API server and React js as my front-end.
What I'm currently facing is that I keep getting index.html file when I request my passport auth by "/api/auth/*". However, it works as I expected when I'm making a request from my front-end via proxy.
So I tried using Regex to exclude "/api/*" route from using static build files.
app.use('/api', api)
app.use(/^\/(?!api).*/, express.static(path.join(__dirname, '/../build')))
app.get(/^\/(?!api).*/, (req, res) => {
res.sendFile(path.join(__dirname, '/../build/index.html'))
})
But not like my expectation, I just got Unexpected token < warning ...
How can I get my get "/api" route to work also while using React js build files?
Or should I just keep making a proxy request from React js dev server?
I want to understand how Express and React js app deployed in some server work together.

Related

Connect express backend to React frontend (in the same server if possible)

I saw a lot of ways to connect React frontend to express backend (REST API) and i don't understand which one of the them is the most common, organized and friendly. (Axios, componentDidMount function and so on..).
My project divide to backend and frontend libraries which includes a connection to mongoDB in the backend.
I am new to React so i will appreciate any recommendation.
You can easily have both on the same server, all you need to do is. Make an express route that servers your react app's index.html.
app.get('/', (req, res) => {
res.sendFile('./public/index.html');
});
Also, don't forget to serve your static files (css, fonts, etc) using express's own middleware.
app.use(express.static('public'));
After you have done that, you can have your API at /api.

How to render/resolve react-router enpoints when being served from an express/node server [duplicate]

This question already has an answer here:
Configure node express for Backbone SPA with pushState
(1 answer)
Closed 2 years ago.
I am using react-router in a react frontend app that is served from a directory, "/build",
of my express server. All the non-frontend functionality (database etc.) come from an endpoint "localhost:3003/api/something" and I have the frontend setup to serve from "localhost:3003/".
The problem I have is that when I navigate from the frontend's home ("localhost:3003/") to elsewhere, e.g. "localhost:3003/drinks/1", everything works fine. However, when I reload the browser whilst at "localhost:3003/drinks/1" or navigate directly to that URL, it gives an "endpoint not found" error.
You have to add those routes on the server side.
A simple way for an SPA to handle every route is like this:
app.get('*', handler);
This error is because react-router is using history.pushState() to resolve the endpoint but if you reload the server will attempt to serve you that endpoint from the server, and that endpoint doesn't exist to the server.
There is a way to tell the server to defer this render to react-router.
app.get('/drinks/*', function response(req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
Now index.js will serve any request that goes to localhost:3003/drinks/anything. Meaning, the front-end will be rendered accordingly by react-router instead of being hijacked by express.

Use Reactjs app as a frontend for express nodejs in backend on domain

I created a frontend app using react js that calls an express node js api in the backend, in localhost i don't have problems because it runs on localhost, but when i deploy them both on plesk server, i don't know how to call express api from my react js app.
1.How to run express node js in production on plesk server.
2.How to call express api from react js app (in localhost i use http://localhost:8000/users)
Thank you kindly
This deployments assumes, you build your react app into your express app. So in final, your app runs on the same domain as your backend.
E.g. if you build your react app to reactapp folder within your express, then you serve it with:
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'reactapp/index.html'));
});
And on the same express you have another route for your api:
app.get('/api/somerestapi', (req, res) => {
// process your api request
res.send({data: 'some data'});
});
It means, you call your API from React with relative path:
const request = new XMLHttpRequest();
request.open('GET', '/api/somerestapi);
...

Create React App with Express API cookie authentication

My setup is thus:
Node server running Express which runs an API.
Inside a subdirectory client is a Create React App project, with the proxy field set to the URL of the Express API.
I start both processes and access the CRA in my browser, which sends requests to the Express API through the proxy.
This all works fine.
In production, I will build the CRA and serve it from the Express app, like so:
app.use('/api/:controller', (req, res, next) => {
return router(req, res, next)
})
app.get('*', (req, res) => {
res.sendFile(path.join(`${__dirname}/client/build/index.html`));
})
My only roadblock is how to handle authentication. I could quite easily do an onload fetch request back to the API when the React app is initialised in the browser to see if the user has a session, but it seems like a waste.
In development (and I guess production for that matter), what would be a good way to 1) read the cookie from the incoming request and 2) pass on the currentUser object to the index.html above (in production) or to CRA in development.
To clarify, I was wondering if there are any specific CRA recipes for handling authentication from the server, before it sends the response back to the browser? (in this dual-purpose codebase setup)
Exact issue: In development, because I'm running yarn run cra, it's spinning up it's own webpack dev server, which serves the React app. So I don't believe I can really get at the request before it gets sent back to the browser.

Separate Node and React App: Allow Express passthrough to React Router

I have two separate apps: one of them is my API in Node with Express, and the other is my front end in React with React Router.
Typically when doing smaller apps, you might have the server code colocated with your client code in the same repo, but in this case they are separate repos. I am trying to allow passthrough to React Router from Express if the route is not matched, and we traditionally do it like this:
app.get('*', function(req, res) {
res.sendFile(path.resolve(__dirname + 'dist/index.html'));
});
See the problem? I don't have the dist folder on my server, so I have no reference to the index.html available. The reason I broke out the repos is because I upload all the front end code to a CDN, and can just proxy the network requests to my API.
How do I allow the passthrough from Express to React Router if I don't have a file or path to resolve in the res.sendFile catch-all ?
A bit of a hack, but I realized that this would probably work and I tried it out and it does indeed. You can probably take this a step further and even extract the referrer from req.headers.
request("https://yourwebsite.com/index.html",(error, response, body) => {
res.send(body)
}

Resources