Handlebars with Express: different html head for different pages
This is a great question and, in my mind, a glaring weakness in Express's view model. Fortunately, there is a solution: use Handlebars block helpers. Here's the helper I use for this purpose:
helpers: { section: function(name, options){ if(!this._sections) this._sections = {}; this._sections[name] = options.fn(this); return null; }}
Then, in your layout, you can do the following:
<head> {{{_sections.head}}}</head><body> {{{body}}}</body>
And in your view:
{{#section 'head'}} <!-- stuff that goes in head...example: --> <meta name="robots" content="noindex">{{/section}}<h1>Body Blah Blah</h1><p>This goes in page body.</p>
You can make the follow:
layout.hbs
<head> <title>{{title}}</title> {{#each css}} <link rel="stylesheet" href="/css/{{this}}" /> {{/each}}</head>
app.js
router.get('/', function (req, res, next) { res.render('index', { title: 'MyApp', css: ['style.css', 'custom.css'] });});
Result:
<head> <title>MyApp</title> <link rel="stylesheet" href="/css/style.css" /> <link rel="stylesheet" href="/css/custom.css" /></head>
Maybe, you could use this implementation of the section helper: https://github.com/cyberxander90/express-handlebars-sections
You just need to install it and enable it:
yarn add express-handlebars-sections # or npm
const expressHandlebarsSections = require('express-handlebars-sections');app.engine('handlebars', expressHandlebars({ section: expressHandlebarsSections()}));
Hope it helps.
Younes