React Router with Node JS - node.js

When using React-Router, you only serve up the original index.html with Node because the client handles the rest. I understand how to route between different pages once the user is at the home page. However, let's say the user types in the URL '/about'. Node will serve up the index.html, but how do you tell React-Router to then immediately take the user to the about page? Thank you.

If you have your BUILT create-react-app project sitting inside you node/public folder. you need to let express know that the index.html file will be handling the routes. see super simple server example below. this will use react routers setup properly.
const express = require('express');
const app = express();
const path = require('path');
app.use(express.static(path.join(__dirname, 'public')));
app.get('*', (req, res) => res.sendFile(path.join(__dirname, 'public/index.html')));
app.listen(3000);

Related

How to manage NodeJs app code to reduce clutter

Hie,
I am developing a Nodejs (Express) web app and pretty much new to this technology. So far I see that there can only be one point of entry mine being my the server.js file. Now it seems all requests and/or processes should be initiated here which is fine for a smaller application, but my site has about 25 page routes already all of who's request should be handle here. I also have a dozen or so Ajax requests are handled here. Now even though I am processing different functions e.g CRUD operations in separate files, I still fear at some point my code will become unreadable as the server.js file get longer
const express = require("express")
const path = require("path")
const exphbs = require("express-handlebars")
let app = express()
app.set("views",path.join(__dirname,'templates'))
app.engine('handlebars',exphbs({defaultLayout:'main'}))
app.set('view engine','handlebars')
app.set('port',(process.env.PORT || 3000));
app.get('/',(req,res)=>{
res.render('home',{'title':'Home'});
});
app.get('/home',(req,res)=>{
res.render('home',{'title':'Home'});
});
app.get('/register',(req,res)=>{
res.render('register',{'title':'Register'});
});
app.use(express.static(path.join(__dirname, '/public')));
app.listen(app.get('port'),()=>{
console.log(`Server started on port : ${app.get('port')}`)
})
So far my server.js is this small, but it just hit me that I have 25 pages and multiple Ajax processes on each.
Yes, you have to structure your routes. For that, you have to look at Express Router. You have to create different route files based on a specific resource.
/routes/homeRoutes.js
const express = require("express");
const router = express.Router();
router.get('/',(req,res)=>{
res.render('home',{'title':'Home'});
});
module.exports = router;
server.js
const homeRoutes = require("./routes/homeRoutes");
app.use("/api/v1/home", homeRoutes);
Also, have a look at the following links for a better understanding of project structure and express router.
https://expressjs.com/en/guide/routing.html
project structure
I think what you are looking for is splitting the code up in local modules. You can place parts of your code in separate files, include module.exports at the end and then require(./filename.js) them in your server.js.
You can see an example here: https://www.tutorialsteacher.com/nodejs/nodejs-local-modules

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')
});

How to create a node based server to serve REST API and also deploy the application.

I am new to nodeJS server area, need help in understanding how to work with REST API (using express) and deploy the angular application over a singe node server and same ports.
By deploying i want to understand if user hit below url http://localhost:8000/<page_name> then the specified page should open.
And is user hit below url using get or post request
http://localhost:8000/api/<api_name> then a json or a text will be returned.
How to run both the thing over a single node server.
Lets assume, you have all your static files in the /public folder of you app. Generally spoken, if you are using express.static, you should also get your index.html because this is handled by default for each directory.
In your case, as you are using Angular, the routing is handled from the client side (SPA). You should only have one single index.html after building your Angular app. All files from your dist folder should then be placed into your /public folder. Then you need to make sure, that initial file serving provides your index.html like so:
In this example static files are served first, then your API and if nothing is found, you are getting back you index file.
const express = require('express');
const app = express();
// serve static files
app.static(__dirname + '/public'));
// serve your API
app.get('/api/welcome', function (req, res) {
res.send('Welcome');
});
// fallback routing (server side handling)
app.get(/.*/, function (req, res) {
res.sendFile(__dirname + ‘/public/index.html‘
});
app.listen(3000);
Next time please make sure, to give all necessary information in your question ;-)
With the help from Sebastian, so far I can find a solution but its not working when i am hitting URL for different pages.
const express = require('express');
const app = express();
app.use(express.static('public'))
Please provide your suggestions.

Serve images and js from different locations ExpressJs: Node

I am using the below code to serve statics files(js, images, css):
app.use(express.static(path.join(__dirname, 'public')));
But now the images have been moved to some different location in the project i.e. outside the public directory (lets say. images).
So how do I differentiate between images and js,css files and serve them from different locations?
EDIT
I guess I have to read the request headers and then decide where to route the request. But looks a little dirty to me.
Try with two separate endpoints:
import express from "express";
import {join} from 'path';
const app = express();
const publicPath = express.static(join(__dirname, '../public/'));
const publicImages = express.static(join(__dirname, '../images/'));
app.use('/public', publicPath);
app.use('/images', publicImages);
app.listen(3400, function() {
console.log("Express server listening on port 3400");
});
Then you use it like this: http://localhost:3400/images/ and http://localhost:3400/public/
In that case you just need to add one more static file configuration
app.use(express.static(path.join(__dirname, 'images')));
And it will be served as
http://example.com/files-from-images-folder

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');
});

Resources