A Blazor component library for editing Razor templates with Monaco Editor and live preview using RazorLight.
- 🎨 Monaco Editor Integration - Professional code editor with Razor syntax highlighting
- 🔍 Live Preview - Real-time template rendering using RazorLight
- 📋 Model Properties Panel - Easy insertion of
@Modelproperties - ⚡ Simple Architecture - Clean, easy-to-understand codebase
- 🚀 No Complex Dependencies - Just Monaco and RazorLight
Install via NuGet Package Manager:
dotnet add package BlazorHtmlEditorOr via Package Manager Console:
Install-Package BlazorHtmlEditorIn your Program.cs:
using BlazorHtmlEditor.Services;
builder.Services.AddScoped<IModelMetadataProvider, ModelMetadataProvider>();
builder.Services.AddScoped<IRazorRenderService, RazorRenderService>();In your App.razor or index.html:
<body>
<!-- Your Blazor app -->
<script src="_framework/blazor.web.js"></script>
<!-- Monaco Editor from CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.45.0/min/vs/loader.min.js"></script>
<script>
require.config({ paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.45.0/min/vs' } });
</script>
<!-- BlazorHtmlEditor scripts -->
<script type="module" src="_content/BlazorHtmlEditor/js/monaco-interop.js"></script>
</body>@page "/template-editor"
@using BlazorHtmlEditor.Components
@using YourApp.Models
<TemplateEditor TModel="Customer"
Title="Customer Template Editor"
InitialContent="@initialTemplate"
ShowSaveButton="true"
ShowPropertiesPanel="true"
DefaultTab="EditorTab.Code"
OnSave="HandleSave" />
@code {
private string initialTemplate = @"
@model Customer
<div class='customer-card'>
<h1>@Model.FirstName @Model.LastName</h1>
<p>Email: @Model.Email</p>
<p>Phone: @Model.Phone</p>
</div>
";
private void HandleSave(string template)
{
// Save your template
Console.WriteLine("Template saved!");
}
}public class Customer
{
public string FirstName { get; set; } = "";
public string LastName { get; set; } = "";
public string Email { get; set; } = "";
public string Phone { get; set; } = "";
}Add these properties to enable RazorLight:
<PropertyGroup>
<PreserveCompilationContext>true</PreserveCompilationContext>
<CopyRefAssembliesToPublishDirectory>true</CopyRefAssembliesToPublishDirectory>
</PropertyGroup>| Parameter | Type | Default | Description |
|---|---|---|---|
TModel |
Generic Type | - | The model type for the template |
Title |
string | "Razor Template Editor" | Editor title |
InitialContent |
string | "" | Initial Razor template content |
ShowSaveButton |
bool | true | Show/hide the Save button |
ShowPropertiesPanel |
bool | true | Show/hide Model Properties panel |
DefaultTab |
EditorTab | Code | Default tab (Code or Preview) |
OnContentChanged |
EventCallback | - | Fired when content changes |
OnSave |
EventCallback | - | Fired when Save button clicked |
BlazorHtmlEditor/
├── Components/
│ ├── TemplateEditor.razor # Main editor with Code/Preview tabs
│ ├── TemplatePreview.razor # Live preview with RazorLight
│ ├── RazorCodeEditor.razor # Monaco editor wrapper
│ └── ModelPropertiesPanel.razor # Model properties browser
│
├── Services/
│ ├── IRazorRenderService.cs # Template rendering interface
│ ├── RazorRenderService.cs # RazorLight implementation
│ └── ModelMetadataProvider.cs # Model reflection service
│
└── Models/
├── ModelPropertyInfo.cs # Property metadata
└── TemplateModelMeta.cs # Model metadata
public class EmailTemplate
{
public string Subject { get; set; } = "";
public string RecipientName { get; set; } = "";
public string Message { get; set; } = "";
}<TemplateEditor TModel="EmailTemplate"
Title="Email Template Editor"
InitialContent="@emailTemplate" />public class Invoice
{
public string InvoiceNumber { get; set; } = "";
public DateTime InvoiceDate { get; set; }
public string CustomerName { get; set; } = "";
public decimal TotalAmount { get; set; }
}<TemplateEditor TModel="Invoice"
Title="Invoice Template Editor"
InitialContent="@invoiceTemplate" />- .NET 8.0 or higher
- Blazor Server or Blazor WebAssembly
Microsoft.AspNetCore.Components.Web(8.0.0)RazorLight(2.3.1)
- RazorLight requires
PreserveCompilationContext=truein your project - Complex Razor features (sections, layouts) not supported in preview
- Preview uses in-memory compilation (no file system access)
Add to your .csproj:
<PropertyGroup>
<PreserveCompilationContext>true</PreserveCompilationContext>
<CopyRefAssembliesToPublishDirectory>true</CopyRefAssembliesToPublishDirectory>
</PropertyGroup>Ensure Monaco JS files are included in your project. The component uses CDN by default.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Monaco Editor - Microsoft's code editor
- RazorLight - Razor template engine
- 🐛 Report a bug
- 💡 Request a feature
- 📧 Contact: GitHub Issues