[javascript] Render basic HTML view?

I have a basic node.js app that I am trying to get off the ground using Express framework. I have a views folder where I have an index.html file. But I receive the following error when loading the web browser.

Error: Cannot find module 'html'

Below is my code.

var express = require('express');
var app = express.createServer();

app.use(express.staticProvider(__dirname + '/public'));

app.get('/', function(req, res) {
    res.render('index.html');
});

app.listen(8080, '127.0.0.1')

What am I missing here?

This question is related to javascript html node.js mongodb express

The answer is


I added below 2 line and it work for me

    app.set('view engine', 'html');
    app.engine('html', require('ejs').renderFile);

I was trying to set up an angular app with an express RESTful API and landed on this page multiple times though it wasn't helpful. Here's what I found that worked:

app.configure(function() {
    app.use(express.static(__dirname + '/public'));         // set the static files location
    app.use(express.logger('dev'));                         // log every request to the console
    app.use(express.bodyParser());                          // pull information from html in POST
    app.use(express.methodOverride());                      // simulate DELETE and PUT
    app.use(express.favicon(__dirname + '/public/img/favicon.ico'));
});

Then in the callback for your api routes look like: res.jsonp(users);

Your client side framework can handle routing. Express is for serving the API.

My home route looks like this:

app.get('/*', function(req, res) {
    res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});

For my project I have created this structure:

index.js
css/
    reset.css
html/
    index.html

This code serves index.html for / requests, and reset.css for /css/reset.css requests. Simple enough, and the best part is that it automatically adds cache headers.

var express = require('express'),
    server = express();

server.configure(function () {
    server.use('/css', express.static(__dirname + '/css'));
    server.use(express.static(__dirname + '/html'));
});

server.listen(1337);

If you're using express@~3.0.0 change the line below from your example:

app.use(express.staticProvider(__dirname + '/public'));

to something like this:

app.set("view options", {layout: false});
app.use(express.static(__dirname + '/public'));

I made it as described on express api page and it works like charm. With that setup you don't have to write additional code so it becomes easy enough to use for your micro production or testing.

Full code listed below:

var express = require('express');
var app = express.createServer();

app.set("view options", {layout: false});
app.use(express.static(__dirname + '/public'));

app.get('/', function(req, res) {
    res.render('index.html');
});

app.listen(8080, '127.0.0.1')

Many of these answers are out of date.

Using express 3.0.0 and 3.1.0, the following works:

app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);

See the comments below for alternative syntax and caveats for express 3.4+:

app.set('view engine', 'ejs');

Then you can do something like:

app.get('/about', function (req, res)
{
    res.render('about.html');
});

This assumes you have your views in the views subfolder, and that you have installed the ejs node module. If not, run the following on a Node console:

npm install ejs --save

With Express 4.0.0, the only thing you have to do is comment out 2 lines in app.js:

/* app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade'); */ //or whatever the templating engine is.

And then drop your static file into the /public directory. Example: /public/index.html


You could also read the HTML file and send it:

app.get('/', (req, res) => {
    fs.readFile(__dirname + '/public/index.html', 'utf8', (err, text) => {
        res.send(text);
    });
});

I usually use this

app.configure(function() {
    app.use(express.static(__dirname + '/web'));
});

Just be careful because that'll share anything in the /web directory.

I hope it helps


try this. it works for me.

app.configure(function(){

  .....

  // disable layout
  app.set("view options", {layout: false});

  // make a custom html template
  app.register('.html', {
    compile: function(str, options){
      return function(locals){
        return str;
      };
    }
  });
});

....

app.get('/', function(req, res){
  res.render("index.html");
});

If you don't have to use the views directory, Simply move html files to the public directory below.

and then, add this line into app.configure instead of '/views'.

server.use(express.static(__dirname + '/public'));

I also faced the same issue in express 3.X and node 0.6.16. The above given solution will not work for latest version express 3.x. They removed the app.register method and added app.engine method. If you tried the above solution you may end up with the following error.

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
    at Function.<anonymous> (/home/user1/ArunKumar/firstExpress/app.js:37:5)
    at Function.configure (/home/user1/ArunKumar/firstExpress/node_modules/express/lib/application.js:399:61)
    at Object.<anonymous> (/home/user1/ArunKumar/firstExpress/app.js:22:5)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:31)
    at Function._load (module.js:308:12)
    at Array.0 (module.js:479:10)
    at EventEmitter._tickCallback (node.js:192:40)

To get rid of the error message. Add the following line to your app.configure function

app.engine('html', require('ejs').renderFile);

Note: you have to install ejs template engine

npm install -g ejs

Example:

