Using Pug (PugJS) for Dynamic HTML Rendering with NodeJS

Pug, also known as PugJS, serves as a templating engine for NodeJS. It enables the dynamic creation of HTML content on the server side, utilizing data transmitted from the backend to the front-end templates. Unlike traditional HTML, Pug’s syntax allows for more compact and flexible markup generation.

In this guide, the example server IP address used is 192.0.2.123.

System Requirements

Before you proceed with the setup, ensure the following conditions are met:

  • You have a non-root user configured with sudo permissions. Refer to our guide on creating and using a sudo user.
  • You are familiar with routing techniques in ExpressJS.
  • Your server’s software packages are current. See our best practices for keeping Ubuntu systems updated.
  • The build-essential package is installed. If it’s missing, install it by running:

  $ sudo apt-get install build-essential

Installing NodeJS and NPM

To install NodeJS from the NodeSource repository, start by ensuring curl is available:

  $ sudo apt-get install curl

Next, add the most recent Active LTS release of NodeJS to your system:

  $ curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -

Now proceed with the installation of NodeJS:

  $ sudo apt-get install nodejs

Finally, verify that NodeJS and NPM are correctly installed:

  $ node -v && npm -v
  v12.x.x
  6.x.x

Environment Setup and ExpressJS Web Server with Pug

Initialize the Project Environment

Begin by creating a new directory to house your project files:

  $ cd ~
  $ mkdir pugjs
  $ cd pugjs

Initialize the NodeJS environment, which generates a package.json configuration file:

Respond to the prompts to tailor the setup to your needs. Simply pressing Enter to accept each default option results in a configuration like this:

  About to write to ~/pugjs/package.json:

  {
    "name": "pugjs",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "license": "ISC"
  }

  Is this OK? (yes)

Install the necessary packages (express and pug) using npm while in the root directory:

  $ npm install --save express pug

Build a Basic ExpressJS Server

Create a file named index.js in the project’s root directory:

Add the following code into index.js to define a simple ExpressJS web server and route:

  const express = require("express");
  const port = process.env.PORT || 8080;
  const app = express();

  app.get('/', (req, res) => {
      res.send("It is working!");
  });

  app.listen(port, () => {
      console.log(`Server started on port ${port}`);
  });

Launch the server using NodeJS. You should receive this confirmation output:

  $ node index.js
  Server started on port 8080

To confirm the routing functionality, open any browser and visit:

http://192.0.2.123:8080/

If successful, you should see the message ‘It is working!’ displayed on the page.

 

Linking PugJS Templates with ExpressJS Routes

Update the index.js file to include support for the PugJS templating engine and configure the route to render a view:

  const express = require("express");
  const path = require("path");
  const port = process.env.PORT || 8080;
  const app = express();

  app.set('view engine', 'pug'); // configure Pug as the view engine
  app.set('views', path.join(__dirname, 'views')); // define the directory for view templates

  app.get('/', (req, res) => {
      res.render("home"); // render the specified view template for this route
  });

  app.listen(port, () => {
      console.log(`Server started on port ${port}`);
  });

Create a directory named views at the root of your project and move into it:

Inside the views folder, create a new file named home.pug. This file will be served by ExpressJS when the root URL is accessed:

After this step, the directory structure of your application (excluding node_modules and package.json) should look like this:

  ~/pugjs/
  ├── index.js
  └── views/
      └── home.pug

Open home.pug and insert the following basic HTML structure in Pug syntax:

  html
      head
          title Homepage
      body
          h1 Welcome to the Homepage!

Return to the root project directory and run the server again using NodeJS:

  $ cd ~/pugjs
  $ node index.js
  Server started on port 8080

Once the server is running, open a web browser and navigate to:

http://192.0.2.123:8080/

You should now see a webpage displaying the message ‘Welcome to the Homepage!’ within an <h1> heading.

 

Passing Data from ExpressJS to a Pug View

To pass data from the backend to a Pug template, update the index.js file to include a second argument when rendering the view. This argument contains the data to be displayed:

  const express = require("express");
  const path = require("path");
  const port = process.env.PORT || 8080;
  const app = express();

  app.set('view engine', 'pug'); // define Pug as the view engine
  app.set('views', path.join(__dirname, 'views')); // point to the view templates directory

  app.get('/', (req, res) => {
      // supply an object to the render method with data for the view
      res.render("home", {message: "THIS IS SENT FROM THE SERVER!"});
  });

  app.listen(port, () => {
      console.log(`Server started on port ${port}`);
  });

Open the home.pug file in the views directory and enhance it to display the passed data:

  html
      head
          title Homepage
      body
          h1 Welcome to the Homepage!
          p=message

Return to the project root and start the server using NodeJS:

  $ cd ~/pugjs
  $ node index.js
  Server started on port 8080

Open a web browser and visit:

http://192.0.2.123:8080/

This time, the page will show the heading ‘Welcome to the Homepage!’ and a paragraph containing ‘THIS IS SENT FROM THE SERVER!’.

Final Thoughts

You’ve successfully configured a basic template setup using Pug. To explore more features and capabilities, refer to the official Pug API documentation.

Source: vultr.com

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in: