Skip to content
  • English Deutsch

benjamin-abt.com

Performance is a feature | Cloud - AI - Azure - .NET - Sustainability

  • Home
  • Blog
  • Portfolio
    • Overview
    • Workshops & Training
    • Publications
  • Contact
  • Home
  • Blog

Text and EMail Templates with Handlebars.NET

Text and EMail Templates with Handlebars.NET
December 12, 2023 4 min read BEN ABT
ASP.NET Core .NET Csharp

This article was written in 2023. Versions, tools and recommendations may have changed since then. Newer posts are collected under ASP.NET Core.

A frequent requirement in apps is the conversion of templates, e.g. for sending e-mails, for PDF templates or other text modules. There are many different ways to do this, ranging from simple string replacements to the Razor engine of ASP.NET Core.

In this article I would like to introduce another possibility: Handlebars.NET.

HandleBars

Handlebars.NET is a library for the .NET platform that enables the use of Handlebars templates in .NET applications. Handlebars is a simple and expressive templating language that allows dynamic content to be inserted into static templates. The Handlebars.NET library provides a .NET implementation of this language.

  • Templating syntax: Handlebars.NET allows templates to be defined using a simple and more readable syntax. Placeholders and control structures are represented by curly brackets and hash characters.

  • Data binding: The library enables data to be bound to templates. This means that dynamic content from a data source can be inserted into the template. This is particularly useful for creating HTML pages with variable content.

  • Extensibility: Handlebars.NET supports the extension of functionality through the implementation of custom helper functions and block helpers. Developers can add their own functions to integrate complex logic into templates.

  • Platform independence: Because it is a .NET library, Handlebars.NET can be used in various .NET environments, including ASP.NET applications and console applications.

HandleBars.NET is an open source project on GitHub , which is referenced via a NuGet package. Please consider sponsoring the project if you use it for commercial purposes.

Sample

In principle, HandleBars offers various options for rendering text, ranging from simple scenarios to more complex requirements, including custom render modules.

One of the best features of HandleBars is that templates can be registered; and an instance is required for registration. In addition to a global instance, however, isolated instances are better in real implementations - because this way I cannot collide with other elements in my app.

It therefore makes sense to create a separate class that manages the instance and registers the templates.

