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.
CodePudding user response:
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.
CodePudding user response:
The CSS showing as plain text may be caused by a wrong Content-type in the header. The browser is interpreting it as a plain text file, instead of handling it as CSS. Before you send the response, you can set response headers in your controller like:
res.header('Content-type', 'text/css');
See Express Docs
Hope this helps.
CodePudding user response:
Try putting your styles folder in public folder itself. For any static files or pages just put in the public folder. It kind of worked for me.