I have an app that I followed from a tutorial for the backend in nodeJS and Express. My connection to MongoDB via Mongoose is working. However, I’ve been trying to add a front-end- at the moment- just a simple html/ejs/css form. My endpoints are loading in localhost but only the html/ejs is rendering. My css file shows as plain code at http://localhost:3000/styles.css
but isn’t loading so I’m just getting plain html/ejs. I’m using VS Code. Here’s my relevant code:
App.js:
const express = require('express'); const bodyParser = require('body-parser'); const product = require('./routes/product.routes'); // Imports routes for the products const app = express(); var path = require('path'); const cors = require('cors'); app.set('views', __dirname + '/views'); app.set('view engine', 'ejs') app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false})); app.use(cors({ origin: '*' })); app.use(express.static(path.join(__dirname, '/public'))); app.use(express.static(path.join(__dirname, 'views'))); app.use("/styles", express.static(__dirname + '/styles')); app.use('/product', product); let port = 3000; app.listen(port, () => { console.log('Server is up and running on port number ' + port); });
Product.routes.js
const express = require('express'); const router = express.Router(); // Require the controllers WHICH WE DID NOT CREATE YET!! const product_controller = require('../controllers/product.controller'); // a simple test url to check that all of our files are communicating correctly. router.get('/', product_controller.start); router.get('/test', product_controller.test); router.post('/create', product_controller.product_create); router.get('/:book', product_controller.product_details); router.put('/:book/update', product_controller.product_update); router.delete('/:book/delete', product_controller.product_delete); module.exports = router;
Product.controller.js
const Product = require('../models/product.model'); //Simple version, without validation or sanitation exports.start = function (req, res) { res.sendFile('index.html', { root: './views' })} exports.test = function (req, res) { res.render('index.ejs', { root: './views' })}
Index.ejs
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>HTML 5 Boilerplate</title> <link rel="stylesheet" type="text/css" href='/public/styles.css'/> <base href="/"> </head> <body> <h1>BookBooker</h1> <h2>A library app for personal use.</h2> <form action="/create" method="POST"> <input type="text" placeholder="Writer" name="name" /> <input type="text" placeholder="Book" name="book" /> <button type="submit">Submit</button> </form> <script src="app.js" type="module" type='text/javascript'></script> </body> </html>
My file structure looks like:
CRUD folder -app.js -package.json -package-lock.json -controller folder --product.controller.js -public folder --styles.css -routes folder --product.routes.js -views folder --index.html --index.ejs
Apologies if it’s obvious- I’m super new to this. As you can see, I’ve tried static files, paths, CORS, and lots of combinations of file routing but I’m getting myself in a big muddle. I’ve considered caching but the css isn’t showing in Chrome, Edge or Incognito mode either. Any help would be appreciated.
Advertisement
Answer
Instead of
<link rel="stylesheet" type="text/css" href='/public/styles.css'/>
write
<link rel="stylesheet" type="text/css" href='/styles.css'/>
The public
folder name is not part of the stylesheet URL, it is just the folder where express.static
looks for files.