Categories
Express JavaScript Vue

Guide to the Express Request Object — Queries and Cookies

The request object lets us get the information about requests made from the client in middlewares and route handlers.

In this article, we’ll look at the properties of Express’s request object in detail, including query strings, URL parameters, and signed cookies.

Request Object

The req parameter we have in the route handlers above is the req object.

It has some properties that we can use to get data about the request that’s made from the client-side. The more important ones are listed below.

req.originalUrl

The originalUrl property has the original request URL.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {  
  res.send(req.originalUrl);  
})
app.listen(3000);

Then when we have the request with query string /?foo=bar , we get back /?foo=bar .

req.params

params property has the request parameters from the URL.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

app.get('/:name/:age', (req, res) => {  
  res.json(req.params)  
})

app.listen(3000, () => console.log('server started'));

Then when we pass in /john/1 as the parameter part of the URL, then we get:

{  
    "name": "john",  
    "age": "1"  
}

as the response from the route above.

req.path

The path property has the path part of the request URL.

For instance, if we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();

app.get('/:name/:age', (req, res) => {  
  res.send(req.path);  
})

app.listen(3000);

and make a request to /foo/1 , then we get back the same thing in the response.

req.protocol

We can get the protocol string with the protocol property.

For example, if we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {  
  res.send(req.protocol);  
})

app.listen(3000);

Then when we make a request through HTTP we get backhttp .

req.query

The query property gets us the query string from the request URL parsed into an object.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.json(req.query)  
})

app.listen(3000, () => console.log('server started'));

Then when we append ?name=john&age=1 to the end of the hostname, then we get back:

{  
    "name": "john",  
    "age": "1"  
}

from the response.

req.route

We get the current matched route with the route property.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();

app.get('/', (req, res) => {  
  console.log(req.route);  
  res.json(req.route);  
})

app.listen(3000);

Then we get something like the following from the console.log :

Route {  
  path: '/',  
  stack:  
   [ Layer {  
       handle: [Function],  
       name: '<anonymous>',  
       params: undefined,  
       path: undefined,  
       keys: [],  
       regexp: /^\/?$/i,  
       method: 'get' } ],  
  methods: { get: true } }

req.secure

A boolean property that indicates if the request is made with via HTTPS.

For example, given that we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.get('/', (req, res) => {    
  res.json(req.secure);  
})

app.listen(3000);

Then we get false if the request is made via HTTP.

req.signedCookies

The signedCookies object has the cookie with the value deciphers from the hashed value.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const cookieParser = require('cookie-parser');  
const app = express();  
app.use(cookieParser('secret'));
app.get('/cookie', (req, res, next) => {  
  res.cookie('name', 'foo', { signed: true })  
  res.send();  
})

app.get('/', (req, res) => {  
  res.send(req.signedCookies.name);  
})

app.listen(3000);

In the code above, we have the /cookie route to send the cookie from our app to the client. Then we can get the value from the client and then make a request to the / route with the Cookie header with name as the key and the signed value from the /cookie route as the value.

For example, it would look something like:

name=s%3Afoo.dzukRpPHVT1u4g9h6l0nV6mk9KRNKEGuTpW1LkzWLbQ

Then we get back foo from the / route after the signed cookie is decoded.

req.stale

