Host React and Express on the same server? - node.js

I am working on a react site that has a contact page. On the contact page there is a text field where you enter a message that will be sent to a specific email address.
Right now I'm just trying to set up express with my react app, the only thing I need Express for is this one feature.
In my react app I am doing
$.post('http://localhost:3030/API',{value:'hi'}, function(result) {
console.log(result);
});
And in my Express index.js file I'm doing
app.get('/API', (request, response) => {
console.log(request);
})
Just as a simple test to see if things are working properly.
When I run these both and attempt to execute my post function, I get the No 'Access-Control-Allow-Origin' header is present on the requested resource. error, which is basically saying that I can't make a request to a separate domain. The issue here is not that error, but the fact that I am running my Express server and react app on two different servers.
Is there a way to have them on the same server? I am very new to back-end development, any help would be very appreciated!

Yes, React runs on the client and Express is a Node.js framework. There's a pretty good chance you're using Express if you're running any boilerplate.
Here's a pretty good walkthrough on more complete routing.
https://medium.com/#patriciolpezjuri/using-create-react-app-with-react-router-express-js-8fa658bf892d
In several of my applications my routes look something like this:
//router.js--and I'm positive this is from some react-express boilerplate
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
const react = (req, res, next)=>{
res.render('react', {
title: 'React Application',
layout: false
});
};
router.get('/app', react);
router.get('/app*', react);
module.exports = router;
//app.js
...
app.use('/', routes); //<--this is the exported router.
...
If you want to be more simple it is probably something like:
let reactRoute = (request, response, next) => {
//render your react page however you're doing that.
}
express.use('/API', yourApiFunction)
express.use('/', reactRoute)
express.use('/*', reactRoute) //Wildcards are REALLY important if you're routing inside react.
You can also bypass things with a proxy but that tends to get more complex than you probably want. Also--keep in mind you don't have to stick to Node on the back-end if you're not comfortable with it. React is client side, I use it with a few production .NET apps, some PHP (lordy!), and, yes, a lot of Node servers.

to solve No 'Access-Control-Allow-Origin' header is present on the requested resource.
you've to use the cors middleware
go to the term
yarn add cors or npm i cors
in server.js
const cors = require("cors");
const express = require("express");
const app = express();
app.use(cors());

Related

Problem using Nodejs / Express routing paths

I am a long time programmer but I'm new to Node and have a simple question about routing paths in Express which I cannot get to the bottom of.
I've developed a very simple app using node/express and MySql. I have then split up my GET and POST routes in the app just for convenience. I am using the route '/posts' at the app level and the sub route '/submit-form' in my router() which is the URL my form submits to.
I'm obviously doing something stupid because it doesn't work, I get the cannot POST message. If I use the full URL in the app and in the router then it works fine so there's nothing wrong with the code I think, only with my understanding of how express does routing.
Any advice appreciated.
A router should be used with the .use() method. Therefore, you should use the following in your app.js file
app.use('/posts', PostRoute)
When the nested router (on /posts) will handle the request, it will now based on the nested route declaration which HTTP method should match
app.js
const app = express();
app.use('/user', require('./routes/user'))
then inside the user;
const router = express.Router({});
router.post('/login', (req,res,next) => {
});
module.exports = router;

I have express on backend and react on frontend, but i also have admin page working on pug template, how can i run it on one domain

