5

I created an ExpressJS app with handlebars templating engine and starting the app via npm start looks all good to me since all assets are being loaded.

Here's my folder structure:

- public
  - css
  - svg
  - uploads
- views
  - layouts
  > home.handlebars

And here's the relevant stuff of my index.js:

const express = require('express');
const exphbs = require('express-handlebars');
const path = require('path');
const fs = require('fs');
const port = 5000;
const index = express();


app.set('views', path.join(__dirname, '/', 'views'));
app.use(express.static(__dirname + '/public'));
app.engine('handlebars', exphbs({
    defaultLayout: 'main',
    layoutsDir: path.join(__dirname, '/', 'views', 'layouts')}
));
app.set('view engine', 'handlebars');

Here is the content of my now.json:

{
    "version": 2,
    "builds": [
        {
            "src": "index.js",
            "use": "@now/node-server"
        }
    ],
    "routes": [
        {
            "src": "/",
            "dest": "/",
            "methods": ["GET"]
        },
        {
            "src": "/justaroute",
            "dest": "/",
            "methods": ["POST"]
        }
    ]
}

The Problem

As I said above using npm start shows my working app but using now dev my app can't find any assets (display a 404 in the console): http://localhost:3000/css/icons.css net::ERR_ABORTED 404 (Not Found) http://localhost:3000/uploads/[...].jpg 404 (Not Found).

It seems that

app.set('views', path.join(__dirname, '/', 'views'));

is setting the views path as root for the assets the views are loading.

Inside the views I load assets like this:

<link rel="stylesheet" type="text/css" href="css/icons.css">

I already tried to add /public/[...] to the assets hrefs and getting the public folder explicitly by adding app.set('public', path.join(__dirname, '/', 'public')); which resulted in Chrome still not finding the assets: http://localhost:3000/public/css/icons.css net::ERR_ABORTED 404 (Not Found)

Tommy
  • 851
  • 9
  • 24
  • Stuck on the exact same issue. I'm trying to serve an archived version of my site with express as I want to from LAMP stack on my VPS to JAM stack. I have changed various paths in the index.html to see if that makes a difference Localhost not an issue, but when deployed to Zeit that is when the issue occurs. 404's on any static asset (image/stylesheet/js). Would love some help! Thanks – nford8 Jun 06 '20 at 18:18

1 Answers1

3

I managed to get this working for myself with the code below. You have to serve the assets folder in both the build and route in now.json. I was serving the file in node and did not have any issue 404, so I ended up confirming it was some sort of Zeit configuration issue.

If run this with "now dev" command, theres a good certainty it will work when deployed to production.

Nb. my assets folder is nested because this site will be archived when my new site is up and running, hence it being placed in the "archive" sub directory. Change this to whatever you suits your needs.

./index.js

var express = require('express');
var server = express();
server.use('/', express.static('/src/archive'));
server.listen(8080);

./now.json

{
  "version": 2,
  "builds": [
    {
      "src": "src/archive/**",
      "use": "@now/static"
    },
    {
      "src": "*.js",
      "use": "@now/node-server"
    }
  ],
  "routes": [
    {
      "src": "/",
      "dest": "src/archive/index.html"
    },
    {
      "src": "/(.+)",
      "dest": "src/archive/$1"
    }
  ]
}
nford8
  • 95
  • 1
  • 1
  • 8