The Blazor AI Chat component provides a conversational, streaming chat interface for building AI assistants and chatbot experiences.
Console log
Customize the appearance of the AIChat component using Style, ShowClearButton, Disabled, and ReadOnly properties.
Create a more compact chat interface suitable for smaller spaces or sidebar implementations.
Build the chrome of an assistant around the conversation. HeaderTemplate renders in the header next to the title, for example a conversation switcher;
InputHeaderTemplate and InputFooterTemplate render above and below the text box, for a status line, a model picker or action buttons.
SendButtonText, SendButtonIcon, StopButtonText and StopButtonIcon label the send and stop buttons, ShowAvatars="false" hides the avatars and @bind-Input reads or sets the text in the box - call FocusAsync to focus it.
With QueueMessages="true" a message sent while an answer streams is shown right away instead of being ignored: a service that implements IAIChatService.TryQueueMessageAsync takes it into the running answer,
otherwise it is sent when the answer completes and Stop drops it and returns the text to the box.
UsageTemplate formats the usage of an answer your way, for example credits from UsageDetails.AdditionalCounts, and MessageFooterTemplate adds content under every message.
When the model writes between tool calls, the answer keeps text and calls in the order they were produced; ChatMessage.GetParts() returns them in that order for your own MessageTemplate.
Entries that are not messages of the conversation - a status line, a progress indicator while something runs, an error - are added with AddMessage and a ChatMessage.Kind of Status, Progress or Error,
and removed with RemoveMessage; the Publish button of this demo adds them. A MessageTemplate can render some messages its own way and call RenderMessage for the rest.
Handle chat events like MessageAdded, MessageSent, ResponseReceived, and ChatCleared to integrate with your application logic.
Console log
Use TimestampFormat to control how the time is rendered next to each message, and ShowDateSeparator (with DateSeparatorFormat)
to insert a divider between messages whenever the day changes — useful when restoring long conversation history via LoadMessages.
Date & Time Options
The AIChat component supports conversation memory that remembers previous questions and maintains context across multiple interactions.
Use SessionId to maintain conversation state, UserId to tell whose conversation it is and SessionIdChanged to track session changes.
Conversations are kept in an IConversationStore: the default InMemoryConversationStore keeps them for the lifetime of the application, and AddConversationStore<TStore>()
plugs in your own - this demo uses one backed by Entity Framework that serializes each conversation with ConversationSessionSerializer, including tool calls, attachments and reasoning.
The store must live where the data survives a reload: on Blazor Server it runs in the server process, while the WebAssembly demo registers a store that calls a small API on the host, because the browser process restarts with every reload.
The service saves the conversation after every answer and GetSessionsAsync, GetOrCreateSessionAsync and DeleteSessionAsync manage the saved ones.
Current conversation
1b8a2342-d6fc-4697-91bb-b74cdcaac81dThe conversation is saved to the store after every answer. Reload the page or open another conversation and come back: the messages, tool calls and attachments are restored.
Saved conversations
1 saved, 6 messages
Give the model access to your application's data and logic with the Tools parameter. Tools are AIFunction instances from
Microsoft.Extensions.AI - create them from any C# method with AIFunctionFactory.Create and describe them with [Description] attributes.
The model decides when to call a tool, AIChat invokes it, shows the call in the conversation and feeds the result back to the model.
The ToolCallCompleted event fires when a tool finishes.
Console log
Use ToolCallTemplate to render tool results with Radzen components instead of text. The template receives a ChatToolCall with the tool
Name, Arguments, Status and Result; call GetResult<T>() to deserialize the result.
Ask for the sales by month to get a chart, or for the orders of a customer to get a data grid, directly in the conversation.
Wrap a tool in ApprovalRequiredAIFunction to ask the user before it runs. AIChat renders the call with its arguments and
Approve / Reject buttons, invokes the tool only when approved and tells the model when the call was rejected.
Use ToolCallTemplate with ApproveToolCall and RejectToolCall to build your own approval UI.
Product | Price | Discontinued |
|---|---|---|
| Alice Mutton | ¤39.00 | |
| Aniseed Syrup | ¤10.00 | |
| Boston Crab Meat | ¤18.40 | |
| Camembert Pierrot | ¤34.00 | |
| Carnarvon Tigers | ¤62.50 | |
| Chai | ¤18.00 | |
| Chang | ¤19.00 | |
| Chartreuse verte | ¤18.00 | |
| Chef Anton's Cajun Seasoning | ¤22.00 | |
| Chef Anton's Gumbo Mix | ¤21.35 | |
| Chocolade | ¤12.75 | |
| Côte de Blaye | ¤263.50 | |
| Escargots de Bourgogne | ¤13.25 | |
| Filo Mix | ¤7.00 | |
| Flotemysost | ¤21.50 | |
| Geitost | ¤2.50 | |
| Genen Shouyu | ¤15.50 | |
| Gnocchi di nonna Alice | ¤38.00 | |
| Gorgonzola Telino | ¤12.50 | |
| Grandma's Boysenberry Spread | ¤25.00 | |
| Gravad lax | ¤26.00 | |
| Guaraná Fantástica | ¤4.50 | |
| Gudbrandsdalsost | ¤36.00 | |
| Gula Malacca | ¤19.45 | |
| Gumbär Gummibärchen | ¤31.23 | |
| Gustaf's Knäckebröd | ¤21.00 | |
| Ikura | ¤31.00 | |
| Inlagd Sill | ¤19.00 | |
| Ipoh Coffee | ¤46.00 | |
| Jack's New England Clam Chowder | ¤9.65 | |
| Konbu | ¤6.00 | |
| Lakkalikööri | ¤18.00 | |
| Laughing Lumberjack Lager | ¤14.00 | |
| Longlife Tofu | ¤10.00 | |
| Louisiana Fiery Hot Pepper Sauce | ¤21.05 | |
| Louisiana Hot Spiced Okra | ¤17.00 | |
| Manjimup Dried Apples | ¤53.00 | |
| Mascarpone Fabioli | ¤32.00 | |
| Maxilaku | ¤20.00 | |
| Mishi Kobe Niku | ¤97.00 | |
| Mozzarella di Giovanni | ¤34.80 | |
| Nord-Ost Matjeshering | ¤25.89 | |
| Northwoods Cranberry Sauce | ¤40.00 | |
| NuNuCa Nuß-Nougat-Creme | ¤14.00 | |
| Original Frankfurter grüne Soße | ¤13.00 | |
| Outback Lager | ¤15.00 | |
| Pâté chinois | ¤24.00 | |
| Pavlova | ¤17.45 | |
| Perth Pasties | ¤32.80 | |
| Queso Cabrales | ¤21.00 | |
| Queso Manchego La Pastora | ¤38.00 | |
| Raclette Courdavault | ¤55.00 | |
| Ravioli Angelo | ¤19.50 | |
| Rhönbräu Klosterbier | ¤7.75 | |
| Röd Kaviar | ¤15.00 | |
| Rogede sild | ¤9.50 | |
| Rössle Sauerkraut | ¤45.60 | |
| Sasquatch Ale | ¤14.00 | |
| Schoggi Schokolade | ¤43.90 | |
| Scottish Longbreads | ¤12.50 | |
| Singaporean Hokkien Fried Mee | ¤14.00 | |
| Sir Rodney's Marmalade | ¤81.00 | |
| Sir Rodney's Scones | ¤10.00 | |
| Sirop d'érable | ¤28.50 | |
| Spegesild | ¤12.00 | |
| Steeleye Stout | ¤18.00 | |
| Tarte au sucre | ¤49.30 | |
| Teatime Chocolate Biscuits | ¤9.20 | |
| Thüringer Rostbratwurst | ¤123.79 | |
| Tofu | ¤23.25 | |
| Tourtière | ¤7.45 | |
| Tunnbröd | ¤9.00 | |
| Uncle Bob's Organic Dried Pears | ¤30.00 | |
| Valkoinen suklaa | ¤16.25 | |
| Vegie-spread | ¤43.90 | |
| Wimmers gute Semmelknödel | ¤33.25 | |
| Zaanse koeken | ¤9.50 |
Console log
Combine AIChat with RadzenSpeechToTextButton to let users talk to the assistant: the button captures speech with the browser's speech recognition
and its Change event passes the transcript to SendMessage.
Set AllowAttachments="true" to let users attach files with the paperclip button, or add them from code with AddAttachment. Images are sent to a multimodal model as image content
and shown in the conversation; text files such as txt, csv, md, json or xml are sent as text, so any model can answer questions about them; PDF files are sent as file content for providers that support it (OpenAI). MaxAttachmentSize, MaxTotalAttachmentSize and AcceptedAttachmentTypes limit what can be attached, AttachmentAdding receives every picked file so you can reject it or replace it
(for example with a scaled down image) and the Error event reports files that cannot be read. ShowUsage displays the tokens the provider reports for each answer and the stop button next to the input cancels a response that is still streaming.
Console log
Answers can show the sources they are based on. A tool that returns ChatCitation instances (title, URL, snippet) sends them to the model as its result and the chat lists them under the answer as numbered links,
so the model can cite them as [1], [2] in the text. Providers that annotate their responses - OpenAI web search, Perplexity, Azure AI Search and others - arrive the same way: the client maps their annotations to
CitationAnnotation of Microsoft.Extensions.AI and the chat collects them in ChatMessage.Citations. ShowCitations hides the list and CitationTemplate renders a source your way.
This demo searches a small documentation index with a tool; replace it with your search service or vector store.
Console log
AIChat talks to the model through the IChatClient abstraction of Microsoft.Extensions.AI.
AddAIChatService configures the built-in OpenAICompatibleChatClient, which works with any OpenAI-compatible chat completions endpoint
(OpenAI, Azure OpenAI, Ollama, LM Studio, Cloudflare Workers AI and others) and supports streaming and tool calling.
builder.Services.AddAIChatService(options =>
{
options.Endpoint = "https://api.openai.com/v1/chat/completions";
options.ApiKey = builder.Configuration["OpenAI:ApiKey"];
options.Model = "gpt-4o-mini";
options.EmbeddingsModel = "text-embedding-3-small";
});
In Blazor Server the options above live on the server and the key never reaches the browser. In a WebAssembly application everything in the client is visible to its users, so the service refuses an API key there:
set Proxy to an endpoint of your server instead and let the server add the key, as this demo does with options.Proxy = "api/chat/completions" in the client and a ChatController in the host
that forwards the body to the provider with the key from its configuration (EmbeddingsProxy does the same for embeddings). Protect that endpoint with [Authorize], otherwise every visitor can spend your quota,
and decide on the server which models, token limits and system prompts the client may use.
To use a different provider, register its IChatClient and AIChat picks it up automatically. Any middleware added with
ChatClientBuilder (logging, caching, OpenTelemetry, rate limiting) applies to the chat as well.
// OpenAI (Microsoft.Extensions.AI.OpenAI)
builder.Services.AddChatClient(new OpenAIClient(apiKey).GetChatClient("gpt-4o-mini").AsIChatClient())
.UseLogging();
// Azure OpenAI (Azure.AI.OpenAI + Microsoft.Extensions.AI.OpenAI)
builder.Services.AddChatClient(new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()).GetChatClient("gpt-4o-mini").AsIChatClient());
// Ollama (OllamaSharp)
builder.Services.AddChatClient(new OllamaApiClient(new Uri("http://localhost:11434"), "llama3.2"));
builder.Services.AddAIChatService();
Customize AI behavior at runtime by configuring the Model, Temperature, MaxTokens, SystemPrompt, Endpoint and Proxy parameters.
These parameters can be set on the component or passed to the SendMessage method to override settings per message, enabling dynamic switching between different AI providers and models.
ApiKey and ApiKeyHeader exist for Blazor Server only; a WebAssembly client must go through a server Proxy, as described under AI providers.
AI Configuration
Current Configuration
Model: @cf/openai/gpt-oss-120b
Total Messages: 0
Available Models
@cf/openai/gpt-oss-120b
Active@cf/meta/llama-3.3-70b-instruct-fp8-fast
@cf/meta/llama-4-scout-17b-16e-instruct
@cf/mistral/mistral-7b-instruct-v0.1
It is a chat UI for AI assistants, with a conversational layout and support for streaming responses as they are generated.
Yes. Pass AIFunction tools created with AIFunctionFactory to the Tools parameter. The model calls them, the component invokes them and renders the calls; wrap a tool in ApprovalRequiredAIFunction to ask the user first.
Any OpenAI-compatible endpoint out of the box, and any Microsoft.Extensions.AI IChatClient (OpenAI, Azure OpenAI, Ollama and others) registered in the service collection.
Radzen Blazor Components, © 2018-2026 Radzen.
Source Code licensed under
MIT