C#
 1// MyTemplateProvider.cs
 2
 3public class MyTemplateProvider
 4{
 5    private readonly IHandlebars _handlebars;
 6
 7    public MyTemplateProvider()
 8    {
 9        _handlebars = Handlebars.Create();
10    }

I can now add certain templates to this instance and register them with the instance.

C#
 1// MyTemplateProvider.cs
 2
 3    public MyTemplateProvider()
 4    {
 5        _handlebars = Handlebars.Create();
 6
 7        Init(); // Add this
 8    }
 9
10    private void Init()
11    {
12        // Add Header Template
13        _handlebars.RegisterTemplate("Header_Template", @"<strong>MyCompany - {{Title}}</strong>");
14
15        // Add Footer Template
16        _handlebars.RegisterTemplate("Footer_Template", @"<i>MyCompany - Copyright 2023</i>");
17
18        // Register Welcome Mail
19        _handlebars.RegisterTemplate("WelcomeMail_Template",
20            """
21            <div>
22                <h1>{{>Header_Template}}</h1>
23                <div class="body">
24                    <h3>Welcome to our demo {{UserName}}!</h3>
25                <p>Thank you for registering. Have fun!</p>
26                </div>
27                <footer>{{>Footer_Template}}</footer>
28            </div>
29            """);
30    }

What is still missing is the actual rendering, i.e. transferring values to the template. To do this, the template must first be compiled and the compilation can then be used to inject values. HandleBars.NET offers the Compile method for this, so that we can only compile the template itself once for performance and resource reasons and then use it again and again.

C#
 1// MyTemplateProvider.cs
 2
 3    private HandlebarsTemplate<object, object>? _welcomeTemplate = null;
 4    public string RenderWelcomeMail(string userName)
 5    {
 6        _welcomeTemplate ??= _handlebars.Compile("{{>WelcomeMail_Template}}");
 7
 8        var data = new
 9        {
10            Title = "Welcome!",
11            UserName = userName
12        };
13
14        var text = _welcomeTemplate(data);
15        return text;
16    }

The renderer is now ready and can be used in an application in a very simple and high-performance way.

C#
 1internal class Program
 2{
 3    static void Main(string[] args)
 4    {
 5        MyTemplateProvider templateProvider = new();
 6
 7        List<string> userNames = ["Batman", "Robin"];
 8        foreach (var userName in userNames)
 9        {
10            string text = templateProvider.RenderWelcomeMail(userName);
11
12            Console.WriteLine($"To: {userName}");
13            Console.WriteLine(text);
14            Console.WriteLine("-------------------");
15        }
16    }
17}

Output:

Shell
 1To: Batman
 2<div>
 3  <h1><strong>MyCompany - Welcome!</strong></h1>
 4  <div class="body">
 5     <h3>Welcome to our demo Batman!</h3>
 6    <p>Thank you for registering. Have fun!</p>
 7  </div>
 8  <footer><i>MyCompany - Copyright 2023</i></footer>
 9</div>
10-------------------
11To: Robin
12<div>
13  <h1><strong>MyCompany - Welcome!</strong></h1>
14  <div class="body">
15     <h3>Welcome to our demo Robin!</h3>
16    <p>Thank you for registering. Have fun!</p>
17  </div>
18  <footer><i>MyCompany - Copyright 2023</i></footer>
19</div>
20-------------------

Related articles

Problem Details in ASP.NET Core and .NET 11

Oct 5, 2026 - 12 min read

Problem Details in ASP.NET Core and .NET 11

builder.Services.AddProblemDetails() registers infrastructure. It does not create an error contract. An ASP.NET Core request can fail during …

Resilience in .NET with Microsoft.Extensions.Resilience

Sep 21, 2026 - 11 min read

Resilience in .NET with Microsoft.Extensions.Resilience

Retries are the most visible resilience strategy and the easiest one to misuse. Repeating a failing call can recover from a short network …

What Matters in ASP.NET Core 11

Sep 14, 2026 - 10 min read

What Matters in ASP.NET Core 11

ASP.NET Core 11 has no single feature that fundamentally changes how web applications are built. That is not a criticism. Mature frameworks …


BEN ABT

BEN ABT

Ben is Chief Engineering Officer and Principal Software Engineer at Medialesson.de, with a strong focus on .NET and Microsoft Azure. In his professional role, he designs and builds highly scalable platforms for hybrid and cloud-based scenarios. He also advises companies and C-levels on migrating to the sovereign cloud.

He runs myCSharp.de, the largest and most active German-speaking C# community forum, actively contributes to both his own and external open-source projects and regularly shares his knowledge through his blog, at community events, conferences and as a writer for technical magazines.

Let's Work Together

Looking for an experienced Platform Architect or Engineer for your next project? Whether it's cloud migration, platform modernization or building new solutions from scratch - I'm here to help you succeed.

New Platforms

Modernization

Training & Consulting

Contact Me
X Facebook LinkedIn WhatsApp
Back Next Blog Post

Open for work!

Contact Me
BEN ABT BEN ABT Software Engineer · Microsoft MVP Passionate about .NET, Azure, performance optimization and sustainable software engineering.

Medialesson GmbH Logo

Microsoft MVP Logo

Recent posts

View all
Stop Using nginx as Your Default Static File Server in Docker

Stop Using nginx as Your Default Static File Server in …

Oct 24, 2026
Containerizing .NET in 2026 Without a Dockerfile

Containerizing .NET in 2026 Without a Dockerfile

Oct 20, 2026
Problem Details in ASP.NET Core and .NET 11

Problem Details in ASP.NET Core and .NET 11

Oct 5, 2026
Resilience in .NET with Microsoft.Extensions.Resilience

Resilience in .NET with Microsoft.Extensions.Resilience

Sep 21, 2026
What Matters in ASP.NET Core 11

What Matters in ASP.NET Core 11

Sep 14, 2026

Tags

.NET (192) Csharp (96) ASP.NET Core (48) Azure (41) DevOps (17) Docker (14) Microsoft (14) EF Core (11) Microsoft MVP (11) AI (10) GitHub (10) GitHub Copilot (10) ASP.NET (9) Security (9) Synology (9) Architecture (8) Raspberry (8) Azure Functions (7) Cloudflare (7) Bicep (6)
benjamin-abt.com

About BEN

Benjamin Abt is a Software Engineer, Platform Architect and Microsoft MVP specializing in .NET, Azure, cloud architecture, performance optimization and sustainable software development.

Connect

  • Follow me on GitHub
  • Follow me on LinkedIn
  • Follow me on Mastodon
  • Microsoft MVP profile
  • Follow SchwabenCode on GitHub
  • Follow me on X

Quick Links

  • Portfolio
  • Blog
  • Workshops & Training
  • Publications
  • Get in Touch
  • Sitemap
Open for Work

© Copyright Benjamin Abt & SchwabenCode | 2011 - 2026

Content licensed under CC BY 4.0 unless otherwise noted.

  • Impressum
  • Privacy
  • Contact