0

My app works locally. Routes work via postman and DB is being hit (As seen on Robo 3t). Heroku deploys the build only to show a blank page when the app is launched. Console show below: enter image description here

Below is my code:

Server.js

const express = require("express");
const app = express();
const path = require("path");
const mongoose = require("mongoose");
const routes = require("./routes");
const bodyParser = require("body-parser");
const cors = require ('cors');
require('dotenv').config()


const PORT = process.env.PORT || 3001;


// Connect to the Mongo DB
mongoose.connect(
    process.env.MONGODB_URI || "mongodb://localhost/sfwReactPortfolio",
    {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  // useCreateIndex: true,
  useFindAndModify: false
}
);



mongoose.set('useCreateIndex', true);

// mongoose.createConnection(
//   process.env.MONGODB_URI || "mongodb://localhost/sfwReactPortfolio", 
//   {   
//   useUnifiedTopology: true,
//   useNewUrlParser: true,
//   useFindAndModify: false,
// });

// /** */ const Book = mongoConnection.model('Book', bookSchema /*, 'COLLECTION_NAME'*/);

const mongoose_db = mongoose.connection;

// Define middlewares here for parsing req.body:
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cors());


// 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"));
}


// Currently serving static assets
app.use(express.static(path.join(__dirname, "public")));

// Add routes, both API and view
app.use(routes);

// // Verifies connection to db on desired port. 
mongoose_db.once("open", function() {
  app.listen(PORT, () => {console.log("Server Listening on Port", PORT)});
})

// // Throws error on failed db connection check. 
mongoose_db.on("error", function() {
  console.error("database failed to open");
})

Routes - index.js

const express = require("express");
const router = express.Router();
const nodemailer = require("nodemailer")
const ContactForm = require('../models/contactForm');

  router.post("/api/messages", (req,res)=>{
    let data = req.body
    let smtpTransport = nodemailer.createTransport({
      service:"Gmail",
      port:465,
      auth: {
        user:"sfwportfoliomessages@gmail.com",
        pass: "git4tm3!"
      }
    });
  
  let mailOptions = {
    from: data.email,
    to:"sfwportfoliomessages@gmail.com",
    subject: `Message from ${data.firstName}`,
    html:`
    <h3>Information</h3>
    <ul>
    <li>firstName: ${data.firstName}</li>
    <li>lastName: ${data.lastName}</li>
    <li>email: ${data.email}</li>
    </ul>
    <h3>Message</h3>
    <p>${data.message}</p>
  <p>${data.time}</p>
    `
  };
  
  smtpTransport.sendMail(mailOptions, (error, res)=>{
    if(error) {
      res.send(error)
    } else {
      res.send("Success")
    }
  })
  
  smtpTransport.close();

  ContactForm.create(req.body,
    function (err, response) {
      console.log(`response: ${response}`)
      if (err){
        console.log(err)
        return
      }
      res.json(response)
    }
  )
  })

   module.exports = router;

Model schema

const mongoose = require("mongoose");

const Schema = mongoose.Schema;

const ContactSchema = new Schema ({
    firstName: {type: Schema.Types.String},
    lastName: {type: Schema.Types.String},
    email: {type: Schema.Types.String},
    message: {type: Schema.Types.String},
    pubDate: {
        type: Schema.Types.Date,
        default: Date.now,
      },
})

const ContactFrom = mongoose.model("ContactForm", ContactSchema);

module.exports = ContactFrom;

Front end App.js

import React from 'react';
import {BrowserRouter as Router, Switch, Route} from "react-router-dom"
import Header from "../src/components/header"
import Footer from "../src/components/footer"
import Portfolio from "../src/pages/portfolio"
import About from "../src/pages/about"
import Contact from "../src/pages/contact"



function App() {
  return (
    <div className="App container-fluid container-sm">
      <Router>
      <Header/>
        <Switch>
          <Route exact path={["/about","/", "/hw-unit20-reactPortfolio"]}>
            <About />
          </Route>
          <Route  path="/contact">
            <Contact />
          </Route>
          <Route exact path="/portfolio">
            <Portfolio />
          </Route>
        </Switch>
    </Router>
      <Footer/>
    </div>
  );
}

export default App;

Manifest.json

    {
  "short_name": "React App",
  "name": "Create React App Sample",
  "start_url": "./index.html",
  "display": "standalone",
  
  "theme_color": "#000000",
  "background_color": "#ffffff"
}

Backend package.json

{
  "name": "hw-unit20-reactPortfolio",
  "version": "1.0.0",
  "engines": {
    "node": "12.x"
  },
  "description": "portfolio v4 created with REACT",
  "main": "server.js",
  "dependencies": {
    "body-parser": "^1.19.0",
    "concurrently": "^5.2.0",
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "if-env": "^1.0.4",
    "moment": "^2.27.0",
    "mongodb": "^3.5.9",
    "mongoose": "^5.9.19",
    "nodemailer": "^6.4.10",
    "nodemon": "^2.0.4",
    "path": "^0.12.7",
    "react-router": "^5.2.0",
    "react-router-dom": "^5.2.0"
  },
  "devDependencies": {},
  "scripts": {
    "start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
    "start:prod": "node server.js",
    "start: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",
    "heroku-postbuild": "npm run build"
  }
}

Client package.json

    {
  "name": "app",
  "homepage": "https://SpencerFalor-Ward.github.io/hw-unit20-reactPortfolio",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:3001/",
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "axios": "^0.19.2",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-router-dom": "^5.2.0",
    "react-scripts": "3.4.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "predeploy": "npm run build"
  },
  "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"
    ]
  }
}

index.html

<!DOCTYPE html>
<html lang="en-us">

    <!--Header containg site tab title, character set, link to CSS sheet-->
    <head>
        <meta charset="UTF-8">
        <!-- <link rel="stylesheet" type="text/css" href="../src/assets/css/reset.css"> -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
        <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
        <link rel="stylesheet" type="text/css" src="./assets/css/styles.css">
        <title>SFW Digital Buisiness Card</title>
    </head>

<body>
    <div id="root"></div>
</body>
</html>

File structure enter image description here

I appreciate any help here!

  • I can´t see if you added the manifest linked in the section of your html file. For more information look here: https://blog.heroku.com/how-to-make-progressive-web-app This might be the trick: https://stackoverflow.com/questions/55177518/manifest-json-unexpected-token Hope it works! – Philipp Jun 24 '20 at 20:48
  • Thank you, Philipp! I added the index.html code. I will look into the links. – Spencer Falor-Ward Jun 24 '20 at 21:48

1 Answers1

1

I found the answer! Using this guide https://coursework.vschool.io/deploying-mern-with-heroku/ led me to adding the following lines of code to my server.js:

app.use(express.static(path.join(__dirname, "client", "build")))

And within my already present

if (process.env.NODE_ENV === "production") {
  app.use("<git repo name>", express.static("client/build"));
  
}

I added

app.get("*", (req, res) => {
    res.sendfile(path.resolve(__dirname, "client", "build", "index.html"));
})

I also made sure to position the above "if....." code right before the code that contained my "app.listen...."

My repo is here:https://github.com/SpencerFalor-Ward/hw-unit20-reactPortfolio

Although I have had success with deploying MERN apps to Heroku before without the code used here, this time it was needed.