stale is the opposite of fresh . See [req.fresh](https://expressjs.com/en/4x/api.html#req.fresh) for more details.

req.subdomains

We can get an array of subdomains in the domain name of the request with the subdomains property.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();

app.get('/', (req, res) => {  
  res.send(req.subdomains);  
})

app.listen(3000);

Then when we make a request to the / route, we get something like:

["beautifulanxiousflatassembler--five-nine"]

req.xhr

A boolean property that’s true is X-Requested-With request header field is XMLHttpRequest .

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();

app.get('/', (req, res) => {  
  res.send(req.xhr);  
})

app.listen(3000);

Then when we make a request to the/ route with the X-Requested-With header set to XMLHttpRequest , we get back true .

Conclusion

There’re many properties in the request object to get many things.

We can get signed cookies with the Cookie Parser middleware. Query strings and URL parameters can access in various form with query , params , and route properties.

Also, we can get parts of the subdomain with the subdomains property.

Categories
Express JavaScript Nodejs

More About Routing with Express

Routing is the most important part of a back end application. Express allows us to route URLs to our route handler code easily.

In this article, we’ll look at how to create different kinds of routes with Express.

Handling All Requests

We can use the app.all method to handle all request methods. To use it, we can write something like the following:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.all('*', (req, res, next) => {  
  console.log('route called');  
  next();  
})

app.get('/', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

The app.all call above will be invoked when any method or URL is sent. It’ll log 'route called' and then call next to call the specific route handler for that route.

Non-Letter Symbols

Express can match routes with non-letter symbols. For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/foo.bar', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then when we make a GET request to foo.bar then we get hi .

Special Characters

Optional Character

If the ? is in a URL path, then it’s considered an optional character. For example, ab?c matches ac or abc .

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab?c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then when we make a request to /ac or /abc , we get hi .

One or More Character

If a URL has a + sign, then it’ll match one or more of the character preceding it.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab+c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then when making a request to /abc , /abbc , /abbbc and so on, we’ll get hi .

Wildcard

The * in the URL is a wildcard character.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab\*c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Then we put anything between ab and c in the URL and get the hi response.

Optional Character Group

A character group is optional if it’s surrounded by parentheses and has a ? after it.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab(cd)?ef', (req, res) => {  
  res.send('hi');  
})
app.listen(3000, () => console.log('server started'));

Then when we go to /abcdef or /abef , we get hi .

Regular Expressions

We can also use regular expressions as route paths. For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get(/\/a/, (req, res) => {  
  res.send('hi');  
})
app.listen(3000, () => console.log('server started'));

Then when we make a request to /a , we get hi .

To get hi when we make any request with path that ends with foo , we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get(/\/.\*foo$/, (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));

Route Parameters

We can designate parameters by writing a colon before the key name of the parameter.

For example, we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/:name/:age', (req, res) => {  
  res.send(req.params);  
})

app.listen(3000, () => console.log('server started'));

Then we get the following response:

{"name":"Mary","age":"10"}

:name and :age are interpreted as route placeholders. req.params will use them as the keys without the colon. Then whatever is set in the place of the placeholders will be the corresponding values.

Route Handlers

The callback in the second argument of the app.get above are route handlers. The same can be done for POST, PUT and DELETE requests by replacing app.get with app.post , app.put and app.delete respectively.

We can chain multiple handlers together with the next function. For example, we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/',  
  (req, res, next) => {  
    console.log('handler 1 called');  
    next()  
  },  
  (req, res) => {  
    console.log('handler 2 called');  
    res.send();  
  })

app.listen(3000, () => console.log('server started'));

Then we should see:

handler 1 called  
handler 2 called

in the console.log output.

We call the next function which originates from the route handler’s parameter to call the next route handler function.

Conclusion

Routing with Express is simple. We can use strings or regular expressions to specify our route paths.

Some characters in string paths like ? , +, or * are special characters for paths with optional characters or wildcards.

Placeholders for route parameters are specified by using a colon in front of the placeholder name.

We call next to chain multiple route handlers together.

Categories
Express JavaScript Nodejs

More About the Express Application Object

The core part of an Express app is the Application object. It’s the application itself.

In this article, we’ll look at the methods of the app object and what we can do with it.

Methods

app.disabled(name)

The method returns true if the given setting is disabled.

For example, if we have:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));

app.disable('foo');

app.get('/', function (req, res, next) {  
  res.json({ fooDisabled: app.disabled('foo') });  
})

app.listen(3000, () => console.log('server started'));

Then we get:

{"fooDisabled":true}

since we called app.disable(‘foo’);

On the other hand, if we called app.enable(‘foo’); then we get:

{"fooDisabled":false}

app.enable(name)

