Header and Footer Partials | EJS & EJS Layouts

Header and Footer Partials | EJS & EJS Layouts

05/10/2026

EJS is a very useful tool in web development that helps integrate JavaScript code inside HTML files. I used it to insert information from a database into pages, and to combine different parts into one page.

In this article, I will install the EJS package and create separate header and footer files that are applied to the main page.

To install EJS, run this in the terminal:

npm i ejs


I don't have an express-ejs-layouts package in the current deployed version of this website, but this time I will add it. That package helps create reusable and well-structured page templates, so the project will have a neater hierarchy:

npm i express-ejs-layouts


Open the views folder and create three new folders: layouts, partials, and pages (we will need them later). In the layouts folder, create a layout.ejs file. In this file, create a default HTML template using the "!" character and the Tab key. Then add the EJS tags in the <body> and <title> elements:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- Here -->
  <title><%= title %></title>
</head>
<body>
  <!-- Here -->
  <%- include('../partials/header') %>
  <%- body %>
  <%- include('../partials/footer') %>
</body>
</html>


This file will be a template for all the pages on this website. In this code, I added lines that include separate partials in this template and also display the title of the page. These files don't exist yet, so before creating them, let's configure EJS in app.js.

const express = require('express') // Import Express
const expressLayouts = require('express-ejs-layouts') // Import EJS Layouts

const app = express() // Web application

app.use(expressLayouts) // Wraps pages in the layout via res.render
app.use(express.static('public')) // Serves static files from the public folder

app.set('view engine', 'ejs') // Engine for converting from .ejs to .html
app.set('layout', 'layouts/layout') // Default layout file

const port = 3000 // Port number

// Displays the About page on the main route
app.get('/', (req, res) => {
  res.render('pages/about', { title: 'About' })
})

// ... other code


In the previous code, I added several new lines and slightly changed the route. First of all, I imported the installed express-ejs-layouts package and applied it to wrap pages in the layout when using res.render. Then I told Express that the public folder is used for static files, so now it will be possible to retrieve them, including CSS files. Next, I changed the view engine to EJS so from now on Express will render EJS templates instead of plain HTML. Finally, I set the layout file as the default layout.

In the route, I changed the method from sendFile, which sent HTML files, to render, which converts EJS templates to HTML. I also added a second argument, { title: 'About' }, which passes the page title that will be displayed in the browser tab.

Move the about.html file to the pages folder and change its extension from .html to .ejs. Open the file and delete everything except the <main> tag and everything inside it.

In the partials folder, create two new files: footer.ejs and header.ejs. There are special tags for headers and footers in HTML with the corresponding names.

Header:

<header>
  <a href="/" class="header-title">_sichen</a>
  <nav class="header-navigation">
    <ul>
      <li>
    <a href="/">About</a>
  </li>
  <li>
    <a href="/">Articles</a>
      </li>
  <li>
    <a href="/">Projects</a>
  </li>
    </ul>
  </nav>
</header>


The title in the header will be the <a> tag, so anybody who clicks it will be taken to the main page. I implemented the navigation bar using the semantic <nav> tag, which helps with SEO (Search Engine Optimization) and accessibility. The links in the navigation bar also lead to the main page for now; I will change the paths when I create these pages.

There is nothing special in footer.ejs:

<footer>
  <p class="footer-copyright">©2026 Sichen | All rights reserved</p>
</footer>


I modified index.css a little so that the main content fills the free space and pushes the footer to the very bottom:

body {
  background-color: rgb(251, 247, 238);
  color: rgb(31, 36, 40);
  font-size: 18px;
  font-family: 'IBM Plex Mono', monospace;
  /* New lines of code */
  min-height: 100dvh; /* The page is at least as tall as the viewport (browser window) */
  display: grid;
  grid-template-rows: auto 1fr auto; /* The main takes all the free space; the header and footer fit their content */
  gap: 20px;
}


I used grid here instead of flex because it divides the page into parts, so it allows me to set the size of each part separately.

Then write the header and footer styles and connect them to layout.ejs via a <link> tag.

Header:

header {
  display: flex;
  align-items: center; /* Centers the elements (horizontally here) perpendicular to the flex direction */
  flex-direction: column; /* Each element is under the previous one */
  gap: 10px;  /* Space between elements */
}

.header-title {
  color: inherit; /* Same color as the page text */
  font-size: 96px;
}

.header-navigation ul {
  margin-left: 40px; /* Left margin set by eye so the menu looks more centered */
  display: flex;
  gap: 25px;
}

.header-navigation li {
  list-style: none; /* Removes the list bullets */
}

.header-navigation a {
  color: inherit;
}


Footer:

footer {
  background-color: #5f8272;
  display: flex;
  justify-content: center; /* Centers the elements along the flex direction */
}

.footer-copyright {
  margin: 0;
  padding: 10px 0;
  font-size: 15px;
  color: #fbf7ee;
}



Links:

1. EJS: https://www.npmjs.com/package/ejs

2. Express EJS Layouts: https://www.npmjs.com/package/express-ejs-layouts