Getting Started with express.js, serving a dynamic HTML - node.js

I'm writing a single page web application using node.js and express. After going through some online tutorials, I found out this is how express.js serves a client directory with HTML, javascript and css
app.use(express.static(__dirname + '/public'));
This works great except the fact that public directory has to have .html root file which is static. I'd like to know how can I serve a dynamic HTML file with this same approach.
I want to insert some data into the page for example "Hello user_name" at the top. How do I do that for this single file.
I want to only do it once, at the startup, after that my application will make rest API calls and get plain JSON responses which it will then put it in the page.

You cannot use the express static server to serve dynamic files as far as I'm aware. In order to serve a dynamic HTML you need to use a templating engine, such as jade or any of these templating engines.
Jade is pretty straightforward to use and is supported by express by default. To set up jade, include the following lines in your app configuration block:
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
The first line sets your views directory - from which the template files would be served. Since you want to serve only an index file, this directory would contain your index.jade template. The second line sets jade as the templating engine.
Now, instead of using the static server to serve the index.html, you need to create a get route '/' to serve the index file, like so:
app.get('/', function(req, res) {
res.render('index', {user_name: username});
});

Related

Express NodeJS Cannot find module 'html'

I have a Node Server with Express. I get the cannot find module 'html' error even though my code looks like this and should be correct in my opinion:
app.set('views', path.join(__dirname, 'build/views'));
app.use(favicon(path.join(__dirname, "build/favicon.ico")));
app.use('/scripts', express.static(path.join(__dirname, 'node_modules')));
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function(req, res){
res.render('index.html');
});
You have to set engine for HTML
Include this code in your main file
var engines = require('consolidate');
app.engine('html', engines.mustache);
app.set('view engine', 'html');
If you only want to serve a static file without passing any variables from the server to the client the easiest solution would be:
res.sendFile(path.join(__dirname + '/build/views/index.html'));
Especially when you are using AngularJS for the client side. The problem with the solution above is that mustache uses {{}} as variables recognition. So does AngularJS which might causes errors!
It seems that you are trying to display a static index.html file but you serve it as if it was a template. Probably Express is trying to find a module for html template format, which doesn't exist.
You may try to send the index as a static file instead of with res.render which is for rendering templates.
Some time ago I wrote an example of serving static files with Express. It's available on GitHub:
https://github.com/rsp/node-express-static-example
See also my other answer, where I explain it in more detail.

Structuring a MEAN app so Express can find all the Jade files

I am building out a MEAN app right now that is getting big. I really need to start modularizing the app but right now my Express server is configured to look for Jade views in one folder
app.set('views', path.join(__dirname, '/app/views'));
app.set('view engine', 'jade');
The authors of these posts show the view files scattered about the app in the different module directories.
https://blog.safaribooksonline.com/2014/03/27/13-step-guide-angularjs-modularization/
http://www.johnpapa.net/angular-app-structuring-guidelines/
If I try to do this now, my Express server will not be able to see them. How can I make it so Express will be able to find all the Jade views?
Two solutions :
You can use a base folder named views and create subfolders inside views.
For example, views/menu/, views/header/. To use this, you have to
declare a basedir in Express so Jade will know where to look your
views, by doing app.locals.basedir = __dirname + "/views";. Then,
in your Jade file, use include /header/a.jade, include
/menu/item1.jade etc...
Use Express App submounting feature. This allows you to modularize
your main app into small apps, which all have their own routes, views
etc... You can watch this nice video tutorial by TJ
Holowaychuk to learn more about this.
Does that help you ?
I just start using module prefixes in my render calls and set my views base directory to be the parent directory of my modules. So if I started with:
app/views/page1.jade
app/views/page2.jade
and was doing res.render("page1"), I reorganize to:
app/module1/page1.jade
app/module2/page2.jade
and I do app.set("views", "app") then render with res.render("module1/page1").

expressjs - not sending the file from view config

In my node app, I configured the views folder, later simply I am passing the html name alone. now the html file need to load from using the views config + html file right. ( am I wrong!)
But it's not working. any one give me the suggestion please?
here is my code :
var express = require('express'),
http = require('http'),
jade = require('jade'),
app = express();
app.set('view engine', 'jade');
app.set('views', __dirname + '/views'); // i configured the path so i am passing file name alone on get.
app.get('/', function(req,res){
res.sendfile('index.html'); //it's not working
res.sendfile('views/index.html') //it works
});
http.createServer(app).listen(3000, function () {
console.log('Express server listening on port ');
});
thanks in advance
You appear to have a misconception about what the view engine is. The view engine takes some non-HTML code, and transforms it into HTML. Here, you have it set to use jade.
The view engine is only good with the res.render() function. res.sendfile() merely sends a file from the current directory -- not the views directory.
Using express if you want to serve some static HTML files. You can just put those files directly in public folder.
When server will get a GET request of / it will search for /public/index.html serve that as response. You don't have to add router for that /.
Other wise if you want to use some template views then you have to use some views engine.

Using holder.js on node.js with express web framework does work

I am using node.js with express web framework and with jade template parser.
I am following the bootstrap examples and have problems with holder.js.
I have put holder.js script into static files (public directory), having in app.js the following:
app.use(express.static(path.join(__dirname, 'public')));
I wanted to display some images with following code in jade template:
img(data-src='/holder.js/500x500/auto')
And it does not work. I checked through the browser and I am able to see holder.js file correctly, but adding any parameters is causing that main page is displayed instead.
I am suspecting that static files handler thinks that there is no such file as holder/500x500/auto and redirects to main page. How can I fix that?
Here is a Runnable with Express and Jade with a couple of Holder placeholders: http://runnable.com/U6IlNqsTu-cR6ZT8/holder-js-in-express-using-jade-for-node-js-and-hello-world
The two placeholders use different themes, with one using the auto flag.
server.js:
var express = require('express')
var app = express();
app.set('view engine', 'jade')
app.get('/', function(req, res){
res.render('index')
})
var server = app.listen(80, function(){})
views/index.jade:
doctype html
html
body
script(src='//cdnjs.cloudflare.com/ajax/libs/holder/2.3.1/holder.min.js')
img(data-src='holder.js/200x200/lava/auto')
img(data-src='holder.js/200x200/sky')
Take the leading slash out of the data-src attribute: holder.js/500x500/auto.

Automatically rendering jade file as if it was an html file?

I can't find an answer to this, despite it seeming rather useful.
I would like to host a site using node.js to serve compiled jade files instead of html files. Currently, I'm using:
app.get('/', function(req, res) {
app.use(express.static(__dirname));
});
How can I get it to find page.jade when someone types in domain.com/page? And furthermore, could I write links that way in the jade file (so a(href='page') link would link to the aforementioned page)?
Set your path as
app.get('/:pageName')
// more code
// then
res.render(req.params.pageName+'.jade')
req.params will contain the last part in property name pageName
Express has a number of possible options for what it calls a "view engine". In order to have it process jade files and serve them as html you must configure it to do so.
One of the easiest ways to do this, if you are starting fresh, is to simply create your project using the express command as mentioned in their guide. The default views engine is jade and the following command sets stylus as the css processor:
express --css stylus myapp
If, instead, you are configuring your own server you need to configure the views engine:
app.configure(function(){
app.set('views', path.join(staticDir,'views'));
app.set('view engine', 'jade');
... the rest of your setup ...
}

Resources