We can use enable to set the setting with the given name to true .

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));

app.enable('foo');

app.get('/', function (req, res, next) {  
  res.json({ fooDisabled: app.disabled('foo') });  
})

app.listen(3000, () => console.log('server started'));

Then we get:

{"fooDisabled":false}

since we called enable with 'foo' passed in.

app.enabled(name)

The enabled method returns if a setting with the given name is enabled. For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.enable('foo');
app.get('/', function (req, res, next) {  
  res.json({ fooDisabled: app.enabled('foo') });  
})

app.listen(3000, () => console.log('server started'));

Then we get {“fooDisabled”:true} since we called app.enable(‘foo’); .

app.engine(ext, callback)

We call the engine method to set the template engine that we use to render our HTML output.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('views', './views');

app.get('/', (req, res, next) => {  
  res.render('index', { people: ['geddy', 'neil', 'alex'] })  
})

app.engine('html', require('ejs').renderFile);  
app.set('view engine', 'ejs');  
app.listen(3000, () => console.log('server started'));

Then we can add our template to views/index.ejs as follows:

<%= people.join(", "); %>

and we get:

geddy, neil, alex

displayed.

The callback should have the parameters, path , options , and callback .

app.get(name)

We can use the get method to get the value of a setting with the given name.

For example, if we have:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('title', 'Foo');
app.get('/', (req, res, next) => {  
  res.send(app.get('title'));  
})

app.listen(3000, () => console.log('server started'));

Then we get Foo displayed since we called:

app.set('title', 'Foo');

app.get(path, callback [, callback …])

The get method lets us pass in a route handler callback or a series of them to handle get requests with the given path .

It takes the following arguments:

  • path — it can be a string or regex representing paths or patterns of paths. The default is / .
  • callback — a function to handle requests. It can be a middleware function, a series of them, array of them, or a combination of all of the above

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('title', 'Foo')
app.get('/', (req, res, next) => {  
  res.send('GET request made');  
})
app.listen(3000, () => console.log('server started'));

app.listen(path, [callback])

It starts a UNIX socket and listens to connects on the given path.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));  
app.set('title', 'Foo')app.get('/', (req, res, next) => {  
  res.send('hi');  
})

app.listen('/tmp/sock');

Then when the /tmp/sock socket isn’t in use, we can start our app by listening to this socket.

app.listen([port[, host[, backlog]][, callback])

This listen method listens for connects on the given host and port.

If the port is omitted or it’s 0, then the operating system will assign an arbitrary port for it to listen to.

We can pass the Express app object to the http.createServer to listen to connections as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const http = require('http');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res, next) => {  
  res.send('hi');  
})

http.createServer(app).listen(3000);

This lets us easily provide both an HTTP and HTTPS version of the app with the same code base.

app is actually a function so we can pass it into http.createServer as a callback.

app.listen() returns an http.Server object and it’s a convenience method for the following:

app.listen = function () {  
  const server = http.createServer(this)  
  return server.listen.apply(server, arguments)  
}

So we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const http = require('http');  
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res, next) => {  
  res.send('hi');  
})

app.listen = function () {  
  const server = http.createServer(this)  
  return server.listen.apply(server, arguments)  
}

app.listen(3000);

Conclusion

We can check is a setting is set to false with the disabled method.

To process GET requests, we can use the get method. It takes a route path and one or more route handler callbacks.

Finally, we have the listen method to listen for connections from UNIX sockets or given host and port. app can be passed into Node.js’ http.createServer method as a callback function since app is actually a function.

Categories
Express JavaScript Nodejs

Using Express Middleware

Middleware functions are functions that have access to the request and response objects, and the next function for call the next middleware.

In this article, we’ll look at what Express middleware does and how we can use them.

Characteristics of Middleware

Middleware functions can run any code, make changes to the request and response object, end the request-response cycle, and call the next middleware in the stack.

Application-Level Middleware

We can run middleware that are used when any routes are called by passing it to the app.use method as a callback.

