Jah M
Jah M

Reputation: 33

Express routes not working with Heroku deployment

I am trying to deploy a client/server application to heroku, using node as the server which serves an index.html via express.

After deploying to heroku, Express is not correctly routing the server to be able to find the index.html.

I get a '404: webpage not found' when I view the deployed project.

Project structure:

public
-- img
-- index.html
-- index.js
server
-- server.js

server.js

const express = require('express');
const app = express();
const path = require('path')
app.use(express.static(path.join(__dirname, '..', 'public')))

I even console log the path that I'm trying to use inside server.js, and I can see that the path is entered correctly. ex:

const fs = require('fs')
fs.readdirSync(path.join(__dirname , '..', 'public')).forEach(file => {
  console.log(file);
});

yields the output in my server logs:

img
index.html
index.js

Yet when I connect to the deployed server the following log:

heroku[router]: at=info method=GET path="/"

indicates that it is still routing to / instead of where express is telling it (/public)

Am i missing something important line in express?

Upvotes: 0

Views: 332

Answers (1)

Jah M
Jah M

Reputation: 33

Found the solution. The problem was that I was trying to use express and node with a socket.io server, and was not setting it up properly.

The first step was to update socket.io from v2.3 to v4.4:

/**
* package.json 
*/

// STEP 1

"dependencies": {
    "express": "^4.17.2",
    "socket.io": "^4.4.0",
    ...
}

The second step was to properly set up the server and routing with account for socket.io:

/**
* server.js
*/

// STEP 2

const PORT = process.env.PORT || 3000
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");

// this 'io' object is used to listen for client web-sockets, and links the
// server to a socket.io instance

 const io = new Server(server, {
   cors: {                       
     origin: "http://localhost:3000",
     methods: ["GET", "POST"]
   }
 })

// 'cors' is just whitelisting the client to get info from the server
// in prod, instead of localhost, it would be the deployed prod website url

The third and final step was to set the server to listen for client interaction:

/**
* server.js
*/

// STEP 3

 server.listen(PORT, () => {
   console.log(`Starting server on port ${PORT}`)
 })

The following changes fixed the server. Note that on the client side, I had to use the socket-client library provided by socket.io to connect to the server. Things worked after that.

Upvotes: 1

Related Questions