Mjml.Net
1.0.2
See the version list below for details.
dotnet add package Mjml.Net --version 1.0.2
NuGet\Install-Package Mjml.Net -Version 1.0.2
<PackageReference Include="Mjml.Net" Version="1.0.2" />
paket add Mjml.Net --version 1.0.2
#r "nuget: Mjml.Net, 1.0.2"
// Install Mjml.Net as a Cake Addin #addin nuget:?package=Mjml.Net&version=1.0.2 // Install Mjml.Net as a Cake Tool #tool nuget:?package=Mjml.Net&version=1.0.2
MJML.NET
A blazingly-fast unofficial port of MJML 4 (by MailJet) to .NET 6.
Introduction
MJML
is a markup language created by Mailjet and designed to reduce the pain of coding a responsive email. Its semantic syntax makes the language easy and straightforward while its rich standard components library shortens your development time and lightens your email codebase. MJML’s open-source engine takes care of translating the MJML
you wrote into responsive HTML.
Usage
Firstly, you'll need to reference the MJML.NET
NuGet Package into your project.
PM > Install-Package Mjml.Net
Secondly, include MJML.NET
namespace into your project.
using Mjml.Net;
Finally, the boilerplate code.
public static void Main (string[] args) {
var mjmlRenderer = new MjmlRenderer();
string text = @"
<mjml>
<mj-head>
<mj-title>Hello World Example</mj-title>
</mj-head>
<mj-body>
<mj-section>
<mj-column>
<mj-text>
Hello World!
</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>";
var html = mjmlRenderer.Render(text, new MjmlOptions {
Beautify = false
}).Html;
}
Options
You can also specify options to the MJML parser.
Name | Data Type | Default | Description |
---|---|---|---|
KeepComments | bool | false | True to keep comments. |
Breakpoint | string | 480px | The default breakpoint to switch to mobile view. |
Styles | Style[] | [] | A list of custom styles. |
ForceOWAQueries | bool | false | True to enable media queries for OWA. |
Beautify | bool | true | True to beatify the HTML. Impacts performance (slower). |
Minify | bool | false | True to minify the HTML. |
Lax | bool | false | In lax mode some errors in the XML will be fixed. Only work when the MJML is passed in as string. Do not turn this on in production, because it can hurt performance. |
Fonts | [string] ⇒ Fond | Preset | A list of supported default fonts. |
XmlEntities | [string] ⇒ string | Preset | A list of supported XML entities. |
ValidatorFactory | IValidatorFactory? | null | The current validator, which also defines the validation mode. |
Supported Components
MJML.NET
tries to implement all functionality 1-2-1
with the MJML 4 project. However, due to JavaScript not being a typed language this means there has been considerate refactoring to the code to make it more aligned with C# typed requirements.
Type | Component | Implemented | Tests | State |
---|---|---|---|---|
Core | mjml | ✅ | ✅ | Feature Complete |
Core | mj-head | ✅ | ✅ | Feature Complete |
Core | mj-body | ✅ | ✅ | Feature Complete |
Core | mj-include | ❌ | ❌ | Not Planned |
Head | mj-attributes | ✅ | ✅ | Feature Complete |
Head | mj-class |
✅ | ✅ | Feature Complete |
Head | mj-all |
✅ | ✅ | Feature Complete |
Head | mj-breakpoint | ✅ | ✅ | Feature Complete |
Head | mj-font | ✅ | ✅ | Feature Complete |
Head | mj-html-attributes | ❌ | ❌ | Not Planned |
Head | mj-preview | ✅ | ✅ | Feature Complete |
Head | mj-style | ✅ | ✅ | Feature Complete |
Head | mj-title | ✅ | ✅ | Feature Complete |
Body | mj-accordion | ✅ | ✅ | Feature Complete |
Body | mj-button | ✅ | ✅ | Feature Complete |
Body | mj-carousel | ✅ | ✅ | Feature Complete |
Body | mj-column | ✅ | ✅ | Feature Complete |
Body | mj-divider | ✅ | ✅ | Feature Complete |
Body | mj-group | ✅ | ✅ | Feature Complete |
Body | mj-hero | ✅ | ✅ | Feature Complete |
Body | mj-image | ✅ | ✅ | Feature Complete |
Body | mj-navbar | ✅ | ✅ | Feature Complete |
Body | mj-raw | ✅ | ✅ | Feature Complete |
Body | mj-section | ✅ | ✅ | Feature Complete |
Body | mj-social | ✅ | ✅ | Feature Complete |
Body | mj-spacer | ✅ | ✅ | Feature Complete |
Body | mj-table | ✅ | ✅ | Feature Complete |
Body | mj-text | ✅ | ✅ | Feature Complete |
Body | mj-wrapper | ✅ | ✅ | Feature Complete |
Benchmarks
Performance was one of the key focuses for this project. We're aiming to support high througput while mainintaing low memory footprint. Below are the benchmarks for every public MJML template compiled (beautified and minified).
Important: These tests do not include loading or saving the template from/to disk.
If you'd like to run the benchmarks your self then you can run the Mjml.Net.Benchmarks
project in release
mode.
BenchmarkDotNet
> .\Mjml.Net.Benchmark.exe
Profiler
> .\Mjml.Net.Benchmark.exe -p -i 100
Benchmark Specs
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19043.1586 (21H1/May2021Update)
Intel Core i7-4790 CPU 3.60GHz (Haswell), 1 CPU, 8 logical and 4 physical cores
.NET SDK=6.0.101
[Host] : .NET 6.0.1 (6.0.121.56705), X64 RyuJIT
Job-YRBKPS : .NET 6.0.1 (6.0.121.56705), X64 RyuJIT
Jit=RyuJit Platform=X64 IterationCount=100
Benchmark Key
MjmlTemplateFilePath : Value of the 'MjmlTemplateFilePath' parameter
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Median : Value separating the higher half of all measurements (50th percentile)
Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
1 us : 1 Microsecond (0.000001 sec)
Benchmark Results
All times are in μs (1ms = 1000 μs)
Method | MjmlTemplateFilePath | Mean | Error | StdDev | Median | Allocated |
---|---|---|---|---|---|---|
Beautified | Amario.mjml | 924.9 | 7.24 | 20.42 | 920.8 | 810 KB |
Minified | Amario.mjml | 980.1 | 25.57 | 75.39 | 974.1 | 810 KB |
Beautified | Arturia.mjml | 438.2 | 9.29 | 27.38 | 438.9 | 384 KB |
Minified | Arturia.mjml | 430.0 | 8.62 | 25.28 | 430.9 | 384 KB |
Beautified | Austin.mjml | 762.0 | 13.06 | 38.30 | 759.7 | 615 KB |
Minified | Austin.mjml | 756.0 | 13.42 | 39.16 | 756.3 | 615 KB |
Beautified | BlackFriday.mjml | 188.3 | 4.39 | 12.94 | 189.2 | 186 KB |
Minified | BlackFriday.mjml | 194.7 | 4.99 | 14.31 | 197.0 | 186 KB |
Beautified | Card.mjml | 290.3 | 7.10 | 20.04 | 290.0 | 259 KB |
Minified | Card.mjml | 284.3 | 5.82 | 17.17 | 287.0 | 259 KB |
Beautified | Christmas.mjml | 413.5 | 8.55 | 25.09 | 417.3 | 360 KB |
Minified | Christmas.mjml | 401.5 | 7.19 | 21.20 | 403.1 | 360 KB |
Beautified | HappyNewYear.mjml | 156.3 | 3.30 | 9.72 | 156.4 | 166 KB |
Minified | HappyNewYear.mjml | 155.2 | 3.46 | 10.21 | 155.2 | 166 KB |
Beautified | ManyHeroes.mjml | 705.7 | 13.98 | 40.33 | 700.0 | 830 KB |
Minified | ManyHeroes.mjml | 667.6 | 9.15 | 26.41 | 653.7 | 830 KB |
Beautified | OnePage.mjml | 414.9 | 8.47 | 24.58 | 403.5 | 399 KB |
Minified | OnePage.mjml | 424.5 | 9.15 | 26.83 | 416.4 | 399 KB |
Beautified | Proof.mjml | 184.2 | 2.90 | 8.33 | 181.6 | 213 KB |
Minified | Proof.mjml | 189.0 | 3.53 | 9.90 | 186.8 | 213 KB |
Beautified | Racoon.mjml | 928.5 | 8.38 | 23.78 | 921.1 | 810 KB |
Minified | Racoon.mjml | 926.7 | 11.90 | 32.98 | 912.9 | 810 KB |
Beautified | Reactivation.mjml | 261.1 | 4.12 | 12.07 | 257.7 | 259 KB |
Minified | Reactivation.mjml | 263.5 | 5.63 | 16.34 | 260.6 | 259 KB |
Beautified | RealEstate.mjml | 707.6 | 11.65 | 33.43 | 701.2 | 623 KB |
Minified | RealEstate.mjml | 725.4 | 20.80 | 58.66 | 708.5 | 623 KB |
Beautified | Recast.mjml | 674.6 | 7.13 | 20.12 | 666.0 | 619 KB |
Minified | Recast.mjml | 661.1 | 3.86 | 10.63 | 659.8 | 619 KB |
Beautified | Receipt.mjml | 275.5 | 2.64 | 7.26 | 272.8 | 263 KB |
Minified | Receipt.mjml | 274.5 | 1.93 | 5.50 | 272.8 | 263 KB |
Beautified | Referral.mjml | 135.3 | 0.75 | 2.19 | 134.9 | 136 KB |
Minified | Referral.mjml | 133.4 | 0.86 | 2.43 | 132.8 | 136 KB |
Beautified | SpheroDroids.mjml | 376.4 | 2.28 | 6.43 | 374.7 | 351 KB |
Minified | SpheroDroids.mjml | 374.5 | 3.66 | 10.01 | 371.8 | 351 KB |
Beautified | SpheroMini.mjml | 395.9 | 4.43 | 12.79 | 390.4 | 368 KB |
Minified | SpheroMini.mjml | 395.4 | 2.11 | 6.13 | 394.3 | 368 KB |
Beautified | UGGRoyale.mjml | 1,126.0 | 6.03 | 17.09 | 1,122.9 | 1,004 KB |
Minified | UGGRoyale.mjml | 1,154.0 | 10.93 | 31.89 | 1,142.2 | 1,004 KB |
Beautified | Welcome.mjml | 125.1 | 0.89 | 2.49 | 124.1 | 131 KB |
Minified | Welcome.mjml | 126.3 | 1.51 | 4.42 | 125.3 | 131 KB |
Beautified | Worldly.mjml | 637.6 | 3.21 | 9.22 | 634.9 | 572 KB |
Minified | Worldly.mjml | 629.6 | 4.24 | 11.60 | 627.9 | 572 KB |
Known Issues
Unknown HTML Entity
We are aware with an issue where by using HTML Character Entities (e.g. ©
) are unknown and throw an unhandled exception during the rendering of the MJML document. This is because we use XmlReader as the main driver for parsing the MJML document.
The solution is to change the HTML Character Entity Names (e.g. ©
) to there corresponding HTML Character Entity Number (e.g. ©
) in the MJML document.
Here are some of the common HTML Character Entities:
Result | Description | Entity Name | Entity Number |
---|---|---|---|
non-breaking space | |
  |
