How can I get my MERN app to refresh correctly on heroku? - javascript

I deployed my MERN app to heroku. It loads, and I can navigate between pages by clicking on the nav bar. But, if I refresh a page, it just comes up blank. There are no error messages on the screen or in the console. If I go back to a previous page that worked before, it also comes up blank. At this point, I don't know what to look for.

My problem stemmed from incorrectly defining the root react route in my server.js file. I got the home page to render and refresh, but then the app would not load any other pages. Here is the server.js file at that point:
const express = require("express");
const mongoose = require("mongoose");
const routes = require("./routes");
const app = express();
// set the port for mongo connection to 3001 in development mode
const PORT = process.env.PORT || 3001;
// Configure body parsing for AJAX requests
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// Serve up static assets
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
app.get("*", function (req, res) {
res.sendFile(path.join(__dirname, "./client/build/index.html"));
});
}
app.use(routes);
mongoose.connect(
process.env.MONGODB_URI || "mongodb://localhost/portfolio_db",
{
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
}
);
// Start the API server on port 3001
app.listen(PORT, () =>
console.log(`🌎 ==> API Server now listening on PORT ${PORT}!`)
);
This sort of fixed my problem, but the app still wasn't routing properly, so I posted this: new issue
Basically, there where 3 problems:
'path' wasn't required at the top of the file, so the path to index.html wasn't defined (had to look at heroku logs to see this error).
The default react route (app.get('*'....)) should not be in the if statement, and
The default react route statement needed to be below the 'app.use(routes)' statement.
I also deleted a statement defining the default react route in /routes/index.js. Now the app deploys and routes correctly.

I was also getting same error "cannot get /page" whenever I did refresh or window.location() So after 3 days of trials and deploys I found this solution. Add this in your server.js file before deploying.
if(process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
app.get("/*", function(req, res) {
res.sendFile(path.join(__dirname, "./client/build/index.html"));
}); }
You can add this code snippet before app.listen. Remember the path says ./client/build/index.html which references to your build file in the production build in remote heroku master.
cannot get /page happens because the server is not able to find the route which was created using react-router or anything else in frontend so we need to direct the app to index.html in production build so that it starts the whole frontend process again and identifies the route...

Related

stuck at building process while hosting on Vercel

I'm using node.js as a server-side to store the API respond, the app is working without any issue but recently I have been trying to host it on Vercel so I ran into many issue, the project get stuck at the building process...
the building output :
Building output
My server.js code :
// Setup empty JS object to act as endpoint for all routes
projectData = {};
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
const Cors = require('cors');
app.use(Cors());
// Initialize the main project folder
app.use(express.static('website'));
// Setup Server
const port = 8000;
const Server = app.listen(port , run);
function run() {
console.log(`hello there :D`);
console.log(`here is ${port} ready to go`);
}
//GET method
app.get('/all', function(req,res){
res.send(projectData)
console.log(projectData);
})
//POST method
app.post("/addUserComment", function(req,res){
projectData = {
temp : req.body.temp,
date : req.body.date,
feeling : req.body.feeling,
}
console.log(projectData);
res.send(projectData);
})
My working directory and build settings :
Working directory
Build settings
note: server.js is my server-side file, and my website folder includes my app.js file and my HTML, CSS files, also i did try to add Vercel.json file but i couldn't understand how to use it, so if you gonna add this file in your answer please explain how and why
I think you need to remove the build command, because it's now trying to run the server.js file instead of making a build.

How to deploy Node JS app cPanel from localhost to a server

I have created a simple Express JS app. and it is working fine in localhost. when I visit localhost:8000 I see static files (index.html, style.css and frontend.js).
I have tried to deploy that app in a server using cPanel. and I have installed Node app and dependencies using package.json successfully. But when I visit the domain I just see a message (Node JS app is working, Node version is 10.24.1).
How to make my app to point and display the static folder (index.html) and run the app?
My app architecture:
server.js
package.json
public/index.html
public/style.css
public/frontend.js
And here is my server.js startup file:
// Setup empty JS object to act as endpoint for all routes
projectData = {};
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Dependencies */
const bodyParser = require('body-parser');
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
const cors = require('cors');
app.use(cors());
// Initialize the main project folder
app.use(express.static('public'));
// Setup Server
const port = 8000;
const server = app.listen(port, function(){
console.log(`server running on localhost: ${port}`);
});
//POST Route to store data in the app endpoint, projectData object
app.post('/addData', addData);
function addData (req, res){
let data = req.body;
projectData = data;
console.log(projectData);
}
app.get('/getData', getData);
function getData(req, res) {
res.send(projectData);
}
The problem here is that you are not pointing a route to send the HTML file. Otherwise the client would have to point it to the correct path of the file, Like localhost:3000/index.html.
you need to send it from the server using app.get
app.get("/", (req, res) => {
res.sendFile(__dirname + "path to the file");
});
The problem was that I have created the app in a subfolder of my domain.
But when I have created subdomain and reinstalled the app inside it, the app is pointing to static folder successfully.