If we want to a middleware function to be called only when a request of one request method is called, then we can pass it to the app.METHOD method as a callback. Where METHOD is get , post , put , delete , etc.

For example, we can write a middleware function and pass it into app.use to log the request method of a request as follows:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.use((req, res, next) => {  
  console.log(req.method);  
  next();  
});

app.get('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));

Then we should get GET logged when we make a GET request to / .

We can restrict the middleware function to be run only on GET requests and to the path / by writing:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  console.log(req.method);  
  next();  
});

app.get('/', (req, res) => {  
  res.json();  
})

app.post('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));

Then we only see GET logged when we make GET requests to the / path.

Running a Series of Middleware Functions

We can use the next method to call the next middleware function in the series, so we can use it to chain middleware function calls together.

For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.use(  
  (req, res, next) => {  
    console.log('middleware 1 called');  
    next();  
  },  
  (req, res, next) => {  
    console.log('middleware 2 called');  
    next();  
  }  
);

app.get('/', (req, res) => {  
  res.json();  
})

app.listen(3000, () => console.log('server started'));

Then we see:

middleware 1 called  
middleware 2 called

from the console.log output of each middleware.

If we send a response in our middleware, then the next one won’t get called. For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.get('/',  
  (req, res, next) => {  
    next()  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

app.get('/',  (req, res, next) => {  
  res.end();  
})

app.listen(3000, () => console.log('server started'));

Then we get the output ‘Second middleware’ when we make a request to / .

Our route handler in:

app.get('/', function (req, res, next) {  
  res.end();  
})

wasn’t called.

We can call next as follows:

next('route');

to go straight to our route handler, bypassing the other middleware functions down the line.

For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.get('/:id',  
  (req, res, next) => {  
    if (req.params.id === '0') {  
      next('route');  
      return;  
    }  
    next();  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

app.get('/:id', (req, res, next) => {  
  res.end(req.params.id);  
})

app.listen(3000, () => console.log('server started'));

Then when we make a request to /0 , then we get 0 . Otherwise, we get ‘Second Middleware’ outputted.

Router Level Middleware

Router level middleware works the same way as app-level middleware, but they’re bound to the instance of the express.Router() instead of the express instance.

For example, we can use it as follows:

const express = require('express')  
const app = express()  
const router = express.Router();
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.use((req, res, next) => {  
  req.requestTime = new Date();  
  next();  
})

router.get('/', (req, res, next) => {  
  res.json(req.requestTime);  
})

app.use('/', router);

app.listen(3000, () => console.log('server started'));

Then when we make a request to the / route we get back the timestamp as the output.

Chaining middlewares and skipping routes work the same way as app-level middleware. For example, we can write the following to chain middlewares as follows:

const express = require('express')  
const app = express()  
const router = express.Router();

app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.use(  
  (req, res, next) => {  
    console.log('middleware 1 called');  
    next();  
  },  
  (req, res, next) => {  
    console.log('middleware 2 called');  
    next();  
  }  
)

router.get('/', (req, res, next) => {  
  res.json();  
})

app.use('/', router);

app.listen(3000, () => console.log('server started'));

Then we see:

middleware 1 called  
middleware 2 called

from the console.log output of each route middleware.

We can use next('route') to skip to the route as follows:

const express = require('express')  
const app = express()  
const router = express.Router();
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))

router.get('/:id',  
  (req, res, next) => {  
    if (req.params.id === '0') {  
      next('route');  
      return;  
    }  
    next();  
  },  
  (req, res, next) => {  
    res.send('Second middleware');  
  }  
)

router.get('/:id', (req, res, next) => {  
  res.end(req.params.id);  
})

app.use('/', router);
app.listen(3000, () => console.log('server started'));

Then when we make a request to /0 , then we get 0 . Otherwise, we get ‘Second Middleware’ outputted.

Conclusion

Using Express middlewares is simple. We can either pass them into app.use to make the middleware run for all request methods, or app.METHOD to make them run for the given method.

We can call next to call the next middleware, and call next('route') to call the route handler directly from a middleware.

Everything applies to both route and app-level middleware, except that they bind to the express.Router() and express() respectively.

Categories
Express JavaScript Nodejs

Using Template Engines with Express

To render an HTML response with an Express route, we should return it as a template with the variable interpolated rather than return it directly as an HTML string.

Templates are convenient and we can use them in a much more flexible way than HTML strings.

In this article, we’ll look at how to set the template engine of our app, and returning HTML responses.

Choosing Template Engines

We can use popular template engines with Express, like Pug, Mustache, and EJS. The default for the Express application generator is Jade, but we can use the other ones listed as well.

To render template files, we can set the application settings. To set the templates folder, we can set the views property by writing the following:

app.set('views', './views')

It’ll set the templates folder to the views directory of our app.

Also, we can set the view engine we want to use by setting the view engine property as follows:

app.set('view engine', 'pug')

To install the template engine library, we can run something like the following:

npm install pug --save

The command above will install pug view engine for us to use.

Rendering Items with Template Engines

We can use the res.render method to render our variables to our templates.

First, we create the views folder to store our templates as we set the ./views folder to be our templates folder.

Since we chose to use Pug as our template engine, the template files should have the .pug extension.

Inside the views folder, create an index.pug and then put:

html  
  head  
    title= title  
  body  
    h1= message

The title= and h1= are our tags and title and message are keys in which Express will use to get the values from in the object that we’ll pass to res.render .

Then we can create index.js in the same level as the views folder and add:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.set('views', './views');  
app.set('view engine', 'pug');

app.get('/', (req, res, next) => {  
  res.render('index', { pageTitle: 'Hello', pageMessage: 'Hello there!' });  
})

app.listen(3000, () => console.log('server started'));

In the code above, we called res.render to render an HTML response. The object:

{ pageTitle: 'Hello', pageMessage: 'Hello there!' }

will be passed to our index.pug template.

title will be the title in:

html  
  head  
    title= pageTitle  
  body  
    h1= pageMessage

message will be replaced by the 'Hello there!' . Anything right of the tag and the equal sign will be replaced by the value with the key given above.

In other words, pageTitle and pageMessage properties’ values’ are the ones that’ll go in between the title and h1 tags respectively.

So we get

and the title of our page will be 'Hello' .

Pug Syntax

We can have dynamic expressions other than variables. Loops and conditional expressions are part of Pug.

HTML Tags

Other HTML tags can be used with Pug.

For example, a link can be written as follows:

a(href='http://medium.com') Medium

In the code above Medium goes between the a tags and href=’http://medium.com' is the href attribute and value respectively.

Loops

We can also write loops with Pug. For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.set('views', './views');  
app.set('view engine', 'pug');

app.get('/', (req, res, next) => {  
  res.render('index', { pageTitle: 'Hello', pageMessages: ['Hi', 'Bye'] });  
})

app.listen(3000, () => console.log('server started'));

in index.js and:

html  
  head  
    title= pageTitle  
  body  
    ul  
      each pageMessage in pageMessages  
        li= pageMessage

in views/index.pug , then we would get:

Conditionals

We can also add conditional expressions to our Pug template. For example, if we have:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))  
app.set('views', './views');  
app.set('view engine', 'pug');

app.get('/', (req, res, next) => {  
  res.render('index', { pageTitle: 'Hello', user: { type: 'member' }   });  
})  
app.listen(3000, () => console.log('server started'));

in index.js and:

html  
  head  
    title= pageTitle  
  body  
    if user.type === 'anonymous'  
      p User type is anonyomous  
    else if user.type === 'member'  
      p User type is member  
    else  
      p User type is admin

in views/index.pug , then we get:

'User type is member'

since user.type in res.render is set to 'member' .

Conclusion

Rendering HTML response is easy if we use a template engine to do it. We can pass in an object in the second argument of res.render to pass in values that we want to display in the template.

With template engines, we can include loops, conditionals, and variables to make displaying dynamic content a breeze.