|
< | less than | < |
< |
> | greater than | > |
> |
& | ampersand | & |
& |
" | double quotation mark | " |
" |
' | single quotation mark (apostrophe) | ' |
' |
© | copyright | © |
© |
® | registered trademark | ® |
® |
™ | registered trademark | ™ |
™ |
Non-encoded URL
We are aware of an issue with non-encoded URL's being recognized as character entities leading to an exception. This is because we use XmlReader as the main driver for parsing the MJML document. This solution is to URL encode all of the URLs in the template.
Contribution
We really appreciate any contribution to the project to help provide a native version of MJML to C#. Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Appreciations
Once again, it's good to share some appreciation to the projects that make MJML.NET
possible.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Microsoft.Extensions.ObjectPool (>= 6.0.3)
NuGet packages (5)
Showing the top 5 NuGet packages that depend on Mjml.Net:
Package | Downloads |
---|---|
Nextalys.Helpers
Package Description |
|
MailChemist
MailChemist is a combination of two technologies (MJML, and Fluid.NET) to dynamically generate beautiful responsive emails driven by templates. |
|
Holoon.MjmlToMail
Template tool for creating translatable e-mails by combining the three tools: scriban, I18Next.Net and mjml-net. |
|
Mjml.Net.PostProcessors
A blazingly-fast unofficial port of MJML (by MailJet) to .NET 6. |
|
Html.Net.PostProcessors
A blazingly-fast unofficial port of MJML (by MailJet) to .NET 6. |
GitHub repositories (2)
Showing the top 2 popular GitHub repositories that depend on Mjml.Net:
Repository | Stars |
---|---|
notifo-io/notifo
Multi channel notification service for collaboration tools, e-commerce, news service and more.
|
|
SebastianStehle/mjml-net
.NET Fork of MJML library with 10x performance and 100% feature parity
|
Version | Downloads | Last updated |
---|---|---|
4.4.0 | 15,919 | 10/1/2024 |
4.3.0 | 4,858 | 9/20/2024 |
4.2.0 | 889 | 9/20/2024 |
4.1.0 | 731 | 9/18/2024 |
4.0.0 | 111 | 9/18/2024 |
3.15.0 | 1,969 | 9/18/2024 |
3.14.0 | 174 | 9/18/2024 |
3.13.0 | 6,004 | 9/9/2024 |
3.12.0 | 30,589 | 7/23/2024 |
3.11.0 | 108,124 | 3/1/2024 |
3.10.0 | 14,629 | 2/20/2024 |
3.9.0 | 4,875 | 2/14/2024 |
3.8.0 | 13,756 | 2/4/2024 |
3.7.0 | 14,284 | 1/16/2024 |
3.6.0 | 125 | 1/16/2024 |
3.5.0 | 1,286 | 1/12/2024 |
3.4.0 | 24,564 | 11/27/2023 |
3.3.0 | 86,945 | 10/19/2023 |
3.2.0 | 14,897 | 10/6/2023 |
3.1.0 | 6,817 | 9/20/2023 |
3.0.0 | 11,297 | 8/26/2023 |
2.1.0-beta1 | 165 | 8/12/2023 |
2.0.0 | 2,530 | 8/11/2023 |
1.24.0 | 45,881 | 6/28/2023 |
1.23.0 | 36,518 | 5/22/2023 |
1.22.0 | 11,881 | 4/5/2023 |
1.21.0 | 42,659 | 3/5/2023 |
1.20.0 | 3,504 | 2/24/2023 |
1.19.0 | 1,309 | 2/24/2023 |
1.18.0 | 262 | 2/24/2023 |
1.17.0 | 58,818 | 12/21/2022 |
1.16.0 | 4,292 | 12/19/2022 |
1.15.0 | 5,927 | 12/13/2022 |
1.14.0 | 303 | 12/13/2022 |
1.13.0 | 296 | 12/13/2022 |
1.12.0 | 316 | 12/13/2022 |
1.11.0 | 33,444 | 10/29/2022 |
1.10.0 | 53,985 | 8/31/2022 |
1.9.0 | 564 | 8/27/2022 |
1.8.0 | 394 | 8/27/2022 |
1.7.0 | 11,444 | 8/1/2022 |
1.6.0 | 409 | 7/31/2022 |
1.5.0 | 412 | 7/31/2022 |
1.4.0 | 12,334 | 6/8/2022 |
1.3.0 | 4,864 | 5/27/2022 |
1.2.0 | 567 | 5/17/2022 |
1.1.1 | 549 | 5/4/2022 |
1.1.0 | 633 | 5/3/2022 |
1.0.4 | 421 | 5/3/2022 |
1.0.3 | 8,138 | 3/30/2022 |
1.0.2 | 428 | 3/30/2022 |
1.0.0 | 625 | 3/23/2022 |
0.3.0 | 477 | 3/20/2022 |
0.2.0 | 606 | 3/20/2022 |