app.configure(function(){

  .....

  // disable layout
  app.set("view options", {layout: false});

  app.engine('html', require('ejs').renderFile);

....

app.get('/', function(req, res){
  res.render("index.html");
});

Note: The simplest solution is to use ejs template as view engine. There you can write raw HTML in *.ejs view files.


Try res.sendFile() function in Express routes.

var express = require("express");
var app     = express();
var path    = require("path");


app.get('/',function(req,res){
  res.sendFile(path.join(__dirname+'/index.html'));
  //__dirname : It will resolve to your project folder.
});

app.get('/about',function(req,res){
  res.sendFile(path.join(__dirname+'/about.html'));
});

app.get('/sitemap',function(req,res){
  res.sendFile(path.join(__dirname+'/sitemap.html'));
});

app.listen(3000);

console.log("Running at Port 3000");

Read here : http://codeforgeek.com/2015/01/render-html-file-expressjs/


For plain html you don't require any npm package or middleware

just use this:

app.get('/', function(req, res) {
    res.sendFile('index.html');
});

if you are using express framework to node.js

install npm ejs

then add config file

app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router)

;

render the page from exports module form.js have the html file in the views dir with extension of ejs file name as form.html.ejs

then create the form.js

res.render('form.html.ejs');


From the Express.js Guide: View Rendering

View filenames take the form Express.ENGINE, where ENGINE is the name of the module that will be required. For example the view layout.ejs will tell the view system to require('ejs'), the module being loaded must export the method exports.render(str, options) to comply with Express, however app.register() can be used to map engines to file extensions, so that for example foo.html can be rendered by jade.

So either you create your own simple renderer or you just use jade:

 app.register('.html', require('jade'));

More about app.register.

Note that in Express 3, this method is renamed app.engine


Add the following Lines to your code

  1. Replace "jade" with "ejs" & "X.Y.Z"(version) with "*" in package.json file

      "dependencies": {
       "ejs": "*"
      }
    
  2. Then in your app.js File Add following Code :

    app.engine('html', require('ejs').renderFile);

    app.set('view engine', 'html');

  3. And Remember Keep All .HTML files in views Folder

Cheers :)


Express 4.x

Send .html files, no template engine...

//...
// Node modules
const path = require('path')
//...
// Set path to views directory
app.set('views', path.join(__dirname, 'views'))
/**
 * App routes
 */
app.get('/', (req, res) => {
  res.sendFile('index.html', { root: app.get('views') })
})
//...
.
+-- node_modules
¦
+-- views
¦   +--index.html
+-- app.js

index.js

var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));


app.get('/', function(req, res) {
    res.render('index.html');
});


app.listen(3400, () => {
    console.log('Server is running at port 3400');
})

Put your index.html file in public folder

<!DOCTYPE html>
<html>
<head>
    <title>Render index html file</title>
</head>
<body>
    <h1> I am from public/index.html </h1>
</body>
</html>

Now run the following code in your terminal

node index.js


It is very sad that it is about 2020 still express hasn't added a way to render an HTML page without using sendFile method of the response object. Using sendFile is not a problem but passing argument to it in the form of path.join(__dirname, 'relative/path/to/file') doesn't feel right. Why should a user join __dirname to the file path? It should be done by default. Why can't the root of the server be by defalut the project directory? Also, installing a templating dependency just to render a static HTML file is again not correct. I don't know the correct way to tackle the issue, but if I had to serve a static HTML, then I would do something like:

const PORT = 8154;

const express = require('express');
const app = express();

app.use(express.static('views'));

app.listen(PORT, () => {
    console.log(`Server is listening at port http://localhost:${PORT}`);
});

The above example assumes that the project structure has a views directory and the static HTML files are inside it. For example, let's say, the views directory has two HTML files named index.html and about.html, then to access them, we can visit: localhost:8153/index.html or just localhost:8153/ to load the index.html page and localhost:8153/about.html to load the about.html. We can use a similar approach to serve a react/angular app by storing the artifacts in the views directory or just using the default dist/<project-name> directory and configure it in the server js as follows:

app.use(express.static('dist/<project-name>'));

I wanted to allow requests to "/" to be handled by an Express route where previously they had been handled by the statics middleware. This would allow me to render the regular version of index.html or a version that loaded concatenated + minified JS and CSS, depending on application settings. Inspired by Andrew Homeyer's answer, I decided to drag my HTML files - unmodified - into a views folder, configure Express like so

   app.engine('html', swig.renderFile);
   app.set('view engine', 'html');
   app.set('views', __dirname + '/views');  

And created a route handler like so

 app.route('/')
        .get(function(req, res){
            if(config.useConcatendatedFiles){
                return res.render('index-dist');
            }
            res.render('index');       
        });

This worked out pretty well.


To render Html page in node try the following,

app.set('views', __dirname + '/views');

app.engine('html', require('ejs').renderFile);
  • You need to install ejs module through npm like:

       npm install ejs --save
    

res.sendFile(__dirname + '/public/login.html');

Here is a full file demo of express server!

https://gist.github.com/xgqfrms-GitHub/7697d5975bdffe8d474ac19ef906e906

hope it will help for you!

