ExpressJS - Serving Dynamic Content
Express.js - Serving Dynamic Content with Template Engines
Section titled “Express.js - Serving Dynamic Content with Template Engines”Express applications often need to generate dynamic HTML content based on data from a database or user input. Instead of manually constructing HTML strings in your JavaScript code (which is error-prone and hard to maintain), you should use a template engine.
What is a Template Engine?
Section titled “What is a Template Engine?”A template engine allows you to write static template files (like HTML, but with special syntax) and inject dynamic data into them at runtime. This practice separates presentation (HTML) from logic (JavaScript), leading to cleaner and more organized code. Popular template engines for Express include Pug (formerly Jade), EJS, and Nunjucks.
In this tutorial, we’ll use Pug for its clean, indentation-based syntax. The principles, however, apply to any template engine.
Project Setup
Section titled “Project Setup”Let’s build a simple app that takes a number from a form, calculates its square on the server, and displays the result.
1. Install Dependencies
Section titled “1. Install Dependencies”You only need express and pug for this example.
npm install express pug2. Configure Express
Section titled “2. Configure Express”First, you need to tell Express which template engine to use and where to find the template files (called ‘views’).
import express from 'express';import path from 'path';import { fileURLToPath } from 'url';
const app = express();const PORT = 3000;
// Necessary for __dirname in ES Modulesconst __filename = fileURLToPath(import.meta.url);const __dirname = path.dirname(__filename);
// 1. Set the view engine to Pugapp.set('view engine', 'pug');// 2. Specify the directory where the template files are locatedapp.set('views', path.join(__dirname, 'views'));3. Handle Form Submissions
Section titled “3. Handle Form Submissions”To process data from an HTML form, you need to use the express.urlencoded() middleware. This middleware parses incoming requests with x-www-form-urlencoded payloads (the default for HTML forms) and populates the req.body object.
Note: In older versions of Express, this required the external body-parser package. It is now built into Express.
// 3. Use middleware to parse form dataapp.use(express.urlencoded({ extended: true }));Creating the Application Logic
Section titled “Creating the Application Logic”1. Create the Pug Template
Section titled “1. Create the Pug Template”Create a directory named views and inside it, a file named calculator.pug.
html head title Dynamic Content Calculator style. body { font-family: sans-serif; padding: 20px; } input, button { font-size: 1rem; padding: 5px; } body h1 Square Calculator
form(action="/calculate", method="POST") div label(for="number") Enter a Number: input#number(name="number" type="number" value=inputValue || '') br button(type="submit") Calculate Square
//- This block only renders if 'result' is passed from the server if result h2 Result: #{result}2. Create the Route Handlers
Section titled “2. Create the Route Handlers”Now, let’s complete our index.js file with the routes to render the form and handle the calculation.
// index.js (continued)
// Route to display the formapp.get('/', (req, res) => { // res.render() finds 'calculator.pug' and sends it as HTML res.render('calculator');});
// Route to handle the form submissionapp.post('/calculate', (req, res) => { const number = parseFloat(req.body.number);
// Basic validation if (isNaN(number)) { return res.render('calculator', { inputValue: req.body.number, result: 'Error: Please enter a valid number.' }); }
const square = number * number;
// Render the same template, but pass data to it res.render('calculator', { inputValue: number, result: `The square of ${number} is ${square}.` });});
app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`);});Running the App
Section titled “Running the App”- Run your server with
node index.js. - Open your browser to
http://localhost:3000. - Enter a number and click the ‘Calculate Square’ button.
- The page will reload, displaying the calculated result right below the form.
Common Pitfalls
Section titled “Common Pitfalls”req.bodyis undefined: This almost always means you forgot to include theapp.use(express.urlencoded({ extended: true }));middleware, or you placed it after your route handler.- Failed to lookup view ”…”: This error means Express cannot find your template file. Double-check that
app.set('views', ...)points to the correct directory and that the filename inres.render()is correct.