Search code examples
node.jsherokuelm

How to enable URL routing in Node and Elm application (Heroku)?


I have an elm application running on Heroku.

I didn't want to use a third party elm buildpack, so I compiled the elm files locally and pushed elm.js onto the Heroku server.

My application is using Node.js backend so I'm using this code in expresss to serve index.html:

if(process.env.NODE_ENV === 'production') {
  app.use(express.static('client'));

  app.get('*', (res:any) => {
    res.sendFile(path.resolve(__dirname, 'client', 'index.html'));
  });
}

I can go to the heroku URL and everything works perfectly. If I click on the internal /login link, I'm redirected to the login page and my url changes to ww.mywebsite.com/login. Internal routing is not my problem.

This is my problem: Although internal routing works, if I were to manually write www.mywebsite.com/login in the navigation bar, instead of seeing the login page, I see Internal Server Error

How do I fix this? Would I need a heroku buildback to accomplish this?


Solution

  • As @kaskelotti from the comments pointed out, Internal Server Error was printing because the files were being found, but another error was happening once they were found. If the files had not been found I would have received a 404 error.

    This was a syntax error in my express code that matched all requests with my static index.html file.

    The code posted in my question is wrong, THIS is how it should look:

    if(process.env.NODE_ENV === 'production') {
      app.use(express.static('client'));
    
      app.get('*', (req , res) => {
        res.sendFile(path.resolve(__dirname, 'client', 'index.html'));
      });
    }
    

    The difference is the argument to the callback function in app.get. Originally it was (res) instead of (req, res), so the res variable was mistaken for an object of type Request and not Response, since it was the first argument.

    Also as @kaskelotti pointed out, Heroku is irrelevant to this problem.