I have express on back-end and react.js on frontend, but i also have admin page with pug view engine, working on express routes, how can i use these in one domain
Expressjs is composable in a really nice way. You can have a top level express application which routes off to sub-express apps and serve your individual services.
Lets say you want to serve your react frontend from www.example.com, your admin (pug views) from www.example.com/admin, and you also want to have an api which serves the react frontend at www.example.com/api`.
You would want something a bit like the following code sample which demonstates the composition of express applications. I've not run the code but it should be enough to get you going.
// This parent app acts as a parent layer and router
// for all your "sub apps". Any middleware you apply
// to this express app will apply to *all your other
// sub-apps*.
const parentApp = express();
// We now create another express instance, this will
// house the API. It can be in another file and you
// could require in something like "require('api');"
// instead but for brevity we'll keep it all in one
// file.
const apiApp = express();
apiApp.get('/info', (req, res, next) => {
console.log('/info');
return res.sendStatus(200);
});
// Mount the sub app on the /api route. This means
// you can how hit 'www.example.com/api/info' and
// you'll get back a 200 status code.
parentApp.use('/api', apiApp);
// Now we setup the admin app which we'll add pug
// views into. This is an example so just pretend
// the views exist.
const adminApp = express();
adminApp.set('views', './views');
adminApp.set('view engine', 'pug');
adminApp.get('/login', (req, res, next) => {
return res.render('login', { title: 'Hey' });
});
// Mount the sub app on the /admin route. This way
// we can hit www.example.com/admin/login to get
// our login page rendered.
parentApp.use('/admin', adminApp);
// Now we create and mount the frontend app that
// serves our fully built react app. You could do
// this with nginx instead but you wanted to do
// it with express so lets do it that way.
const frontendApp = express();
frontendApp.use(express.static('/frontend));
parentApp.use('/', frontendApp);
If you'd rather not create yourself a top level express app (and thus creating a bit of a monolith application) then I'd recommend checking out the nginx documentation, or the docs for the HTTP server you use. You should be able to direct requests to particular endpoints to different node applications running on different ports. Static files can then be served natively by your HTTP server. This is definetely a more efficient and elegant approach, but since you asked about express I wanted to showcase that approach primarily.

Using Mixpanel - Node Library in Express

I am currently trying integrate the Mixpanel Node library into a test application that I am building. This is a Node.js application using the express framework.
As per the express docs, I have a JS file to manage the project, a folder called "public" that contains all of my static files, and another folder with the node modules that come with express.
I have two static HTML pages in "public" that I am trying to put mixpanel tracking into. I am running the project locally by running node app.js.
app.js includes:
const express = require('express');
const app = express();
const port = 3000;
const path = require('path');
//Mixpanel Additions
var Mixpanel = require('mixpanel');
var mixpanel = Mixpanel.init('<I am putting my project token here>', {
protocol: 'https'
});
//App Configuration and Init
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/public/page.html'));
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
In my HTML files I try to use mixpanel functions by putting them into script tags:
<script>
mixpanel.track("event")
</script>
But when I run node app.js and view the page in my browser it says:
Uncaught ReferenceError: mixpanel is not defined
I have a pretty poor understanding of node.js, but I am imagining that I need to use app.use(), app.get(), or something along those lines to get the Mixpanel lib loaded into the app. What am I doing wrong? I also realize that my understanding of Express and Node is pretty rudimentary, so any additional knowledge is appreciated, especially if I am way off.
If you want to call mixpanel tracking functions in the browser, you should load the mixpanel library in a script tag on the browser side, as seen here:
https://developer.mixpanel.com/docs/javascript
The purpose of the node.js package is to send events from the server side, like if you wanted to log when page.html is rendered, you could do
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/public/page.html'));
mixpanel.track('event')
});

Routing in Express and MEAN stack

I am following an on-line tutorial of implementing in MEAN. Everything looks great. Except when it comes to routes. I understand that routes need to be in a javascript files (js extension). It's okay with a small web site. But as the number of requests grow, I would like to put them in separate files. I looked up in SOF for how to include files in Javascript. It is non-trivial. Has anyone faced this issue before? Can anyone comment?
Thanks
You can use Router Middleware by using express.Router(). This allows you to break your routes into different files. On a side note, middleware is very powerful and is worth learning about, its a huge part of Express.
Say you have an app that has a /users section. You can create a separate routes file called users.js that contains all routes that pertain to your /users resources. Then inside your server.js where your main Express app is listening, you can assign the users.js routes to the /users resource using app.use().
You can have as many routers as you'd like, all routes are read top-down when Express is deciding which route to use.
./routes/users.js
// Create an express router
var router = require('express').Router();
// Define a route for GET /
router.get('/', function(req, res) {
res.status(200).send('Welcome to /users');
});
// make our router available for require() statements
module.exports = router;
server.js
var express = require('express');
var app = express();
// Users routes
var users = require('./routes/users');
// Tell our app to use the Users routes defined in ./routes/users.js
app.use('/users', users);
app.listen(process.env.PORT || 3000, function() {
console.log('listening');
});

Get response of Node.js Express app as a string

How does one get the response of an express app as a string given a request object?
In other words, I want a way to send a request object to an express app and receive its response as a string.
As code, I am looking for some implementation of the sendToThisApp method:
var app = express();
app.get( /* Some code here */ );
var request = // Some request object
var response = app.sendToThisApp(req)
console.log(response);
Thanks.
Here is the code for a simple Node.js Express app :
var app, express;
express = require('express');
app = express();
app.get('/', function(req, res) {
console.log(res);
res.end();
});
app.listen(8080);
In order to trigger a get request on this app, you need to run the app on node. Open a terminal and type this command:
node app.js
Then, you only need to start your favorite browser, go to localhost:8080, and look back at the log of the response in your terminal.
It looks like you're expecting things to happen synchronously that node and express want to handle asynchronously through callbacks.
But aside from that, I'm not really understanding what you're trying to do.
If you have the code for the node app, and you just want to see the response object as a string, then the easiest way to handle that is through the callback on the get.
app.get('/', function(req,res){
console.log(res);
}
But without knowing what you're actually after, I can't give better advice.

Resources