Express EJS Views, Layouts, and Partials

Registered members can download the FREE Get Started App. This is the project I used to compose articles about setting up VS Code and developing Node with Express and the Embedded JavaScript (EJS) view engine.

Views in Express EJS are a lot like views in MVC and pages in Razor Pages. Layouts and partials are like _Layouts and _Partials in ASP.NET Core. This article describes the implementations.

When I decided to learn Express, I found a lot of articles and AI suggestions which did not implement ES6 standards. ES6 or ECMAScript 2015 changed the landscape of JavaScript with the ability to create promises for asynchronous programming. I am familiar with ASP.NET Core and C# web applications and SQL Server databases. I developed this Express application with KenHaggerty.Com as a model. Registered members can download the FREE Get Started PostgreSQL app and Get Started MySQL app which implement this getting started with Express EJS tutorial.

You need to install the express-ejs-layouts library to implement a main layout like ASP.NET Core's _Layout.cshtml. From the project folder, open PowerShell or a command prompt and run the npm command.

npm install express-ejs-layouts

Launch VS Code. From PowerShell or a command prompt execute "code .". Open server.js and add the expressLayouts middleware. I also configure a public folder for static files.

server.js
app.use(express.static('public'));

app.use(expressLayouts);
app.set('layout', 'layouts/main');
app.set('layout extractScripts', true);

From the Explorer tab, add a root folder named public. The public folder will contain static files like style.css and site.js which are served directly to the client. Expand the views folder and add the layout, pages, and partial folders. Move any existing views like index.ejs to the pages folder. Add a main.ejs file to the layout folder. The extractScripts layout option in server.js relocates scripts in views to the script variable in the main.ejs file.

Add expressLayouts Middleware

The main.ejs layout loads with every page and gives the application a consistent navigation system. I use Bootstrap css and Bootstrap-Native js to provide a collapsible mobile friendly menu with the navbar component. Any files in the public folder can be referenced with the root path like /favicon.ico.

main.ejs
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= pageTitle %></title>
    <link rel="shortcut icon" href="/favicon.ico" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.8/css/bootstrap.min.css" 
        integrity="sha512-2bBQCjcnw658Lho4nlXJcc6WkV/UxpE/sAokbXPxQNGqmNdQrWqtw26Ns9kFF/yG792pKR1Sx8/Y1Lf1XN4GKA==" 
        crossorigin="anonymous" referrerpolicy="no-referrer" />
    <link rel="stylesheet" href="/css/style.css">
</head>

<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-primary mb-3">
        <div class="container">
            <a class="navbar-brand" href="/">Get Started</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse"
                aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="navbar-collapse collapse" id="navbarSupportedContent">
                <ul class="navbar-nav">
                    <li class="nav-item"><a class="nav-link" href="/about"><span>About</span></a></li>
                </ul>
            </div>
        </div>
    </nav>
    <main>
        <div class="container">
            <%- body %>
        </div>
    </main>
    <footer>
        <div class="navbar-dark bg-primary px-4">
            &copy; 2025 Ken Haggerty
        </div>
    </footer>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap.native/5.1.6/bootstrap-native.min.js"
        integrity="sha512-r+bQtRG0rDGJI4/SXo1li9IfCJIz7Hw2jyued7Uqc2ZtbWl6VoDwARPIjQ2rBvLntOnPLivStY5NE3i6uVH98Q=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script type="text/javascript" src="/js/site.js"></script>
    <%- script %>
</body>

</html>
Get Started Home Desktop
Get Started Home Mobile

Partials are html code snippets which can be added to a view with the include directive. Use the raw output tag <%- %> instead of <%= %> to avoid double-escaping the HTML output from the included file.

<%- include('../partials/modal'); %>
Contact Us Modal
Created: 2/14/26