This example enables AI-powered extensions for both the DevExpress Blazor Rich Text Editor and HTML Editor. These extensions supply AI functions designed to process text/HTML content.
Implementation Details
Both the DevExpress Blazor Rich Text Editor (DxRichEdit) and Blazor HTML Editor (DxHtmlEditor) ship with an AdditionalItems
property. You can populate this property with commands and allow users to process editor text as needs dictate. Available commands for both editors are as follows:
- Ask AI Assistant allows user to process text based on a custom prompt.
- Change Style rewrite text using a specified style.
- Change Tone rewrite text using a specified tone.
- Describe Picture generates the description for an image (for Rich Text Editor only).
- Expand expands text.
- Explain explains text.
- Proofread proofreads text.
- Shorten shortens text.
- Summarize summarizes text.
- Translate translates text into the specified language.
Register AI Services
[!NOTE]
DevExpress AI-powered extensions follow the "bring your own key" principle. DevExpress does not offer a REST API and does not ship any built-in LLMs/SLMs. You need an active Azure/Open AI subscription to obtain the REST API endpoint, key, and model deployment name. These variables must be specified at application startup to register AI clients and enable DevExpress AI-powered Extensions in your application.
Add the following code to the Program.cs file to register AI services in the application:
C#using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
...
string azureOpenAIEndpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");
string azureOpenAIKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY");
string deploymentName = string.Empty;
IChatClient chatClient = new AzureOpenAIClient(
new Uri(azureOpenAIEndpoint),
new AzureKeyCredential(azureOpenAIKey)).AsChatClient(deploymentName);
builder.Services.AddDevExpressBlazor();
builder.Services.AddChatClient(config => config.Use(chatClient));
builder.Services.AddDevExpressAI();
Enable AI-powered extension for the DevExpress Blazor Rich Text Editor
AI-powered extension for our Blazor Rich Text Editor adds AI-related commands to the editor's context menu.
You can add predefined commands or implement custom commands as necessary. This example introduces a Rewrite like Shakespeare context menu item.
C#public class ShakespeareAIContextMenuItem : BaseAIContextMenuItem {
[Inject] IAIExtensionsContainer? aIExtensionsContainer { get; set; }
protected override string DefaultItemText => "Rewrite like Shakespeare";
protected override Task<TextResponse> GetCommandTextResult(string text) {
var customExtension = aIExtensionsContainer.CreateCustomPromptExtension();
return customExtension.ExecuteAsync(new CustomPromptRequest("Rewrite the following text in William Shakespeare style.", text));
}
}
Declare DxRichEdit's AdditionalItems and populate it with commands in the following manner:
Razor@using DevExpress.AIIntegration.Blazor.RichEdit
@using DevExpress.Blazor.RichEdit
<DxRichEdit DocumentContent="DocumentContent" CssClass="my-editor">
<AdditionalItems>
<ShakespeareAIContextMenuItem />
<SummarizeAIContextMenuItem />
<ExplainAIContextMenuItem />
<ProofreadAIContextMenuItem />
<ExpandAIContextMenuItem />
<ShortenAIContextMenuItem />
<AskAssistantAIContextMenuItem />
<ChangeStyleAIContextMenuItem />
<ChangeToneAIContextMenuItem />
<TranslateAIContextMenuItem Languages="@("German, French, Chinese")" />
</AdditionalItems>
</DxRichEdit>
Enable AI-powered extension for the DevExpress Blazor HTML Editor
The AI-powered extension for our Blazor HTML Editor adds AI-related commands to the editor's toolbar.
You can add predefined commands or implement custom commands as necessary. This example introduces a Rewrite like Shakespeare toolbar item.
C#public class ShakespeareAIToolbarItem: BaseAIToolbarItem {
[Inject] IAIExtensionsContainer? aIExtensionsContainer { get; set; }
protected override string DefaultItemText => "Rewrite like Shakespeare";
protected override Task<TextResponse> GetCommandTextResult(string text) {
var customExtension = aIExtensionsContainer.CreateCustomPromptExtension();
return customExtension.ExecuteAsync(new CustomPromptRequest("Rewrite the following text in William Shakespeare style.", text));
}
}
Declare DxHtmlEditor's AdditionalItems and populate it with commands in the following manner:
Razor@using DevExpress.AI.Samples.Blazor.Editors.Components.AdditionalItems
@using DevExpress.AIIntegration.Blazor.HtmlEditor
<DxHtmlEditor @bind-Markup="Value" CssClass="my-editor" BindMarkupMode="HtmlEditorBindMarkupMode.OnLostFocus">
<AdditionalItems>
<ShakespeareAIToolbarItem />
<SummarizeAIToolbarItem />
<ExplainAIToolbarItem />
<ProofreadAIToolbarItem />
<ExpandAIToolbarItem />
<ShortenAIToolbarItem />
<AskAssistantAIToolbarItem />
<ChangeStyleAIToolbarItem />
<ChangeToneAIToolbarItem />
<TranslateAIToolbarItem Languages="@("German, French, Chinese")" />
</AdditionalItems>
</DxHtmlEditor>
Files to Review
- RichEdit.razor
- HtmlEditor.razor
- ShakespeareAIContextMenuItem.cs
- ShakespeareAIToolbarItem.cs
- Program.cs
Documentation
- DevExpress AI-powered Extensions for Blazor
- AI-powered Extension for Blazor Rich Text Editor
- AI-powered Extension for Blazor HTML Editor
Online Demo
More Examples
- AI Chat for Blazor — How to add DxAIChat component in Blazor, MAUI, WPF, and WinForms applications
- Blazor Grid and Report Viewer — Incorporate an AI Assistant (Azure OpenAI) in your next DevExpress-powered Blazor app
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
Razor@page "/"
@using DevExpress.AIIntegration.Blazor.RichEdit
@using DevExpress.AI.Samples.Blazor.Editors.Components.AdditionalItems
@using DevExpress.Blazor.RichEdit
@using System.Reflection
<DxRichEdit DocumentContent="DocumentContent" CssClass="my-editor">
<AdditionalItems>
<ShakespeareAIContextMenuItem />
<SummarizeAIContextMenuItem />
<ExplainAIContextMenuItem />
<ProofreadAIContextMenuItem />
<ExpandAIContextMenuItem />
<ShortenAIContextMenuItem />
<AskAssistantAIContextMenuItem />
<ChangeStyleAIContextMenuItem />
<ChangeToneAIContextMenuItem />
<TranslateAIContextMenuItem Languages="@("German, French, Chinese")" />
</AdditionalItems>
</DxRichEdit>
@code {
const string DocumentResourceName = "DevExpress.AI.Samples.Blazor.Editors.Docs.Example.docx";
byte[] DocumentContent { get; set; }
protected override void OnInitialized()
{
using (var ms = new MemoryStream())
{
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(DocumentResourceName);
stream?.CopyTo(ms);
DocumentContent = ms.ToArray();
}
base.OnInitialized();
}
}
Razor@page "/htmleditor"
@using DevExpress.AI.Samples.Blazor.Editors.Components.AdditionalItems
@using DevExpress.AIIntegration.Blazor.HtmlEditor
<DxHtmlEditor @bind-Markup="Value" CssClass="my-editor" BindMarkupMode="HtmlEditorBindMarkupMode.OnLostFocus">
<AdditionalItems>
<ShakespeareAIToolbarItem />
<SummarizeAIToolbarItem />
<ExplainAIToolbarItem />
<ProofreadAIToolbarItem />
<ExpandAIToolbarItem />
<ShortenAIToolbarItem />
<AskAssistantAIToolbarItem />
<ChangeStyleAIToolbarItem />
<ChangeToneAIToolbarItem />
<TranslateAIToolbarItem Languages="@("German, French, Chinese")" />
</AdditionalItems>
</DxHtmlEditor>
@code {
public string Value { get; set; } = @"<h2>
HTML Editor
</h2><br>
<p>The HTML Editor component for Blazor is a WYSIWYG (what you see is what you get) text editor that allows users to format text and add graphics. The document can use HTML or Markdown format.</p>
<p>Supported features:</p>
<ul>
<li>Inline formats:
<ul>
<li><strong>Bold</strong>, <em>italic</em>, <s>strikethrough</s> text formatting</li>
<li>Font, size, color changes (HTML only)</li>
</ul>
</li>
<li>Block formats:
<ul>
<li>Headings</li>
<li>Text alignment</li>
<li>Lists (bullet and numbered)</li>
<li>Code blocks</li>
<li>Quotes</li>
</ul>
</li>
<li>HTML and Markdown support</li>
<li>Variable support: produce documents based on templates</li>
<li>Toolbar with adaptive layout support</li>
<li>Insert images: specify a URL or upload from the local file system</li>
<li>Table support</li>
</ul>
<p>Supported browsers:
<table>
<tbody>
<tr>
<td><strong>Google Chrome (including Android)</strong></td>
<td>Latest</td>
</tr>
<tr>
<td><strong>Apple Safari (including iOS)</strong></td>
<td>Latest</td>
</tr>
<tr>
<td><strong>Mozilla Firefox</strong></td>
<td>Latest</td>
</tr>
<tr>
<td><strong>Microsoft Edge</strong></td>
<td>Latest</td>
</tr>
<tr>
<td><strong><a href='https://support.microsoft.com/en-us/microsoft-edge/what-is-microsoft-edge-legacy-3e779e55-4c55-08e6-ecc8-2333768c0fb0' rel='noopener noreferrer' target='_blank'>Microsoft Edge Legacy</a></strong></td>
<td>Not supported</td>
</tr>
</tbody>
</table>
<br>";
}
C#using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Blazor.HtmlEditor;
using DevExpress.AIIntegration.Extensions;
using Microsoft.AspNetCore.Components;
namespace DevExpress.AI.Samples.Blazor.Editors.Components.AdditionalItems {
public class ShakespeareAIToolbarItem: BaseAIToolbarItem {
[Inject] IAIExtensionsContainer? aIExtensionsContainer { get; set; }
protected override string DefaultItemText => "Rewrite like Shakespeare";
protected override Task<TextResponse> GetCommandTextResult(string text) {
var customExtension = aIExtensionsContainer.CreateCustomPromptExtension();
return customExtension.ExecuteAsync(new CustomPromptRequest("Rewrite the following text in William Shakespeare style.", text));
}
}
}
C#using Azure;
using Azure.AI.OpenAI;
using DevExpress.AI.Samples.Blazor.Editors.Components;
using Microsoft.Extensions.AI;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
string azureOpenAIEndpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");
string azureOpenAIKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY");
string deploymentName = string.Empty;
IChatClient chatClient = new AzureOpenAIClient(
new Uri(azureOpenAIEndpoint),
new AzureKeyCredential(azureOpenAIKey)).AsChatClient(deploymentName);
builder.Services.AddDevExpressBlazor();
builder.Services.AddChatClient(config => config.Use(chatClient));
builder.Services.AddDevExpressAI();
var app = builder.Build();
// Configure the HTTP request pipeline.
if(!app.Environment.IsDevelopment()) {
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.Run();