or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-compilation.mdcompilation.mdconfiguration.mdexpress-integration.mdindex.mdrendering.md

express-integration.mddocs/

0

# Express.js Integration

1

2

Native Express.js view engine support for seamless web application integration. Pug provides a built-in Express view engine that handles template rendering within the Express middleware pipeline.

3

4

## Capabilities

5

6

### Express View Engine Function

7

8

The `__express` function provides Express.js view engine interface compatibility.

9

10

```javascript { .api }

11

/**

12

* Express.js view engine interface

13

* @param path - Template file path

14

* @param options - View options from Express including locals

15

* @param fn - Express callback function

16

*/

17

function __express(path, options, fn);

18

```

19

20

**Usage Examples:**

21

22

```javascript

23

const express = require('express');

24

const pug = require('pug');

25

26

const app = express();

27

28

// Set Pug as the view engine

29

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

30

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

31

32

// Express routes using Pug templates

33

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

34

res.render('index', {

35

title: 'Home Page',

36

message: 'Welcome to our site!'

37

});

38

});

39

40

app.get('/user/:id', (req, res) => {

41

const user = getUserById(req.params.id);

42

res.render('user-profile', {

43

user: user,

44

isOwner: req.user && req.user.id === user.id

45

});

46

});

47

48

app.listen(3000);

49

```

50

51

### Express Configuration

52

53

**Basic Setup:**

54

55

```javascript

56

const express = require('express');

57

const app = express();

58

59

// Configure Pug as view engine

60

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

61

app.set('views', path.join(__dirname, 'views'));

62

63

// Optional: Configure Pug-specific settings

64

app.locals.pretty = true; // Pretty-print HTML (development only)

65

app.locals.cache = process.env.NODE_ENV === 'production';

66

```

67

68

**Advanced Configuration:**

69

70

```javascript

71

const express = require('express');

72

const pug = require('pug');

73

74

const app = express();

75

76

// Custom Pug configuration

77

app.engine('pug', (filePath, options, callback) => {

78

// Custom options for all Pug templates

79

const pugOptions = {

80

...options,

81

basedir: app.get('views'),

82

cache: app.get('env') === 'production',

83

compileDebug: app.get('env') !== 'production',

84

filters: {

85

markdown: (text) => require('markdown-it')().render(text),

86

currency: (amount) => '$' + parseFloat(amount).toFixed(2)

87

}

88

};

89

90

return pug.renderFile(filePath, pugOptions, callback);

91

});

92

93

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

94

```

95

96

### Template Directory Structure

97

98

Typical Express + Pug project structure:

99

100

```

101

project/

102

├── views/

103

│ ├── layout.pug # Base layout template

104

│ ├── index.pug # Home page

105

│ ├── error.pug # Error page

106

│ ├── partials/

107

│ │ ├── header.pug # Header component

108

│ │ ├── footer.pug # Footer component

109

│ │ └── nav.pug # Navigation

110

│ └── users/

111

│ ├── profile.pug # User profile

112

│ └── settings.pug # User settings

113

├── public/ # Static assets

114

├── routes/ # Express routes

115

└── app.js # Main application

116

```

117

118

### Template Inheritance with Express

119

120

**Layout Template (views/layout.pug):**

121

122

```pug

123

doctype html

124

html

125

head

126

title= title || 'My App'

127

link(rel='stylesheet', href='/css/style.css')

128

block head

129

body

130

include partials/header

131

main.container

132

block content

133

include partials/footer

134

script(src='/js/app.js')

135

block scripts

136

```

137

138

**Page Template (views/index.pug):**

139

140

```pug

141

extends layout

142

143

block head

144

meta(name='description', content='Welcome to our homepage')

145

146

block content

147

h1= title

148

p= message

149

150

if user

151

p Welcome back, #{user.name}!

152

else

153

a(href='/login') Please log in

154

155

block scripts

156

script(src='/js/homepage.js')

157

```

158

159

### Express Middleware Integration

160

161

**Template Variables Middleware:**

162

163

```javascript

164

// Add common variables to all templates

165

app.use((req, res, next) => {

166

res.locals.currentUser = req.user;

167

res.locals.currentPath = req.path;

168

res.locals.environment = app.get('env');

169

res.locals.moment = require('moment'); // Date utility

170

next();

171

});

172

173

// Now available in all templates

174

app.get('/dashboard', (req, res) => {

175

res.render('dashboard', {

176

title: 'Dashboard'

177

// currentUser, currentPath, environment, moment are automatically available

178

});

179

});

180

```

181

182

**Error Handling Middleware:**

183

184

```javascript

185

// Custom error page rendering

186

app.use((err, req, res, next) => {

187

res.status(err.status || 500);

188

189

if (req.accepts('html')) {

190

res.render('error', {

191

title: 'Error',

192

error: app.get('env') === 'development' ? err : {},

193

message: err.message,

194

status: err.status || 500

195

});

196

} else if (req.accepts('json')) {

197

res.json({ error: err.message });

198

} else {

199

res.type('txt').send(err.message);

200

}

201

});

202

```

