I deployed a MERN app to Heroku (using MongoDB Atlas for database) and the home page is not rendering the login or register forms. I checked the Heroku logs for any errors and there are no errors. Also, when I inspect the elements I see the elements are there but the React components are not rendering. Only the CSS background image is rendering. Is there something off with my heroku-postbuild script? Thanks.enter image description here
Heroku app hosted at "https://glacial-gorge-15530.herokuapp.com/login". Below are my server.js and package.json files. I also added images of development vs production screenshots of the login page.
server.js
const express = require('express');
const connectDB = require('./config/db');
const path = require('path');
const app = express();
//Connect Database
connectDB();
//Init middleware
app.use(express.json({ extended: false }));
//Define routes
app.use('/api/users', require('./routes/users'));
app.use('/api/auth', require('./routes/auth'));
app.use('/api/recipes', require('./routes/recipes'));
//Serve static assets in production
if(process.env.NODE_ENV === 'production') {
//Set static folder
app.use(express.static('client/build'));
app.get('*', (req, res) => res.sendFile(path.resolve(__dirname,'client', 'build', 'index.html')));
}
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
package.json
{
"name": "favorite-recipes-2",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"client": "0.0.1",
"config": "^3.3.1",
"create-react-app": "^3.4.1",
"express": "^4.17.1",
"express-validator": "^6.6.0",
"jsonwebtoken": "^8.5.1",
"materialize-css": "^1.0.0-rc.2",
"mongoose": "^5.9.20",
"react-transition-group": "^4.4.1"
},
"devDependencies": {
"concurrently": "^5.2.0",
"nodemon": "^2.0.4"
}
}
Screenshots of login page in production environment
Screenshots of login page in development environment
Your .form-container element has an opacity of 1%, which is why the elements are invisible.
.form-container {
background-color: #e7e3e3;
opacity: 1%;
}
Remove opacity: 1%.
Related
Let me explain further, what i mean is i have created a mern app which is already deployed on heroku now i want to make changes in the app but before i push it again on heroku i want to check my changes locally so how do i do that?
I tried the heroku local command but it starts the client side and cannot fetch the node server routes please help me out here !? here is my code:
node app.js
import express from "express";
import bodyParser from "body-parser";
import dotenv from 'dotenv'
import router from './Routes/auth.js'
import path from 'path';
dotenv.config({path:'./config.env'});
const host = '0.0.0.0';
const port = process.env.PORT || 5000;
const app= express()
app.use(router);
if(process.env.NODE_ENV === "production"){
const __dirname=path.resolve();
app.use(express.static(path.join(__dirname,"/client/build")));
app.get("*",(req,res)=>{
res.sendFile(path.resolve(__dirname,'client','build','index.html'));
})
}
app.listen(port,host,()=>{
console.log(`Server Started Succesfully on port number ${port}`);
})
package.jso(nodejs)
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "app.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "npx nodemon app.js",
"client":"npm start --prefix client",
"dev":"concurrently \"npm start\" \"npm run client\"",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"body-parser": "^1.19.1",
"cookie-parser": "^1.4.6",
"dotenv": "^10.0.0",
"express": "^4.17.2",
"jsonwebtoken": "^8.5.1",
"moment": "^2.29.1",
"mongoose": "^6.1.8"
}
}
My file system
According to my testing You can do:
Check on Browser Tools: Like Responsiveness
Check your elements in DevTools
All Pages all Div tags elements, responsiveness of app, and design you can check of your app
for node server routes you can check by testing it in Postman API tool
That's it Ready to Deploy
I am trying to deploy a full-stack app on heroku, i have tried couple of things but none of them worked... when i entered "heroku logs" to follow up with the errors it should me code: 'MODULE_NOT_FOUND even though the node_module's can be found in both the Root of the project and the Frontend file as well , how do i fix this error and where does it come from ?
Here's a picture of my projects structure:
server.js:
require('dotenv').config();
const path = require('path');
const express = require("express");
const productRoutes = require("./routes/productRoutes");
const connectDB = require("./config/db");
connectDB();
const app = express();
app.use(express.json());
//--------------- deployment -------
app.use("/api/products", productRoutes);
if(process.env.NODE_ENV === "production") {
app.use(express.static(path.join('../frontend/build')));
app.get('*',(req,res) => {
res.sendFile(path.resolve(__dirname,'../frontend/build','index.html'))
})
} else {
app.get("/", (req, res) => {
res.send("Api running");
})
}
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
.env:
PORT=8080
MONGO_URI=*****
NODE_ENV=production
Package.json:
{
"name": "mern-shopping-build",
"version": "1.0.0",
"description": "Shopping list built with MERN stack",
"main": "server.js",
"engines": {
"node": "16.4.1",
"npm": "7.18.1"
},
"scripts": {
"build": "cd frontend && npm run dev",
"install-client": "cd frontend && npm install",
"heroku-postbuild": "npm run install-client && npm run build",
"start": "node server.js",
"server": "nodemon backend/server.js",
"client": "npm start && cd frontend",
"dev": "concurrently --kill-others-on-fail \"npm run server\" \"npm start --prefix frontend\""
},
"keywords": [],
"author": "Karim ",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"mongoose": "^5.13.2"
},
"devDependencies": {
"concurrently": "^6.2.0",
"nodemon": "^2.0.9"
}
}
ProcFile:
web node server.js
I Would appreciate any kind of feedback or help, Thank you!
A Procfile is not technically required to deploy simple apps written in most Heroku-supported languagesāthe platform automatically detects the language and creates a default web process type to boot the application server.
Just make sure to point your root package.json main key to backend/server.js.
Most likely it would work otherwise share your Build Logs to check it further.
{
"main": "backend/server.js"
}
I have deployed my site to google cloud platform and the react(static) part is working fine, but anytime I go to /api/mail/send to use nodemailer I either get a 404 error saying it cant be found or with some configurations in the yaml file I just a 500 error.. below is my yaml, package.json and server.js files
App.yaml
runtime: nodejs12
env: standard
basic_scaling:
max_instances: 5
idle_timeout: 5m
handlers:
- url: /api/.*
secure: always
script: auto
- url: /
static_files: client/build/index.html
upload: client/build/index.html
secure: always
- url: /
static_dir: client/build
secure: always
Package.json
{
"name": "mern",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js",
"dev": "concurrently \"nodemon --ignore 'client/*'\" \"npm run client\"",
"client": "cd client && npm run start",
"install": "cd client && npm install",
"build": "cd client && npm run build"
},
"author": "",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^9.8.6",
"concurrently": "^5.3.0",
"husky": "^4.2.5",
"postcss-cli": "^7.1.1",
"tailwindcss": "^1.6.2"
},
"dependencies": {
"if-env": "^1.0.4",
"axios": "^0.19.2",
"body-parser": "^1.19.0",
"classnames": "^2.2.6",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-session": "^1.17.1",
"morgan": "^1.10.0",
"nodemailer": "^6.4.11"
}
}
server.js
require('dotenv').config()
const express = require("express");
const morgan = require('morgan');
const routes = require("./routes");
const path = require('path');
const app = express();
const PORT = process.env.PORT || 3001;
// Define middleware here
app.use(morgan('dev'));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// Add routes, both API and view
app.use(routes);
// Serve up static assets (usually on heroku)
app.use(express.static("client/build"));
// Start the API server
app.listen(PORT, function() {
console.log(`š ==> API Server now listening on PORT ${PORT}!`);
});
Thanks
I read bunch of blogs about MERN application deployment on Heroku but they all are uses separate package.json for client and server!
Is it possible to use one package.json file?
My Project Structure
My package.json
{
"name": "ecommerce",
"version": "0.1.0",
"private": true,
"author": "Dweep Panchal",
"license": "ISC",
"dependencies": {
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.5.0",
"#testing-library/user-event": "^7.2.1",
"braintree-web-drop-in-react": "^1.1.1",
"concurrently": "^5.2.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.1",
"react-stripe-checkout": "^2.6.3",
"body-parser": "^1.19.0",
"braintree": "^2.22.0",
"cookie-parser": "^1.4.5",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-jwt": "^5.3.3",
"express-validator": "^6.4.0",
"formidable": "^1.2.2",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.15",
"mongoose": "^5.9.7",
"stripe": "^8.46.0",
"uuid": "^7.0.3"
},
"scripts": {
"server": "cd ./backend && node app.js",
"start": "concurrently \"npm run server\" \"react-scripts start\"",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy": "http://localhost:8000",
"devDependencies": {
"nodemon": "^2.0.3"
},
"engines": {
"node": "10.16.0",
"npm": "6.9.0"
}
}
app.js
require("dotenv").config({ path: "../.env" });
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const cors = require("cors");
const app = express();
// Routes
const authRoutes = require("./routes/auth");
const userRoutes = require("./routes/user");
const categoryRoutes = require("./routes/category");
const productRoutes = require("./routes/product");
const orderRoutes = require("./routes/order");
const stripeRoutes = require("./routes/stripepayment");
const braintreeRoutes = require("./routes/braintreepayment");
// DB Connection
mongoose
.connect(
`mongodb+srv://${process.env.DB_NAME}:${process.env.DB_PASS}#${process.env.DB_PROJECT}-xi8tq.mongodb.net/${process.env.DB_PROJECT}?retryWrites=true&w=majority`,
{
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: true,
}
)
.then(() => console.log("DB Connected!"))
.catch(() => console.log("Failed to Connect DB"));
// Middleware
app.use(bodyParser.json());
app.use(cookieParser());
app.use(cors());
// My Routes
app.use("/api", authRoutes);
app.use("/api", userRoutes);
app.use("/api", categoryRoutes);
app.use("/api", productRoutes);
app.use("/api", orderRoutes);
app.use("/api", stripeRoutes);
app.use("/api", braintreeRoutes);
// Server Connection
const port = process.env.BACKEND_PORT || 8000;
app.listen(port, () => console.log(`Server Running at Port ${port}`));
When i deployed this application on heroku then project url shows:
Invalid Host header
Whole project: https://github.com/dweep612/ecommerce
Let me quickly explain how deploying any Reactjs and express to heroku work. The goal is to generate a build folder with npm run build and then starting the server to serve static content from that build folder.
In the heroku documentation, it states that heroku-postbuild runs before the start scripts. This is a perfect place to do npm run build to generate a build folder and then using the start script to run your server code. From there your server should be using express.static and pointing where ever you generated your build folder.
That is why people like to use a server package.json because it won't interfere with the react start script. Now the problem I immediately see is that you are not using the scripts correct nor are you pointing at that build folder that you are suppose to generate.
In your package.json create a start script that starts your app.js file and then create a heroku-postbuild that will generate a build folder. Like below
"scripts": {
"start": "cd ./backend && node app.js",
"heroku-postbuild": "npm run build",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
After that you should have app.use(express.static(<<location of build folder>>)) in your app.js . Add the code below in your app.js
if (process.env.NODE_ENV === "production") {
app.use(express.static("../build"));
}
The reason I said ../build is because your build folder is outside of the backend folder.
I also checked out your entire code and there are other small configuration issue. For example, if you are deploying to heroku , you should be using process.env.PORT
Yes it's possible, if your backend serves your frontend. Two package.json is useful when your backend and your frontend run on two separate node programs.
The invalid host headers are probably due to how your server handles headers, but since you didn't posted a minimal reproducible example, as of now we can't help you further.
I used MERN(MongoDb, Express, React js, Node) technology for my app. It works locally fine. but When I deployed in heroku I am getting internal server error. I might made mistake in setup but I can't see it.
In google Chrome console I got this error: Refused to load the image 'https://diary2020.herokuapp.com/favicon.ico' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.
When I used Heroku logs I got this:
This is my server setup:
require("dotenv").config();
const express = require("express");
const cors = require("cors");
const morgan = require("morgan");
const app = express();
const logs = require("./src/logs.js/logs");
const mongoose = require("mongoose");
const path = require("path");
const helmet = require("helmet");
//middlewares
app.use(cors());
app.use(morgan("dev"));
app.use(express.json());
app.use(helmet());
//connect to db
mongoose
.connect(process.env.MONGODB_URI, {
useUnifiedTopology: true,
useNewUrlParser: true
})
.then(() => console.log("DB Connected!"))
.catch(err => {
console.log(err);
});
app.use("/api", logs);
app.use(express.static(__dirname + "build")); //
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "build", index.html));
});
const port = process.env.PORT || 5000;
app.listen(port, () => {
console.log(`Server is running port ${port}`);
});
In my client folder first run npm run build then I cut it and pasted it outside of the client. Then I connected to server. As you can above. But it does not recognize the build's index.html
This is my backend package.json
{
"name": "form",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js",
"server": "node server.js",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\""
},
"author": "alak",
"license": "MIT",
"dependencies": {
"concurrently": "^5.1.0",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"helmet": "^3.21.3",
"heroku": "^7.39.0",
"jquery": "^3.4.1",
"mongoose": "^5.9.3",
"morgan": "^1.9.1",
"path": "^0.12.7",
"react-router-dom": "^5.1.2", //I MISTAKENLY INSTALLED IT.BUT I THINK IT SHOULD NOT BE A PROBLEM
"react-transition-group": "^4.3.0" //I MISTAKENLY INSTALLED IT. BUT I THINK IT SHOULD NOT BE A PROBLEM
}
}
This is React's package.json
{
"name": "client",
"version": "0.1.0",
"engines": {
"node": "13.10.1",
"npm": "6.13.7"
},
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.3.2",
"#testing-library/user-event": "^7.1.2",
"moment": "^2.24.0",
"react": "^16.13.0",
"react-dom": "^16.13.0",
"react-scripts": "3.4.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"proxy": "http://localhost:5000",
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
The ReferenceError you're seeing is caused by index.html not being wrapped in quotations - node is trying to evaluate the html property of an object named index which I'm willing to bet is not what you meant.
app.use(express.static(__dirname + "build")); //
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "build", index.html)); // <- try "index.html"
});
The probable reason why you getting this error is likely because you've added /build folder to your .gitignore file or generally haven't checked it into git. So when you git push heroku master, build folder you're referencing don't get push to heroku. And that's it shows this error.
T its work properly locally