I have an express app that renders Mustache templates. On one of my routes, the template renders just fine, but on another one, the CSS refuses to apply because it's of the MIME type text/html (says Chrome console).
Here is how I configure my express app:
const app = express();
app.use(express.static(__dirname + '/public'));
app.use(
cookieSession({
maxAge: 30 * 24 * 60 * 60 * 1000,
keys: [
process.env.COOKIE_KEY_1,
process.env.COOKIE_KEY_2,
process.env.COOKIE_KEY_3
]
})
);
app.use(passport.initialize());
app.use(passport.session());
app.engine('mst', mustacheExpress(__dirname + '/views/partials', '.mst'));
app.set('views', __dirname + '/views', '.mst');
app.set('view engine', 'mst');
Here are the routes. '/' serves the CSS just fine, but the MIME type error appears with '/user/profile'.
app.get('/', (req, res) => {
res.render('home', {
user: req.user,
title: 'Home'
});
});
app.get('/user/profile', (req, res) => {
res.render('profile', {
user: req.user,
title: 'Profile'
});
});
And here is Mustache partial I use as a header. This is where I call the CSS. Note that the Bootstrap CSS works fine. The problem I have concerns both styles.css and login.css.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{{title}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/styles.css">
{{#login}}
<link rel="stylesheet" type="text/css" href="css/login.css">
{{/login}}
</head>
<body>
<header>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="/">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ml-auto">
{{#user}}
<li class="nav-item dropdown" id="header__dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{user.name}}
<img class="user__pic" src="{{user.pic}}" alt="Profile picture" />
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/user/profile">Profile</a>
<a class="dropdown-item" href="/user/settings">Settings</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/logout">Logout</a>
</div>
</li>
{{/user}}
{{^user}}
{{^login}}
<li class="nav-item">
<a href="/login" class="btn btn-outline-secondary" role="button">Login</a>
<a href="/login" class="btn btn-danger" role="button">Sign up</a>
</li>
{{/login}}
{{/user}}
</ul>
</div>
</nav>
</header>
I've tried a few things, like deleting node_modules and reinstalling, but in the end I just don't get it. I can't seem to find the difference in the way I declare those routes. Any help would be much appreciated!
Thanks
OK I found the solution. In my HTML header, I'm calling CSS files using the 'css/styles.css' string, so the server will follow that route not from the root of the server, but from the URL of the followed route.
So for my home route ('/'), it works fine, the server looks for '/css/styles.css', but for my profile route ('/user/profile'), it was looking for '/user/css/styles.css'.
Therefore the solution was to call the CSS in my HTML header with an absolute path rather than a relative. '/css/styles.css' instead of 'css/styles.css'.