203

204

### Advanced Express Features

205

206

**Conditional Rendering:**

207

208

```javascript

209

app.get('/products', (req, res) => {

210

const products = getProducts();

211

const viewMode = req.query.view || 'grid';

212

213

res.render('products', {

214

title: 'Products',

215

products: products,

216

viewMode: viewMode,

217

showFilters: products.length > 10,

218

isAdmin: req.user && req.user.role === 'admin'

219

});

220

});

221

```

222

223

**Template Caching Strategy:**

224

225

```javascript

226

const express = require('express');

227

const app = express();

228

229

// Environment-based caching

230

if (app.get('env') === 'production') {

231

app.enable('view cache'); // Enable Express view caching

232

app.locals.cache = true; // Enable Pug template caching

233

app.locals.compileDebug = false;

234

} else {

235

app.locals.pretty = true; // Pretty HTML in development

236

app.locals.compileDebug = true;

237

}

238

```

239

240

**Custom Helper Functions:**

241

242

```javascript

243

// Add helper functions to templates

244

app.locals.formatDate = (date) => {

245

return new Date(date).toLocaleDateString();

246

};

247

248

app.locals.truncate = (text, length = 100) => {

249

return text.length > length ? text.substring(0, length) + '...' : text;

250

};

251

252

app.locals.asset = (path) => {

253

// Asset versioning helper

254

const version = app.get('env') === 'production' ? '?v=1.0.0' : '';

255

return path + version;

256

};

257

258

// Usage in templates:

259

// p= formatDate(post.createdAt)

260

// p= truncate(post.content, 150)

261

// link(rel='stylesheet', href=asset('/css/style.css'))

262

```

263

264

### Performance Optimization

265

266

**Production Configuration:**

267

268

```javascript

269

const express = require('express');

270

const app = express();

271

272

if (process.env.NODE_ENV === 'production') {

273

// Enable all Express optimizations

274

app.enable('view cache');

275

app.set('trust proxy', 1);

276

277

// Pug optimizations

278

app.locals.cache = true;

279

app.locals.compileDebug = false;

280

app.locals.pretty = false;

281

282

// Precompile critical templates

283

const criticalTemplates = ['layout', 'index', 'error'];

284

criticalTemplates.forEach(template => {

285

pug.compileFile(`./views/${template}.pug`, { cache: true });

286

});

287

}

288

```

289

290

**Memory Management:**

291

292

```javascript

293

// Monitor template cache size in production

294

if (process.env.NODE_ENV === 'production') {

295

setInterval(() => {

296

const cacheSize = Object.keys(pug.cache).length;

297

console.log(`Template cache size: ${cacheSize}`);

298

299

if (cacheSize > 100) {

300

console.warn('Template cache is large, consider cleanup');

301

}

302

}, 300000); // Check every 5 minutes

303

}

304

```

305

306

### Error Handling

307

308

**Template Rendering Errors:**

309

310

```javascript

311

app.get('/user/:id', (req, res, next) => {

312

try {

313

const user = getUserById(req.params.id);

314

315

if (!user) {

316

return res.status(404).render('404', {

317

title: 'User Not Found',

318

message: 'The requested user could not be found.'

319

});

320

}

321

322

res.render('user-profile', { user });

323

} catch (err) {

324

// Template rendering error

325

console.error('Template error:', err);

326

next(err);

327

}

328

});

329

```

330

331

**Development Error Pages:**

332

333

```javascript

334

if (app.get('env') === 'development') {

335

app.use((err, req, res, next) => {

336

res.status(err.status || 500);

337

res.render('error', {

338

title: 'Development Error',

339

message: err.message,

340

error: err, // Full error object in development

341

stack: err.stack

342

});

343

});

344

}

345

```

346

347

### Testing Templates with Express

348

349

**Template Testing Setup:**

350

351

```javascript

352

const request = require('supertest');

353

const express = require('express');

354

355

const app = express();

356

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

357

app.set('views', './test/fixtures/views');

358

359

app.get('/test', (req, res) => {

360

res.render('test-template', { message: 'Hello Test' });

361

});

362

363

// Test template rendering

364

describe('Template Rendering', () => {

365

it('should render test template', (done) => {

366

request(app)

367

.get('/test')

368

.expect(200)

369

.expect(/<p>Hello Test<\/p>/)

370

.end(done);

371

});

372

});

373

```

374

375

**Mocking Template Data:**

376

377

```javascript

378

const mockData = {

379

users: [

380

{ id: 1, name: 'Alice', email: 'alice@example.com' },

381

{ id: 2, name: 'Bob', email: 'bob@example.com' }

382

]

383

};

384

385

app.get('/test-users', (req, res) => {

386

res.render('users', {

387

title: 'Test Users',

388

users: mockData.users

389

});

390

});

391

```

392

393

This completes the Express.js integration documentation, providing comprehensive coverage of how to use Pug as an Express view engine with practical examples and best practices.