how to use serve static file with express and react?

I have a project made with create-react-app and i would like to use it within express ( as i need some back end functionnality).
basically, my server render a blank page when i run it....
here is the code of my server:
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, 'public')));
// An api endpoint that returns a short list of items
app.get('/api/getList', (req,res) => {
var list = ["item1", "item2", "item3"];
res.json(list);
console.log('Sent list of items');
});
// Handles any requests that don't match the ones above
app.get('*', (req,res) =>{
res.sendFile(path.join(__dirname , 'public', 'index.html'));
});
const port = process.env.PORT || 5000;
app.listen(port);
console.log('App is listening on port ' + port);
if i enter the endpoint http://localhost:5000/api/getList, i can see the result, but when i want to display my react app for the other end point, the page is blank.
The react app use different Route and i also added a proxy in the package.json.
my server source file is at the root of the react app like the image.
Does someone has an idea why the react app doesnt show?
Thanks
You have two lines that are kind of doing the same thing:
// Serve the static files from the React app
app.use(express.static(path.join(__dirname, 'public')));
Will serve your index.html file to http://localhost:5000/index.html
According to the Express documentation https://expressjs.com/en/starter/static-files.html
And then it seems like you have the second route:
app.get('*', is formatted incorrectly.
It would need to be app.get('/*'.
If you aren't directing the user to multiple routes then it might be better to just use the root, app.get('/', rather than trying to catch all routes.

Prerender Angular app on an already existing Node.js server

My goal is to have dynamic og: tags, that can be seen by the facebook crawler. By doing some research I figured the best (and probably the only) approach is to prerender my app on the server. However I'm having problems with doing that.
I already have an existing Node.js server which looks a little different from the servers in most online guides.
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const http = require('http');
const app = express();
// Api for retrieving data from DB
const api = require('./server/api');
// Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Angular DIST folder
app.use(express.static(path.join(__dirname, 'dist')));
// Api location
app.use('/api', api);
// Send all other requests to the Angular app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'))
})
// Set Port
const port = process.env.PORT || '3040';
app.set('port', port);
const server = http.createServer(app)
server.listen(port, () => console.log('Magic happens on localhost:' + port));
I've tried using prerender.io. I got an API key, installed prerender-node and put this right before redirecting the request to index.html:
app.use(require('prerender-node').set('prerenderToken', 'my-token'));
// Send all other requests to the Angular app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'))
})
I also added this to my index.html:
<meta name="fragment" content="!">
Nothing changed. Perhaps there's something else I need to do to get it working? Again, my goal is to have dynamic og: tags, that can be seen by the facebook crawler.
Additional info: For now, I'm setting the meta tags using the Meta serivce that comes with Angular 4, if it matters.
EDIT:
Demo link if someone wants to test: http://aramet.demo.cdots.bg/news-preview/1
Can you try moving the:
app.use(require('prerender-node').set('prerenderToken', 'my-token'));
above the static file line like:
app.use(require('prerender-node').set('prerenderToken', 'my-token'));
// Angular DIST folder
app.use(express.static(path.join(__dirname, 'dist')));
Since your index.html file is in your dist folder and you're serving static files from the dist folder, I'm wondering if the static call is serving your index.html file somehow.

Express sending assets with wrong MIME type

Using Express to serve a Vue.js webpack app, I am receiving the following error after deploy:
Is my code for serving the app is the issue here?
app.use(helmet())
app.use(express.static(path.resolve(__dirname, '../client/dist/static')));
app.all('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '../client/dist', 'index.html'));
})
Otherwise isn't express.static supposed to automatically assign content types to the static files?
You get this message also when the response status in 404 Not Found, so check carefully that the files actually exist from Network tab.
Network tab:
Console tab:
See a similar issue here: https://stackoverflow.com/a/48792698/258772
For some reason, had to now specify a mount path:
app.use('/static', express.static(path.resolve(__dirname, '../client/dist/static')));
Yes same problems over here.
I'm using ecstatic (still with express) now. I'm not sure if this is the solution (I'm not on the machine that made the error possible).
Will try it tommorow on the 'error' machine.
const express = require('express');
const ecstatic = require('ecstatic');
const http = require('http');
const app = express();
app.use(ecstatic({
root: `${__dirname}/public`,
showdir: false,
}));
http.createServer(app).listen(8080);
console.log('See if its cool on -> :8080');

Categories