Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Pug with Express

So far Pug has run at build time: a script created the HTML files once. On a server it is different — Express (a popular web framework for Node.js) renders the page from the template again on every request and can insert fresh data, for example from a database. Express itself is covered in detail in the Express course of the JavaScript section; here you only see what connects it to Pug.

Installing

Create a new project and install Express together with Pug:

mkdir cafe-server
cd cafe-server
npm init -y
npm pkg set type=module
npm install express pug

This lesson targets Express 5, the current version this command installs.

The server

Create the file src/server.js:

// src/server.js
import express from "express";
 
const app = express();
app.set("view engine", "pug");
 
const menu = [
  { name: "Espresso", price: 2 },
  { name: "Cappuccino", price: 3 },
];
 
app.get("/", (req, res) => {
  res.render("index", { title: "Morning Café", menu });
});
 
app.listen(3000, () => {
  console.log("Server running: http://localhost:3000");
});

The line app.set("view engine", "pug") tells Express that templates are written in Pug. res.render() finds the template by its name without the extension, passes it the data object and sends the finished HTML as the response.

The template

Express looks for templates in the views/ folder in the project root. Create views/index.pug:

doctype html
html(lang="en")
  head
    meta(charset="utf-8")
    title= title
  body
    h1= title
    ul
      each item in menu
        li #{item.name} — $#{item.price}

The fields of the object from res.render() became the variables title and menu, just like the data from build.js before.

Running it

node src/server.js

Open http://localhost:3000 and you will see the heading and the list of drinks. The browser receives this HTML:

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Morning Café</title></head><body><h1>Morning Café</h1><ul><li>Espresso — $2</li><li>Cappuccino — $3</li></ul></body></html>

Express does not turn on pretty, so the HTML arrives on one line, which makes the page smaller. The browser developer tools are a more convenient way to read the code: they show it with indentation.

Layouts and mixins on the server

Everything from the previous lessons works here too: put layout.pug, mixins.pug and the includes/ folder into views/, and start pages with extends layout.pug. Paths in extends and include are still counted from the current file.

Common mistake

Inserting what visitors sent with != or !{...}: a name from a form, the text of a review. On a server such data arrives all the time, and any unescaped insertion opens the door to an XSS attack. Output user data only with = and #{...}.

Thanks for reading!

Donate to the site — we work hard for you.