Pug Template Inheritance: Reduce HTML Duplication with Extends and Blocks
Learn how Pug's extends and block directives let you share layout markup across pages, avoid duplication, and keep server‑side rendering clean.
13 Dec 2025, 23:27 UTC

Why duplication hurts server‑side rendered sites
When you build a web application with a server‑side renderer, every page usually shares the same doctype, head, and body structure. Copy‑pasting that boilerplate for each view quickly becomes error‑prone and makes updates painful. The core problem is repeated markup that must stay in sync across many files.
Pug’s inheritance model solves the problem
Pug (formerly Jade) provides the extends directive to create a hierarchy of templates. A base file, often called a layout, defines the overall HTML skeleton and places block markers where page‑specific content belongs. Child templates declare which layout they extends and then replace, append, or prepend content inside those blocks. Because the hierarchy is resolved at compile time, the resulting HTML is exactly what you expect, and missing or mismatched blocks raise clear compile errors.
Defining a layout
The layout file starts with a doctype and contains a block content placeholder. Anything outside a block — such as a header or footer — remains unchanged when the layout is used. Example:
doctype html
html
head
title= title
body
block content
Creating a child page
A child template declares the layout it inherits and supplies content for the block. If you want to add a heading, you simply place it inside the block. You can also extend a block to add content before or after the default:
- Define the block in the layout with optional default markup.
- In the child, use
block contentto replace the default, orappend blockname/prepend blocknameto modify the surrounding context. - Render the child with the Pug runtime; the compiler merges the blocks into a single HTML document.
Worked example
Let’s build a minimal site with a shared header and footer.
# layout.pug
doctype html
html
head
title= title
body
block header
block content
block footer
Now a page that uses this layout:
# page.pug
extends layout
block header
h1= title
block content
p This is the main content of the page.
The extends relationship is resolved during compilation, so any typo in the layout filename or an undefined block will cause the Pug compiler to abort with a descriptive error, preventing silent rendering bugs.
Trade‑offs and practical limits
While inheritance reduces duplication, deep nesting of multiple extends chains can make the template graph hard to trace. Each additional layout adds compile‑time coupling, meaning a change in a base file may require recompiling dependent templates. Whitespace inside a block must match the surrounding indentation; otherwise the compiler may misinterpret the nesting and generate malformed HTML. Also, Pug automatically escapes interpolated values with =; if you need raw HTML you must use != and sanitize carefully.
How to verify your setup
Run the following commands to ensure you are using a supported Pug version and to test the inheritance flow:
- Check the installed version:
npm list pugorpug --version. Versions before 2.0 introduced different error messages for missing blocks. - Compile a test layout with
pug compileFile layout.pug -o layout.jsand then render a child template via an Express route:res.render('page', {title: 'My Page'}). Inspect the generated HTML to confirm the heading appears inside the layout’sbody. - If you see a compile error mentioning an undefined block, double‑check the block name spelling and that the child template actually
extendsthe correct file.
Closing steps
Start by extracting the common skeleton of your site into a single layout.pug file. Add block placeholders where each page will differ. Create child templates that extends the layout and fill the blocks. Verify the output with the steps above, and enable function‑level caching in production to avoid recompiling on every request. With this pattern you’ll keep your HTML DRY, maintainable, and less prone to rendering surprises.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.