_x000D_
_x000D_
// simple express server for HTML pages!_x000D_
// ES6 style_x000D_
_x000D_
const express = require('express');_x000D_
const fs = require('fs');_x000D_
const hostname = '127.0.0.1';_x000D_
const port = 3000;_x000D_
const app = express();_x000D_
_x000D_
let cache = [];// Array is OK!_x000D_
cache[0] = fs.readFileSync( __dirname + '/index.html');_x000D_
cache[1] = fs.readFileSync( __dirname + '/views/testview.html');_x000D_
_x000D_
app.get('/', (req, res) => {_x000D_
    res.setHeader('Content-Type', 'text/html');_x000D_
    res.send( cache[0] );_x000D_
});_x000D_
_x000D_
app.get('/test', (req, res) => {_x000D_
    res.setHeader('Content-Type', 'text/html');_x000D_
    res.send( cache[1] );_x000D_
});_x000D_
_x000D_
app.listen(port, () => {_x000D_
    console.log(`_x000D_
        Server is running at http://${hostname}:${port}/ _x000D_
        Server hostname ${hostname} is listening on port ${port}!_x000D_
    `);_x000D_
});
_x000D_
_x000D_
_x000D_


If you are trying to serve an HTML file which ALREADY has all it's content inside it, then it does not need to be 'rendered', it just needs to be 'served'. Rendering is when you have the server update or inject content before the page is sent to the browser, and it requires additional dependencies like ejs, as the other answers show.

If you simply want to direct the browser to a file based on their request, you should use res.sendFile() like this:

const express = require('express');
const app = express();
var port = process.env.PORT || 3000; //Whichever port you want to run on
app.use(express.static('./folder_with_html')); //This ensures local references to cs and js files work

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/folder_with_html/index.html');
});

app.listen(port, () => console.log("lifted app; listening on port " + port));

This way you don't need additional dependencies besides express. If you just want to have the server send your already created html files, the above is a very lightweight way to do so.



1) The best way is to set static folder. In your main file (app.js | server.js | ???):

app.use(express.static(path.join(__dirname, 'public')));

public/css/form.html
public/css/style.css

Then you got static file from "public" folder:

http://YOUR_DOMAIN/form.html
http://YOUR_DOMAIN/css/style.css

2)

You can create your file cache.
Use method fs.readFileSync

var cache = {};
cache["index.html"] = fs.readFileSync( __dirname + '/public/form.html');

app.get('/', function(req, res){    
    res.setHeader('Content-Type', 'text/html');
    res.send( cache["index.html"] );                                
};);

I didn't want to depend on ejs for simply delivering an HTML file, so I simply wrote the tiny renderer myself:

const Promise = require( "bluebird" );
const fs      = Promise.promisifyAll( require( "fs" ) );

app.set( "view engine", "html" );
app.engine( ".html", ( filename, request, done ) => {
    fs.readFileAsync( filename, "utf-8" )
        .then( html => done( null, html ) )
        .catch( done );
} );

If you want to render HTML file you can use sendFile() method without using any template engine

const express =  require("express")
const path = require("path")
const app = express()
app.get("/",(req,res)=>{
    res.sendFile(**path.join(__dirname, 'htmlfiles\\index.html')**)
})
app.listen(8000,()=>{
    console.log("server is running at Port 8000");
})

I have an HTML file inside htmlfile so I used path module to render index.html path is default module in node. if your file is present in root folder just used

res.sendFile(path.join(__dirname, 'htmlfiles\\index.html'))

inside app.get() it will work


folder structure:

.
+-- index.html
+-- node_modules
¦   +--{...}
+-- server.js

server.js

var express = require('express');
var app = express();

app.use(express.static('./'));

app.get('/', function(req, res) {
    res.render('index.html');
});

app.listen(8882, '127.0.0.1')

index.html

<!DOCTYPE html>
<html>
<body>

<div> hello world </div>

</body>
</html>

output:

hello world


app.get('/', function (req, res) {
res.sendfile(__dirname + '/public/index.html');
});

In server.js, please include

var express = require("express");
var app     = express();
var path    = require("path");


app.get('/',function(req,res){
  res.sendFile(path.join(__dirname+'/index.html'));
  //__dirname : It will resolve to your project folder.
});

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to mongodb

Server Discovery And Monitoring engine is deprecated Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017] Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified Failed to start mongod.service: Unit mongod.service not found db.collection is not a function when using MongoClient v3.0 MongoError: connect ECONNREFUSED 127.0.0.1:27017 MongoDB: How To Delete All Records Of A Collection in MongoDB Shell? How to resolve Nodejs: Error: ENOENT: no such file or directory How to create a DB for MongoDB container on start up?

Examples related to express

UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block jwt check if token expired Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017] npm notice created a lockfile as package-lock.json. You should commit this file Make Axios send cookies in its requests automatically What does body-parser do with express? SyntaxError: Unexpected token function - Async Await Nodejs Route.get() requires callback functions but got a "object Undefined" How to redirect to another page in node.js