<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~files/atom-premium.xsl"?>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedpress="https://feed.press/xmlns" xmlns:media="http://search.yahoo.com/mrss/" xmlns:podcast="https://podcastindex.org/namespace/1.0">
  <feedpress:locale>en</feedpress:locale>
  <link rel="hub" href="https://feedpress.superfeedr.com/"/>
  <logo>https://static.feedpress.com/logo/telerik-blogs-web-blazor-61850150254c2.jpg</logo>
  <title type="text">Telerik Blogs | Web | Blazor</title>
  <subtitle type="text">The official blog of Progress Telerik - expert articles and tutorials for developers.</subtitle>
  <id>uuid:ef233391-5030-4295-b2b7-e7980cca24b2;id=4755</id>
  <updated>2026-04-11T21:15:17Z</updated>
  <link rel="alternate" href="https://www.telerik.com/"/>
  <link rel="self" type="application/atom+xml" href="https://feeds.telerik.com/blogs/web-blazor"/>
  <entry>
    <id>urn:uuid:9bf61f7e-e7a4-44d4-aba4-e8c1fc74615b</id>
    <title type="text">Progress Telerik Agentic UI Generator vs. Syncfusion Agentic UI Builder</title>
    <summary type="text">See how the AI-based UI creation tools from devtools powerhouses Progress and Syncfusion stack up when they go head to head.</summary>
    <published>2026-04-08T16:38:33Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Hassan Djirdeh </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17315934/progress-telerik-agentic-ui-generator-vs-syncfusion-agentic-ui-builder"/>
    <content type="text"><![CDATA[<p><span class="featured">See how the AI-based UI creation tools from devtools powerhouses Progress and Syncfusion stack up when they go head to head. </span></p><p>AI-powered code generation has become a significant part of how developers build user interfaces. The <a target="_blank" href="https://survey.stackoverflow.co/2025/ai/#1-ai-tools-in-the-development-process">2025 Stack Overflow Developer Survey</a> found that 84% of developers are now using or planning to use AI tools in their development process.</p><p>Original AI adoption has been through tools like code autocompletion and chat-based assistants, but agentic UI tools take things further. Rather than suggesting the next line of code, they can take a natural language prompt and produce working, styled UI code in seconds.</p><p>However, not all AI generation tools are created equal. The quality of the output, how reliably it builds on the first attempt, how fast it runs and how well it handles things like accessibility and theming can vary quite a bit between tools. These differences matter because a tool that requires a large number of follow-up prompts to correct errors or produce code that doesn&rsquo;t match the original requirements isn&rsquo;t truly saving us time.</p><p>In this article, we&rsquo;ll look at a head-to-head comparison between two agentic UI generation tools: the <strong>Progress Telerik Agentic UI Generator</strong> which includes the <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/ai/agentic-ui-generator/getting-started">Blazor Agentic UI Generator for .NET/Blazor</a> and the <a target="_blank" href="https://www.telerik.com/kendo-react-ui/components/ai-tools/agentic-ui-generator/getting-started">Kendo UI Generator for Angular and React</a>, and the <a target="_blank" href="https://www.syncfusion.com/explore/agentic-ui-builder/"><strong>Syncfusion Agentic UI Builder</strong></a>. We&rsquo;ll walk through the results of extensive testing across multiple frameworks, covering output quality, performance, stability, accessibility, theming and more.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-04/progress-vs-syncfusion.jpg?sfvrsn=d281e72b_2" alt="Progress Telerik vs. Syncfusion" /></p><h2 id="how-the-comparison-was-conducted">How the Comparison Was Conducted</h2><p>To make this comparison as fair and thorough as possible, both tools were tested across multiple frameworks using two evaluation approaches.</p><h3 id="blazor.net">Blazor/.NET</h3><p>On the Blazor/.NET side, 23 prompts were run through the Telerik Agentic UI Generator and the Syncfusion Agentic UI Builder. These prompts ranged from simple single-component requests to complex multi-section layouts like e-commerce catalog pages and CMS admin dashboards. Each prompt&rsquo;s output was rated on a 0 to 7 scale:</p><ul><li><strong>0-1</strong>: Doesn&rsquo;t build or crashes with no UI</li><li><strong>2-3</strong>: Partially renders, major sections broken</li><li><strong>4</strong>: Renders but requires multiple prompts to clear build or runtime errors</li><li><strong>5</strong>: Renders but doesn&rsquo;t match prompt requirements in several areas</li><li><strong>6</strong>: Mostly complete, minor issues</li><li><strong>7</strong>: Fully matches requirements</li></ul><p>The evaluation also tracked how many prompts were needed before the output could successfully build and render, as well as the time (in seconds) from initial prompt submission to output generation.</p><h3 id="angular-and-react">Angular and React</h3><p>For Angular and React, a dedicated evaluation was conducted comparing the Kendo Agentic UI Generator against the Syncfusion Agentic UI Builder. Rather than scoring individual prompts, this evaluation focused on a technical comparison of the tools themselves. By running many prompts and examining the context returned by each tool, the analysis compared how each MCP server helps the AI agent arrive at its output across categories like layout, styling, accessibility, documentation and component handling.</p><h2 id="output-quality-and-reliability">Output Quality and Reliability</h2><p>This is the category where the gap between the two tools becomes immediately clear.</p><p>Across the 23 Blazor prompts, the Telerik Agentic UI Generator consistently produced complete, requirement-matching output on the first attempt. The Syncfusion Agentic UI Builder told a different story. It experienced <strong>five failures</strong> where no usable UI was generated at all, and several other prompts that required follow-up prompts to fix errors before the output could even build. Let&rsquo;s look at a couple of examples.</p><h3 id="failures">Failures</h3><p>The very first prompt asked both tools to build a login screen with email/password validation and an admin dashboard with a sidebar menu, key metrics and recent activity.</p><p><strong>Prompt</strong>: <em>&ldquo;I have created an empty application that now needs a login screen and an admin dashboard. Add a login form with email/password fields and validation. After a successful login, redirect to an admin dashboard page featuring a sidebar menu and a main content area displaying key metrics and recent activity.&rdquo;</em></p><p>The Telerik Generator produced a fully working output on the first attempt.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-04/blazor-agentic-ui-prompt-1.png?sfvrsn=ead93eba_1" alt="Telerik UI Generator produced dashboard" /></p><p>The Syncfusion Builder returned an error along the lines of: <code>Error. This response is truncated because it is too long. Try rephrasing your question.</code> No UI was generated at all.</p><p>The second prompt told both tools to create a monitoring dashboard with system health KPIs, a log stream panel, charts for API response times and requests per service.</p><p><strong>Prompt</strong>: <em>&ldquo;Create a new page using the existing top navigation and footer. In the middle, add 3 rows with 3 responsive columns each. The top row shows system health KPIs for CPU, memory and error counts. The middle rows include a Log Stream panel, a line Chart of API response times and a bar chart of requests per service. The bottom row contains a Deployment History table, an Alerts panel and a list of open tickets.&rdquo;</em></p><p>The Telerik Generator again produced a fully working output on the first pass.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-04/blazor-agentic-ui-prompt-2.png?sfvrsn=150ecc0b_1" alt="Telerik Generator produced dashboard with graphs" /></p><p>The Syncfusion Builder hit the same truncation error.</p><p>These are the kinds of prompts that represent real-world use cases. A login screen with a dashboard and a monitoring page with multiple data panels aren&rsquo;t unusual requests.</p><h3 id="errors-requiring-follow-ups">Errors Requiring Follow-ups</h3><p>Not every issue is an error during the generation process. Some prompts produced output that needed additional work to get running.</p><p>We fired a prompt to ask for a product catalog page with a responsive layout, product cards, a filtering toolbar and expandable detail views. The Telerik Generator handled it cleanly on the first attempt. The Syncfusion Builder hit an error about a missing component parameter and needed a second follow-up prompt to fix it.</p><p><strong>Prompt</strong>: <em>&ldquo;Create a product catalog page with a responsive CSS layout. The layout should display product cards. Add a toolbar with filtering options, and expandable detail view for each product that work seamlessly on mobile, tablet, and desktop.&rdquo;</em></p><p>The first output by the Telerik Blazor generator:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-04/blazor-agentic-ui-prompt-4.png?sfvrsn=5b3d958b_1" alt="Telerik Blazor AI UI Generator produced product catalog" /></p><p>The final output from Syncfusion, after the necessary follow-up prompt:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-04/syncfusion-agentic-ui-prompt-4.png?sfvrsn=a91f64f0_1" alt="Syncfusion product catalog" /></p><p>The Syncfusion Builder&rsquo;s errors in these cases often involved referencing component parameters that don&rsquo;t exist, which may suggest the tool&rsquo;s AI agent is working with less reliable component information during generation.</p><h3 id="partial-results">Partial Results</h3><p>Not all issues showed up as crashes or errors needing follow-ups. Let&rsquo;s look at an example of a prompt that was made which involved a theming request.</p><p><strong>Prompt</strong>: <em>&ldquo;Generate a custom theme for a corporate blue and green color scheme with high contrast accessibility requirements.&rdquo;</em></p><p>The Telerik Agentic UI Generator created the output matching the requirements.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-04/blazor-agentic-ui-prompt-13.png?sfvrsn=ed53d11a_1" alt="Telerik Agentic UI generator blue n=and green" /></p><p>The Syncfusion Builder did create a custom theme, but the expected theme wasn&rsquo;t applied to the output.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-04/syncfusion-agentic-ui-prompt-13.png?sfvrsn=eaac1328_1" alt="Syncfusion green and blue missing" /></p><h3 id="the-bigger-picture">The Bigger Picture</h3><p>Even when we set aside the failures and only look at prompts where the Syncfusion Builder produced something usable, the outputs still frequently fell short of the original requirements.</p><p>On the Angular and React side, the findings were consistent. While the final rendered UI sometimes appeared similar at a glance, the most significant differences were in how each tool&rsquo;s MCP server helped the agent arrive at that output. The Kendo Generator&rsquo;s tools consistently delivered more relevant, targeted context to the AI agent, filtering results to what was actually needed for the prompt. The Syncfusion Builder&rsquo;s tools returned broader, less filtered responses, often including full component prop lists and governance rules regardless of what was asked.</p><h2 id="performance">Performance</h2><p>Speed matters when we&rsquo;re iterating on UI designs with AI. Waiting several minutes for a complex layout to generate can significantly slow down the development flow.</p><p>Across the Blazor evaluation, the Telerik Generator was consistently faster. The speed advantage was most noticeable on complex layout prompts. For example, on a complex e-commerce catalog page with filtering, sorting, responsive breakpoints and pagination, the Telerik Generator completed in about 799 seconds while the Syncfusion Builder took 908 seconds.</p><p>There was one outlier where Syncfusion was notably faster (a simpler single-component case), but across the full set of 23 prompts, the speed advantage consistently favored Telerik.</p><h2 id="accessibility">Accessibility</h2><p>Accessibility is often treated as an afterthought, but for enterprise applications, it&rsquo;s a requirement, not a nice-to-have!</p><p>The Kendo Generator includes a dedicated accessibility tool (<a target="_blank" href="https://www.telerik.com/kendo-react-ui/components/ai-tools/agentic-ui-generator/prompt-library#accessibility-assistant">#kendo_accessibility_assistant</a>) that retrieves WCAG 2.2 Level AA guidelines as a mandatory step in the generation process. It also fetches component-specific accessibility requirements for each component used in the output. This leads to every piece of generated UI having accessibility considerations baked in from the start.</p><p>From what we can gather, and at the time of writing, the Syncfusion Builder doesn&rsquo;t have a strong accessibility tool like the <code>#kendo_accessibility_assistant</code>.</p><h2 id="theming-layout-and-documentation">Theming, Layout and Documentation</h2><p>Beyond output quality and speed, the Angular and React evaluation revealed some important architectural differences in how each tool handles theming, layout and documentation.</p><h3 id="theming">Theming</h3><p><strong>Theming</strong> is more than color selection. The Kendo UI Generator produces a complete design system from a single prompt, including colors, typography, spacing scales, border radius, elevation and shadows. The Syncfusion Builder&rsquo;s style tool is limited to component state colors and semantic colors. Typography, spacing and elevation aren&rsquo;t reachable through it, so the generated output may look right in terms of color but lack the design coherence that holds a full application together.</p><h3 id="layout">Layout</h3><p><strong>Layout</strong> is also where a notable dependency difference comes in. The Kendo UI Generator uses a self-contained layout system built on its own CSS utilities, introducing no external dependencies. The Syncfusion Builder relies on <a target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a>, injected into every project, and works from a catalog of 265+ prebuilt blocks. When the desired layout doesn&rsquo;t match a catalog entry, the result approximates what was asked for.</p><p>For teams already using Tailwind, this might feel natural but for projects on a different CSS framework (<a target="_blank" href="https://material.angular.dev/">Angular Material</a>, for example), adding Tailwind on top can introduce style conflicts. This can also be a potential blocker for organizations that restrict third-party dependencies.</p><p>Responsiveness follows a similar split: the Kendo UI Generator has a dedicated phase with explicit breakpoint reasoning, while the Syncfusion Builder inherits responsive behavior from Tailwind&rsquo;s defaults without any first-class responsive logic of its own.</p><h3 id="documentation">Documentation</h3><p><strong>Documentation</strong> plays a bigger role in output quality than it might seem, since it directly shapes how well the AI agent understands the components it&rsquo;s generating. The Kendo UI Generator injects relevant documentation chunks directly into every component tool call, including API references with full type signatures. The Syncfusion Builder treats documentation as a separate tool, triggered only by specific keywords. At the time of the evaluation, results from this tool were inconsistent and the service had been unavailable for over 24 hours for both Angular and React.</p><p>One other important observation from the Angular and React evaluation: the Kendo UI Generator customizes its workflow per prompt using confidence scores, including only the tools and instructions relevant to each request. The Syncfusion Builder runs the same fixed sequence for most prompts regardless of complexity, and its component tools return the full prop list and approximately 250 lines of governance rules on every call. The result is that <strong>the Kendo UI agent operates on targeted, preprocessed context while the Syncfusion agent carries a heavier payload for every request</strong>.</p><h2 id="wrap-up">Wrap-up</h2><p>The comparison across Blazor, Angular and React tells a consistent story with these agentic UI generators. The Progress Telerik Agentic UI Generator outperforms the Syncfusion Agentic UI Builder across output quality, reliability, performance, accessibility, theming, layout and documentation.</p><p>On the Blazor side, the Telerik Generator had zero full failures across 23 prompts while Syncfusion had five, along with a consistent speed advantage on complex prompts and more reliable first-pass output. On the Angular and React side, the advantages show up in the underlying architecture, where the Kendo Generator&rsquo;s tools consistently deliver cleaner, more relevant context to the AI agent.</p><hr /><blockquote><p>Get started with AI-empowered development. The <a target="_blank" href="https://www.telerik.com/mcp-servers">Kendo UI and Telerik AI tools</a> are ready. And they come as part of the free trial of the component libraries.</p><br /><p><a href="https://www.telerik.com/mcp-servers#how-to-try" class="Btn" target="_blank">Try Now</a></p></blockquote><hr /><p>For more information on the Progress Telerik Agentic UI Generator, check out the following resources:</p><ul><li><a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/ai/agentic-ui-generator/getting-started">Telerik Agentic UI Generator for Blazor</a></li><li><a target="_blank" href="https://www.telerik.com/kendo-angular-ui/components/ai-tools/agentic-ui-generator/getting-started">Kendo UI Generator for Angular</a></li><li><a target="_blank" href="https://www.telerik.com/kendo-react-ui/components/ai-tools/agentic-ui-generator/getting-started">Kendo UI Generator for React</a></li></ul><p>The full comparison data referenced in this article is available for download:</p><ul><li><a target="_blank" href="https://www.telerik.com/docs/default-source/blogs-docs//syncfusion-builder-vs-telerik-generator-comparison.xlsx">Telerik UI for Blazor Agentic UI Generator vs Syncfusion Agentic UI Builder Comparative Evaluation (XLSX)</a></li><li><a target="_blank" href="https://www.telerik.com/docs/default-source/blogs-docs//syncfusion-ui-builder-vs-kendo-ui-generator.xlsx">Kendo Agentic UI Generator vs Syncfusion Agentic UI Builder (XLSX)</a></li></ul><hr /><h2 id="summary-faqs">Summary FAQs</h2><h3 id="what-do-these-tools-do">What Do These Tools Do?</h3><h4 id="what-telerik-agentic-ui-generator-is">What Telerik Agentic UI Generator Is</h4><p>According to the <a href="https://www.telerik.com/mcp-servers" target="_blank">Progress Telerik website</a>, the Telerik Agentic UI Generator for Telerik and Kendo UI libraries is an intelligent development tool delivered through the Model Context Protocol (MCP) Server that enables UI generation from natural language prompts. Once configured and authenticated, you can use the Agentic UI Generator tool (#telerik_ui_generator) together with the available specialized MCP assistants.</p><h4 id="what-syncfusion-agentic-ui-builder-is">What Syncfusion Agentic UI Builder Is</h4><p>According to the <a target="_blank" href="https://www.syncfusion.com/explore/agentic-ui-builder/">Syncfusion site</a>, Syncfusion&rsquo;s Agentic UI Builder is designed to work inside an IDE to generate UIs, dashboards or pages with Syncfusion components with natural language commands. Syncfusion uses MCP integration to access component APIs, prebuilt UI blocks, styling configurations, icon libraries and code generation.</p><h3 id="why-does-mcp-matter-in-both-products">Why Does MCP Matter in Both Products?</h3><p>Both brands&rsquo; tools use Model Context Protocol (MCP) servers to connect AI applications directly to the software specs for the individual library. This means that the AI is informed on component documentation, best practices, workflows and tooling provided by the UI library, so the AI can create a user interface more in line with how the library was designed to work. It should result in better outputs than if an AI were cobbling together an interface without guidance.</p><p>Learn more about the individual MCP servers:</p><ul><li><a href="https://www.telerik.com/blazor-mcp-servers" target="_blank">Telerik UI for Blazor MCP Servers</a></li><li><a href="https://www.telerik.com/angular-mcp-servers" target="_blank">Kendo UI for Angular MCP Servers</a></li><li><a href="https://www.telerik.com/react-mcp-servers" target="_blank">KendoReact MCP Servers</a></li><li><a target="_blank" href="https://ej2.syncfusion.com/react/documentation/mcp-server/overview">Syncfusion EJ2 React MCP Server</a></li><li><a target="_blank" href="https://ej2.syncfusion.com/angular/documentation/mcp-server/overview">Syncfusion EJ2 Angular MCP Server</a></li><li><a target="_blank" href="https://blazor.syncfusion.com/documentation/mcp-server/overview">Syncfusion Blazor MCP Server</a></li></ul><h3 id="are-prompt-libraries-included">Are Prompt Libraries Included?</h3><h4 id="telerik-and-kendo-ui-generator-prompt-libraries">Telerik and Kendo UI Generator Prompt Libraries</h4><p>Yes! Prompt libraries are included for the Kendo UI and Telerik AI UI Generator tools:</p><ul><li>Blazor: <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/ai/agentic-ui-generator/prompt-library">https://www.telerik.com/blazor-ui/documentation/ai/agentic-ui-generator/prompt-library</a></li><li>React: <a target="_blank" href="https://www.telerik.com/kendo-react-ui/components/ai-tools/agentic-ui-generator/getting-started">https://www.telerik.com/kendo-react-ui/components/ai-tools/agentic-ui-generator/getting-started</a></li><li>Angular: <a target="_blank" href="https://www.telerik.com/kendo-angular-ui/components/ai-tools/agentic-ui-generator/prompt-library">https://www.telerik.com/kendo-angular-ui/components/ai-tools/agentic-ui-generator/prompt-library</a></li></ul><h4 id="syncfusion-agentic-ui-builder-prompt-libraries">Syncfusion Agentic UI Builder Prompt Libraries</h4><p>Yes! Prompt libraries are included for the Syncfusion Agentic UI Builder tools:</p><ul><li>Blazor: <a target="_blank" href="https://blazor.syncfusion.com/documentation/mcp-server/agentic-ui-builder/prompt-library">https://blazor.syncfusion.com/documentation/mcp-server/agentic-ui-builder/prompt-library</a></li><li>React: <a target="_blank" href="https://ej2.syncfusion.com/react/documentation/mcp-server/agentic-ui-builder/prompt-library">https://ej2.syncfusion.com/react/documentation/mcp-server/agentic-ui-builder/prompt-library</a></li><li>Angular: <a target="_blank" href="https://ej2.syncfusion.com/angular/documentation/mcp-server/agentic-ui-builder/prompt-library">https://ej2.syncfusion.com/angular/documentation/mcp-server/agentic-ui-builder/prompt-library</a></li></ul><img src="https://feeds.telerik.com/link/23050/17315934.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:d364128b-f493-4804-8555-fe37bca196fa</id>
    <title type="text">Blazor Basics: Building Responsive Blazor Apps with CSS Media Queries</title>
    <summary type="text">Responsive design is the reason applications feel polished and user-friendly. Learn how to build responsive Blazor web applications using CSS media queries.</summary>
    <published>2026-04-06T20:25:23Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Claudio Bernasconi </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17314707/blazor-basics-building-responsive-blazor-apps-css-media-queries"/>
    <content type="text"><![CDATA[<p><span class="featured">Responsive design is the reason applications feel polished and user-friendly. Learn how to build responsive Blazor web applications using CSS media queries.</span></p><p>Today, we will learn how to build responsive Blazor web applications. Responsive design is the reason applications feel polished and user-friendly.</p><p>We will first learn the basics of responsive design and how to use CSS media queries to implement responsive layouts. Next, we will learn about what we should and should not do in our Blazor logic (C# code).</p><p>You can <a target="_blank" href="https://github.com/claudiobernasconi/BlazorMediaQueries">access the code used in this example on GitHub</a>.</p><h2 id="what-is-responsive-design-for-blazor-apps">What Is Responsive Design for Blazor Apps?</h2><p>Blazor provides a user interface rendering engine (Razor components) that lets us implement behavior using C#. Blazor components consist of an HTML and CSS template combined with C# interaction logic.</p><p>In modern web development, we want to utilize <strong>CSS media queries</strong> to let our web applications adapt to different screen sizes:</p><ul><li>Small screens, such as mobile phones</li><li>Medium screens, such as tablets</li><li>Large screens, such as desktop computers</li><li>(optional) Ultra-wide monitors</li></ul><p>Best practices for general web development also apply to implementing Blazor web applications.</p><h2 id="css-media-queries-in-blazor-components">CSS Media Queries in Blazor Components</h2><p>Let&rsquo;s learn about <strong>CSS media queries</strong> using a practical example, a Blazor web application generated from the .NET 10 Blazor Web App project template.</p><p>The <code>NavMenu</code> component contains a menu toggler. How it appears on the screen differs completely between a larger and a smaller screen.</p><p><img title="Blazor Web App: No Nav Button" src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/nav-button-not-visible-on-desktop.png?sfvrsn=257d381_2" alt="A browser with a running Blazor web appliation on desktop. The nav button is not visible." /></p><p>For a larger screen, the menu is always visible on the left. For a smaller screen, the menu is collapsed, and the menu toggler is visible. The menu only appears if the user presses the hamburger menu button.</p><p>The HTML definition in the <code>NavMenu</code> component looks like this:</p><pre class=" language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>checkbox<span class="token punctuation">"</span></span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Navigation menu<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>navbar-toggler<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre><p>It&rsquo;s an input element with the <code>navbar-toggler</code> CSS class attached.</p><p>Let&rsquo;s look at the CSS code defining that behavior:</p><pre class=" language-css"><code class="prism  language-css"><span class="token selector"><span class="token class">.navbar-toggler</span> </span><span class="token punctuation">{</span>
    <span class="token property">appearance</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">3.5</span>rem<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">2.5</span>rem<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> white<span class="token punctuation">;</span>
    <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
    <span class="token property">top</span><span class="token punctuation">:</span> <span class="token number">0.5</span>rem<span class="token punctuation">;</span>
    <span class="token property">right</span><span class="token punctuation">:</span> <span class="token number">1</span>rem<span class="token punctuation">;</span>
    <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span>px solid <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">0.1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token url">url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")</span> no-repeat center/<span class="token number">1.75</span>rem <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">0.1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>This CSS class definition defines the visual appearance of the menu toggler. It includes an inline SVG to define the three horizontal lines and a few spacing definitions.</p><p>As shown in the image above, on larger screens, this nav menu button is not visible. Let&rsquo;s look at the CSS code that implements this behavior.</p><pre class=" language-css"><code class="prism  language-css"><span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">min-width</span><span class="token punctuation">:</span> 641px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
    <span class="token selector"><span class="token class">.navbar-toggler</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>The <code>@media</code> syntax introduces the <strong>CSS media query</strong> feature. In the parentheses, we can implement a filter. In this case, we want all CSS definitions placed inside the curly braces to apply in case the filter condition evaluates to true. In this case, the minimum width of the rendered web page is expected to be 641 pixels.</p><p>In other words: When the page is at least 641 pixels in width, we want the CSS definitions inside the curly braces to be applied. In this definition, we set the <code>display</code> property to <code>none</code> for the <code>navbar-toggler</code> CSS class.</p><p><strong>Learning:</strong> Using CSS media queries, we can implement conditional rules based on a filter criterion. For example, we can add additional CSS definitions for existing CSS classes.</p><p><strong>Hint:</strong> There are additional CSS definitions inside the <code>NavMenu.razor.css</code> file generated by the default .NET 10 Blazor Web App project template. For simplicity and illustration, I included only the relevant code.</p><h2 id="hiding-information-on-smaller-screens">Hiding Information on Smaller Screens</h2><p>A very useful technique is to show certain information only for larger screens.</p><p>As mentioned earlier, you want to carefully decide what information to show on the screen. Does it help the user with the current use case, or does it distract? Is it really necessary?</p><p>Consider the following screenshot of the Weather page for a desktop-sized screen.</p><p><img title="Blazor Web App: Weather Page with all columns" src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/weather-page-all-columns-visible.png?sfvrsn=eff050a4_2" alt="A browser with a running Blazor web appliation on desktop. The weather page contains the Date, Temp. (C), Temp. (F), and Summary columns." /></p><p>We have data in four columns: Date, Temperature in Celsius, Temperature in Fahrenheit and Summary.</p><p>The Summary column adds a textual explanation and gives slightly more detail than the numerical temperature. Let&rsquo;s say we don&rsquo;t want to show that Summary on mobile to help the user focus on the actual temperature numbers.</p><p>Let&rsquo;s add the following class definition to the <code>th</code> and <code>td</code> elements of the table in the <code>Weather</code> page component:</p><pre class=" language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>desktop-only<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Summary<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>desktop-only<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@forecast.Summary<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>We added the desktop-only CSS class to those HTML elements.</p><p>Now, we implement the CSS code inside the <code>Weather.razor.css</code> file:</p><pre class=" language-css"><code class="prism  language-css"><span class="token selector"><span class="token class">.desktop-only</span> </span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">min-width</span><span class="token punctuation">:</span> 768px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
    <span class="token selector"><span class="token class">.desktop-only</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>We set the <code>display</code> property to <code>none</code> and implement a media query to set it to block for screens larger than 768 pixels.</p><p><img title="Blazor Web App: Weather Page with limited data" src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/weather-page-summary-not-visible-on-mobile.png?sfvrsn=a130b019_2" alt="A browser with a running Blazor web appliation on mobile. The weather page contains the Date, Temp. (C), and Temp. (F) columns. The Summary column does not show up on mobile." /></p><p>As you can see in the image, the Summary column doesn&rsquo;t show up for mobile users.</p><p>This is a simple yet powerful technique for conditionally rendering information based on screen size without requiring imperative C# code, such as using the <code>@if</code> directive in the component&rsquo;s template.</p><h2 id="integrating-user-interface-control-libraries">Integrating User Interface Control Libraries</h2><p>You might think that using a professional user control library, such as Progress <a target="_blank" href="https://www.telerik.com/blazor-ui">Telerik UI for Blazor</a>, solves everything for you. They provide professional-looking, tested user interface controls with accessibility and usability in mind. They also provide theming support, making it easy to apply custom colors.</p><p>However, while those components are implemented with responsive design in mind internally, you still have to arrange the layout around them, show and hide panels, and adjust spacing or information density.</p><p>You need to understand the overall structure of your web application and know when to step in and adjust the page layout to accommodate the various aspect ratios and device sizes of the modern world&mdash;from a handheld smartphone to a large 34" desktop monitor.</p><p>A good example provides the implementation of the <code>MainLayout</code> page in the default .NET 10 Blazor Web App project template:</p><pre class=" language-css"><code class="prism  language-css"><span class="token selector"><span class="token class">.page</span> </span><span class="token punctuation">{</span>
    <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">min-width</span><span class="token punctuation">:</span> 641px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
    <span class="token selector"><span class="token class">.page</span> </span><span class="token punctuation">{</span>
        <span class="token property">flex-direction</span><span class="token punctuation">:</span> row<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>The <code>page</code> CSS class is applied to the most outer <code>div</code> of the <code>MainLayout</code> component. It defines a relative position and a flex layout with the flex direction <code>column</code>. It means that the items will be rendered vertically below each other.</p><p>The following media query, with a minimum width of 641 pixels, sets the flex direction to <code>row</code>. It means that for screens at least 641 pixels wide, the items will be placed horizontally beside each other.</p><p><strong>This is an excellent example of how to utilize CSS media queries to structure your pages for different screen sizes.</strong></p><p>Yes, utilizing one of the proven user interface libraries will take a lot of weight off your shoulders and provide you with ready-to-use building blocks.</p><p>It will save you a lot of time and let you focus on solving your business problems rather than reinventing the wheel by implementing foundational components.</p><p>However, a fully responsive web application integrates those components to form a truly responsive web application.</p><p><strong>In short:</strong> Responsive design touches all levels of web application development. You have to consider it when implementing reusable building blocks, and when orchestrating them to form a page or application part.</p><h2 id="best-practices-for-implementing-responsive-blazor-web-applications">Best Practices for Implementing Responsive Blazor Web Applications</h2><p>The following best practices will help you with implementing your responsive Blazor web applications:</p><ol><li><strong>Use a mobile-first approach:</strong> When implementing page layouts, always start with the layout for the smallest screens. It will force you to clearly structure the information and present it in a user-friendly way. Creating the layouts for bigger screens is much simpler than starting with a big screen and trying to size it down.</li><li><strong>Use CSS Grid &amp; CSS Flexbox:</strong> They adapt naturally to screen changes, reducing the need for complex breakpoints and other complex CSS magic. I personally prefer Flexbox for internal component structure and Grid for layout.</li><li><strong>Use CSS Isolation in Blazor:</strong> Component-specific styles written in [Component].razor.css files are scoped and easily maintainable. You&rsquo;re sure that changes made in that file do not propagate to other components or your entire application code.</li><li><strong>Avoid screen-size logic in C#:</strong> Do not try to detect screen width or similar information from C# interaction code. Let CSS do the layouting and focus on loading, storing, updating and organizing data in your C# Code.</li><li><strong>Use the browser&rsquo;s developer tools:</strong> Test your responsive web app by changing resolutions and aspect ratios to simulate different devices.</li><li><strong>Use prebuilt user interface libraries:</strong> Reinventing the wheel is time-consuming, and you risk repeating mistakes others have already made and fixed. However, you still need to take care to properly integrate and arrange those third-party components to keep your web application fully responsive.</li></ol><h2 id="conclusion">Conclusion</h2><p>Blazor provides a powerful, simple user interface rendering engine. However, true responsiveness comes from combining it with modern CSS techniques, such as media queries.</p><p>Utilizing CSS Isolation will allow you to separate the scope of your CSS for individual components.</p><p>Responsive design is important for implementing modern low-level components, but also for integrating them into a full webpage or web application.</p><p>While CSS media queries are powerful and let us implement conditional behavior, it&rsquo;s still a lot of code that needs to be maintained. Be careful to extract reused code into components to minimize the effect, and use third-party user interface libraries to avoid re-inventing the wheel.</p><p>If you want to learn more about Blazor development, watch my <a target="_blank" href="https://www.youtube.com/playlist?list=PLwISgxnkpZGL_LhTQCWwp-WCzupv7lcp0">free Blazor Crash Course</a> on YouTube. And stay tuned to the Telerik blog for more <a target="_blank" href="https://www.telerik.com/blogs/tag/blazor-basics">Blazor Basics</a>.</p><img src="https://feeds.telerik.com/link/23050/17314707.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:fda2f92a-0bba-4092-b4a7-71adac14edf1</id>
    <title type="text">Instantiating Objects and Accessing Properties in Blazor</title>
    <summary type="text">Learn how to use Blazor’s interop features with JavaScript to handle live C# objects for typeable code.</summary>
    <published>2026-03-30T19:06:20Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Héctor Pérez </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17309760/instantiating-objects-accessing-properties-blazor"/>
    <content type="text"><![CDATA[<p><span class="featured">Learn how to use Blazor&rsquo;s interop features with JavaScript to handle live C# objects for typeable code.</span></p><p>Blazor is Microsoft&rsquo;s framework ideal for creating single-page applications (SPAs), complementing the stack for developing applications entirely in .NET. This is why each year we see significant updates in the framework that allows developers to create secure and robust applications. These changes, along with <a target="_blank" href="https://www.telerik.com/blazor-ui">Blazor control suites</a>&nbsp;like the one from Progress Telerik, undoubtedly accelerate the development of complete apps.</p><p>In this article, I will tell you about the new interop features with JavaScript, which certainly marks a significant improvement in handling objects from the C# language. Let&rsquo;s get started!</p><h2 id="understanding-the-problem-to-solve">Understanding the Problem to Solve</h2><p>Until .NET 10, interoperability with JS was mainly done by invoking JS functions, without being able to directly handle live objects from C# code, which involved creating wrappers and code that could often lead to failures and runtime errors due to syntax errors.</p><p>We can get an idea of the above through a practical case. Suppose that in our application, we have a <a target="_blank" href="https://www.telerik.com/blazor-ui/gridhttps://demos.telerik.com/blazor-ui/grid/overview">Blazor Data Grid</a> control that allows displaying products from an online store. Each row has a column with a button to show a lightbox popup, where images are displayed. The demonstration code, for you to gain a complete idea, looks as follows.</p><p>First, I created a JavaScript file with the necessary functionality to display the lightbox image gallery:</p><p><strong>lightboxGallery.js</strong></p><pre class=" language-javascript"><code class="prism  language-javascript">window<span class="token punctuation">.</span>lightboxGallery <span class="token operator">=</span> <span class="token punctuation">{</span>
    LightboxGallery<span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token class-name">LightboxGallery</span> <span class="token punctuation">{</span>
        <span class="token function">constructor</span><span class="token punctuation">(</span>imageUrls<span class="token punctuation">,</span> startIndex <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>images <span class="token operator">=</span> imageUrls<span class="token punctuation">;</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>currentIndex <span class="token operator">=</span> startIndex<span class="token punctuation">;</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>keyHandler <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token function">show</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">createOverlay</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">displayImage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token function">createOverlay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>

            <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">.</span>className <span class="token operator">=</span> <span class="token string">'lightbox-overlay'</span><span class="token punctuation">;</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token template-string"><span class="token string">`
            &lt;div class="lightbox-container"&gt;
                &lt;button class="lightbox-close"&gt;&amp;times;&lt;/button&gt;
                &lt;button class="lightbox-prev"&gt;&amp;lsaquo;&lt;/button&gt;
                &lt;div class="lightbox-content"&gt;
                    &lt;img class="lightbox-image" src="https://www.telerik.com" alt="Gallery Image"&gt;
                    &lt;div class="lightbox-counter"&gt;&lt;/div&gt;
                &lt;/div&gt;
                &lt;button class="lightbox-next"&gt;&amp;rsaquo;&lt;/button&gt;
            &lt;/div&gt;
        `</span></span><span class="token punctuation">;</span>

            document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">)</span><span class="token punctuation">;</span>
            
            <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'.lightbox-close'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'.lightbox-prev'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">prev</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'.lightbox-next'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>target <span class="token operator">===</span> <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">keyHandler</span> <span class="token operator">=</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>key <span class="token operator">===</span> <span class="token string">'Escape'</span><span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>key <span class="token operator">===</span> <span class="token string">'ArrowLeft'</span><span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">prev</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>key <span class="token operator">===</span> <span class="token string">'ArrowRight'</span><span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token punctuation">;</span>
            document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'keydown'</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>keyHandler<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token function">displayImage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span>

            <span class="token keyword">const</span> img <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'.lightbox-image'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">const</span> counter <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'.lightbox-counter'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            img<span class="token punctuation">.</span>src <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>images<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>currentIndex<span class="token punctuation">]</span><span class="token punctuation">;</span>
            counter<span class="token punctuation">.</span>textContent <span class="token operator">=</span> <span class="token template-string"><span class="token string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>currentIndex <span class="token operator">+</span> <span class="token number">1</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> / </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>images<span class="token punctuation">.</span>length<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>currentIndex <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>currentIndex <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token keyword">this</span><span class="token punctuation">.</span>images<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">displayImage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token function">prev</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>currentIndex <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>currentIndex <span class="token operator">-</span> <span class="token number">1</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>images<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token keyword">this</span><span class="token punctuation">.</span>images<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">displayImage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">this</span><span class="token punctuation">.</span>overlayElement <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>keyHandler<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                document<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">'keydown'</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>keyHandler<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">this</span><span class="token punctuation">.</span>keyHandler <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
        
        <span class="token function">getCurrentIndex</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>currentIndex<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        
        <span class="token function">getImagesLength</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>images<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre><p>The above code shows the definition of a JS class <code>LightboxGallery</code> with some properties to control the gallery. In addition, methods are also defined to enable interaction with it, such as <code>next</code>, <code>prev</code>, <code>show</code>, etc.</p><p>This file needs to be registered in <code>App.razor</code> to be able to use it from the application, as I show you below:</p><pre class=" language-html"><code class="prism  language-html">....
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">&gt;</span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Routes</span> <span class="token attr-name">@rendermode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>InteractiveServer<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ReconnectModal</span> <span class="token punctuation">/&gt;</span></span>
    &lt;script src="https://www.telerik.com@Assets["_content/Telerik.UI.for.Blazor/js/telerik-blazor.js"]"&gt;<span class="token script language-javascript"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
    &lt;script src="https://www.telerik.com@Assets["js/lightboxGallery.js"]"&gt;<span class="token script language-javascript"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
    &lt;script src="https://www.telerik.com@Assets["_framework/blazor.web.js"]"&gt;<span class="token script language-javascript"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Finally, I created a Razor page where I use the Blazor Data Grid and <a target="_blank" href="https://www.telerik.com/blazor-ui/buttons">Blazor Button</a> components to create a quick and functional graphic interface.</p><pre class=" language-xml"><code class="prism  language-xml">@page "/products-traditional"
@inject IJSRuntime JSRuntime

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>PageTitle</span><span class="token punctuation">&gt;</span></span>Products - Traditional JS Interop<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>PageTitle</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>container-fluid mt-4<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>row mb-4<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>col-12<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>display-6<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Product Gallery<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span>          
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>row<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>col-12<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikGrid</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@Products<span class="token punctuation">"</span></span>
                         <span class="token attr-name">Pageable</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span>
                         <span class="token attr-name">PageSize</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>10<span class="token punctuation">"</span></span>
                         <span class="token attr-name">Sortable</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span>
                         <span class="token attr-name">FilterMode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@GridFilterMode.FilterRow<span class="token punctuation">"</span></span>
                         <span class="token attr-name">Resizable</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span>
                         <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>600px<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>GridColumns</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>GridColumn</span> <span class="token attr-name">Field</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@nameof(Product.Id)<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Title</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>ID<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>80px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>GridColumn</span> <span class="token attr-name">Field</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@nameof(Product.Name)<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Title</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Product Name<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>200px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>GridColumn</span> <span class="token attr-name">Field</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@nameof(Product.Category)<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Title</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Category<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>150px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>GridColumn</span> <span class="token attr-name">Field</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@nameof(Product.Price)<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Title</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Price<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>120px<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Template</span><span class="token punctuation">&gt;</span></span>
                            @{
                                var product = context as Product;
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>$@product?.Price.ToString("N2")<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                            }
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Template</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>GridColumn</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>GridColumn</span> <span class="token attr-name">Field</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@nameof(Product.Stock)<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Title</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Stock<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>GridColumn</span> <span class="token attr-name">Title</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Actions<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>150px<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Filterable</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span> 
                                <span class="token attr-name">Sortable</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Template</span><span class="token punctuation">&gt;</span></span>
                            @{
                                var product = context as Product;
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikButton</span> <span class="token attr-name">OnClick</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@(async () =&gt; await ShowImagesTraditional(product))<span class="token punctuation">"</span></span>
                                               <span class="token attr-name">ThemeColor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Button.ThemeColor.Primary<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                    Show Images
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikButton</span><span class="token punctuation">&gt;</span></span>
                            }
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Template</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>GridColumn</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>GridColumns</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikGrid</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>If we want to invoke the methods from the JS code, there are various ways, although in the following example I show you one of the easiest. To display the gallery, we would use the following code:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">private</span> <span class="token keyword">async</span> Task <span class="token function">ShowImagesTraditional</span><span class="token punctuation">(</span>Product<span class="token operator">?</span> product<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>product <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">||</span> product<span class="token punctuation">.</span>ImageUrls<span class="token punctuation">.</span>Count <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span>
        <span class="token keyword">return</span><span class="token punctuation">;</span>
        
    <span class="token keyword">var</span> imageUrlsJson <span class="token operator">=</span> System<span class="token punctuation">.</span>Text<span class="token punctuation">.</span>Json<span class="token punctuation">.</span>JsonSerializer<span class="token punctuation">.</span><span class="token function">Serialize</span><span class="token punctuation">(</span>product<span class="token punctuation">.</span>ImageUrls<span class="token punctuation">)</span><span class="token punctuation">;</span>
    
    <span class="token comment">// Step 1</span>
    <span class="token keyword">await</span> JSRuntime<span class="token punctuation">.</span><span class="token function">InvokeVoidAsync</span><span class="token punctuation">(</span><span class="token string">"eval"</span><span class="token punctuation">,</span> 
        $<span class="token string">"window.__tempGallery = new lightboxGallery.LightboxGallery({imageUrlsJson}, 0)"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    
    <span class="token comment">// Step 2</span>
    <span class="token keyword">await</span> JSRuntime<span class="token punctuation">.</span><span class="token function">InvokeVoidAsync</span><span class="token punctuation">(</span><span class="token string">"eval"</span><span class="token punctuation">,</span> <span class="token string">"window.__tempGallery.show()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    
    <span class="token comment">// Step 3</span>
    <span class="token keyword">var</span> currentIndex <span class="token operator">=</span> <span class="token keyword">await</span> JSRuntime<span class="token punctuation">.</span><span class="token generic-method function">InvokeAsync<span class="token punctuation">&lt;</span><span class="token keyword">int</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token string">"eval"</span><span class="token punctuation">,</span> <span class="token string">"window.__tempGallery.currentIndex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    
    <span class="token comment">// Step 4</span>
    <span class="token keyword">var</span> imagesCount <span class="token operator">=</span> <span class="token keyword">await</span> JSRuntime<span class="token punctuation">.</span><span class="token generic-method function">InvokeAsync<span class="token punctuation">&lt;</span><span class="token keyword">int</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token string">"eval"</span><span class="token punctuation">,</span> <span class="token string">"window.__tempGallery.images.length"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    
    <span class="token comment">// Step 5</span>
    Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>$<span class="token string">"Traditional: Showing {imagesCount} images, starting at index {currentIndex}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    
    isGalleryOpen <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">;</span>
    <span class="token function">StateHasChanged</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    
<span class="token punctuation">}</span>
</code></pre><p>Here&rsquo;s what we do in the above code:</p><ul><li><strong>Step 1</strong>: We use eval and global variables in <code>window</code> to maintain the reference to the gallery.</li><li><strong>Step 2</strong>: The method show defined in the class <code>LightboxGallery</code> is called.</li><li><strong>Step 3</strong>: We obtain the <code>index</code> of the image from the gallery.</li><li><strong>Step 4</strong>: The number of images is obtained using <code>lenght</code>.</li><li><strong>Step 5</strong>: The results are displayed based on the information obtained.</li></ul><p>The same applies to perform operations like navigating forward or backward:</p><p><strong>Navigating Forward</strong></p><pre class=" language-javascript"><code class="prism  language-javascript"><span class="token keyword">await</span> JSRuntime<span class="token punctuation">.</span><span class="token function">InvokeVoidAsync</span><span class="token punctuation">(</span><span class="token string">"eval"</span><span class="token punctuation">,</span> <span class="token string">"window.__tempGallery.next()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p><strong>Navigating Backward</strong></p><pre class=" language-javascript"><code class="prism  language-javascript"><span class="token keyword">await</span> JSRuntime<span class="token punctuation">.</span><span class="token function">InvokeVoidAsync</span><span class="token punctuation">(</span><span class="token string">"eval"</span><span class="token punctuation">,</span> <span class="token string">"window.__tempGallery.prev()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>Or even to close the gallery:</p><pre class=" language-javascript"><code class="prism  language-javascript"><span class="token keyword">await</span> JSRuntime<span class="token punctuation">.</span><span class="token function">InvokeVoidAsync</span><span class="token punctuation">(</span><span class="token string">"eval"</span><span class="token punctuation">,</span> <span class="token string">"window.__tempGallery.close()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">await</span> JSRuntime<span class="token punctuation">.</span><span class="token function">InvokeVoidAsync</span><span class="token punctuation">(</span><span class="token string">"eval"</span><span class="token punctuation">,</span> <span class="token string">"delete window.__tempGallery"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>The example being executed looks as follows:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/demo-app-js-gallery.gif?sfvrsn=466ae63b_2" alt="The demo application displaying a gallery rendered with JavaScript" /></p><p>In the previous example, you can notice several problems, starting with the use of <code>eval</code>, which allows executing text as JavaScript code. Although it is an easy way to run code, it poses a danger as it opens the door to code injection. Moreover, it is slow as it cannot be optimized, is difficult to debug and is generally considered a bad practice.</p><p>Another problem is the direct use of global variables in <code>window</code>, as there is a risk of collisions with other libraries in the project; there is no management of galleries or lifecycle, plus there is no control over when to destroy it.</p><p>A third serious problem is that there can be a memory leak if the object in memory isn&rsquo;t destroyed since the browser&rsquo;s garbage collection (GC) cannot collect the reference, leaving listeners and live DOM references.</p><h2 id="new-javascript-interop-features-in-blazor-10">New JavaScript Interop Features in Blazor 10</h2><p>We could continue discussing the multiple issues in the example from the previous section, but let&rsquo;s focus on the new features of Blazor in .NET 10 to address this.</p><h2 id="the-invokeconstructorasync-method">The InvokeConstructorAsync Method</h2><p>In .NET 10, it is possible to use the method <code>InvokeConstructorAsync</code>, which allows you to invoke a JS constructor asynchronously. This method will execute the <code>new</code> operator and return a type <code>IJSObjectReference</code>. For example, to display a gallery, it would be done as follows:</p><pre class=" language-csharp"><code class="prism  language-csharp">@code <span class="token punctuation">{</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    <span class="token keyword">private</span> IJSObjectReference<span class="token operator">?</span> galleryInstance<span class="token punctuation">;</span>
    <span class="token keyword">private</span> GalleryInfo<span class="token operator">?</span> currentGalleryInfo<span class="token punctuation">;</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    <span class="token keyword">private</span> <span class="token keyword">async</span> Task <span class="token function">ShowImagesModern</span><span class="token punctuation">(</span>Product<span class="token operator">?</span> product<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>product <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">||</span> product<span class="token punctuation">.</span>ImageUrls<span class="token punctuation">.</span>Count <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span>
            <span class="token keyword">return</span><span class="token punctuation">;</span>

        <span class="token keyword">try</span>
        <span class="token punctuation">{</span>            
            <span class="token keyword">if</span> <span class="token punctuation">(</span>galleryInstance <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                <span class="token keyword">await</span> galleryInstance<span class="token punctuation">.</span><span class="token function">DisposeAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            
            <span class="token keyword">var</span> imageUrls <span class="token operator">=</span> product<span class="token punctuation">.</span>ImageUrls<span class="token punctuation">.</span><span class="token function">ToArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            
            <span class="token comment">// Step 1</span>
            galleryInstance <span class="token operator">=</span> <span class="token keyword">await</span> JSRuntime<span class="token punctuation">.</span><span class="token function">InvokeConstructorAsync</span><span class="token punctuation">(</span>
                <span class="token string">"lightboxGallery.LightboxGallery"</span><span class="token punctuation">,</span> 
                imageUrls<span class="token punctuation">,</span> 
                <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">// Step 2</span>
            <span class="token keyword">await</span> galleryInstance<span class="token punctuation">.</span><span class="token function">InvokeVoidAsync</span><span class="token punctuation">(</span><span class="token string">"show"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">// Step 3</span>
            <span class="token keyword">var</span> currentIndex <span class="token operator">=</span> <span class="token keyword">await</span> galleryInstance<span class="token punctuation">.</span><span class="token generic-method function">GetValueAsync<span class="token punctuation">&lt;</span><span class="token keyword">int</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token string">"currentIndex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            
            <span class="token comment">// Step 4</span>
            <span class="token keyword">var</span> imagesLength <span class="token operator">=</span> <span class="token keyword">await</span> galleryInstance<span class="token punctuation">.</span><span class="token generic-method function">GetValueAsync<span class="token punctuation">&lt;</span><span class="token keyword">int</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token string">"images.length"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            
            <span class="token comment">//Step 5</span>
            currentGalleryInfo <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">GalleryInfo</span>
            <span class="token punctuation">{</span>
                CurrentIndex <span class="token operator">=</span> currentIndex<span class="token punctuation">,</span>
                TotalImages <span class="token operator">=</span> imagesLength
            <span class="token punctuation">}</span><span class="token punctuation">;</span>

            <span class="token function">StateHasChanged</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            
            Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>$<span class="token string">"Modern: Showing {imagesLength} images, starting at index {currentIndex}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            
        <span class="token punctuation">}</span>
        <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> ex<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>$<span class="token string">"Error showing images: {ex.Message}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>In the above code, the exact same steps are followed to display the gallery, but with cleaner code. <code>InvokeConstructorAsync</code> is used to create the object and maintain its reference, which can in turn be used to invoke other methods using the traditional method <code>InvokeVoidAsync</code>. In our example, we invoke the method <code>show</code> defined in the JavaScript class.</p><p>To perform other actions, a similar approach is followed:</p><p>To advance:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">await</span> galleryInstance<span class="token punctuation">.</span><span class="token function">InvokeVoidAsync</span><span class="token punctuation">(</span><span class="token string">"next"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>To go back:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">await</span> galleryInstance<span class="token punctuation">.</span><span class="token function">InvokeVoidAsync</span><span class="token punctuation">(</span><span class="token string">"prev"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>To close the gallery:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">await</span> galleryInstance<span class="token punctuation">.</span><span class="token function">InvokeVoidAsync</span><span class="token punctuation">(</span><span class="token string">"close"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
currentGalleryInfo <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token function">StateHasChanged</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>With this new approach, we have a drastic change not only aesthetically but also internally. For example, each component has its own instance, which prevents collisions between them. Additionally, there is a controlled lifecycle with no memory leaks. You may also notice that parameter passing is much simpler and safer.</p><h2 id="the-getvalueasync-and-setvalueasync-methods">The GetValueAsync and SetValueAsync Methods</h2><p>In addition to the method for invoking a JS function constructor, we can also access the values of the instance obtained through the methods <code>GetValueAsync&lt;TValue&gt;(string identifier)</code> and <code>SetValueAsync&lt;TValue&gt;(string identifier, TValue value)</code>. A clear example of this can be seen when we obtain the value of the current image and the length for debugging purposes:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token comment">// Step 3</span>
<span class="token keyword">var</span> currentIndex <span class="token operator">=</span> <span class="token keyword">await</span> galleryInstance<span class="token punctuation">.</span><span class="token generic-method function">GetValueAsync<span class="token punctuation">&lt;</span><span class="token keyword">int</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token string">"currentIndex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// Step 4</span>
<span class="token keyword">var</span> imagesLength <span class="token operator">=</span> <span class="token keyword">await</span> galleryInstance<span class="token punctuation">.</span><span class="token generic-method function">GetValueAsync<span class="token punctuation">&lt;</span><span class="token keyword">int</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token string">"images.length"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//Step 5</span>
currentGalleryInfo <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">GalleryInfo</span>
<span class="token punctuation">{</span>
    CurrentIndex <span class="token operator">=</span> currentIndex<span class="token punctuation">,</span>
    TotalImages <span class="token operator">=</span> imagesLength
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token function">StateHasChanged</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>$<span class="token string">"Modern: Showing {imagesLength} images, starting at index {currentIndex}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>In the above code, these values are displayed through an <code>Console.WriteLine</code>, but you could perfectly use them to modify other UI elements or to perform operations.</p><h2 id="conclusion">Conclusion</h2><p>Throughout this article, you have been introduced to the new JavaScript interop features available in .NET 10, which undoubtedly marks an evolution in the way interaction with JS occurs when necessary. It is time to create safer and typeable code in web apps based on Blazor.</p><hr /><p>Remember, you can try Telerik UI for Blazor free for 30 days:</p><p><a href="https://www.telerik.com/try/ui-for-blazor" target="_blank" class="Btn">Try Now</a></p><img src="https://feeds.telerik.com/link/23050/17309760.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:d682b921-294a-4401-b442-3aed57b43aa9</id>
    <title type="text">What’s New for Blazor in .NET 11 Preview Releases 1 and 2</title>
    <summary type="text">Tour the notable Blazor changes and new features in .NET 11 Previews 1 and 2 for an early glimpse into what’s coming for Blazor in .NET 11.</summary>
    <published>2026-03-25T16:13:51Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Jon Hilton </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17305972/whats-new-blazor-net-11-preview-releases-1-2"/>
    <content type="text"><![CDATA[<p><span class="featured">Tour the notable Blazor changes and new features in .NET 11 Previews 1 and 2 for an early glimpse into what&rsquo;s coming for Blazor in .NET 11.</span></p><p>Ever since the significant changes that landed with .NET 8, we&rsquo;ve seen incremental updates to Blazor over several releases.</p><p>This year seems set to continue that trend, with some key gaps being filled and refinements to key features. So no structural shifts, new hosting models or render modes, but we do finally get a <code>Label</code> component for forms!</p><p>Here are some notable Blazor changes and new features that landed in .NET 11 Previews 1 and 2.</p><h2 id="tempdata-for-static-ssr">TempData for Static SSR</h2><p>Ever since .NET 8, we&rsquo;ve had SSR mode for Blazor. It&rsquo;s a way of building applications using Blazor&rsquo;s Razor components, but without resorting to Blazor Server or Blazor WASM to run those components.</p><p>With SSR, when a user requests your page, Blazor runs on the server, locates the relevant page component, renders it and returns the generated HTML which is then displayed in the browser.</p><p>In this mode you can also use forms to capture user input.</p><p>But sometimes you want to take information and persist it between page navigations. For example, maybe a user enters their name in a form, and you want to show them a personalized message on the subsequent confirmation screen, &ldquo;Thanks, Jon, for your order.&rdquo;</p><p>Prior to .NET 11, this required you to pass the value along somehow, with common solutions involving query string, session state or custom cookies.</p><p>But MVC and Razor Pages developers have long been able to use something called Temp Data to store that information between screens. Temp Data is specifically for capturing short-lived messages or data that only need to survive one redirect, then disappear.</p><p>In .NET 11, Temp Data is coming to Blazor and will be available as a cascading parameter in static SSR components, with no extra registration needed beyond the usual <code>AddRazorComponents()</code>:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token punctuation">[</span>CascadingParameter<span class="token punctuation">]</span>
<span class="token keyword">public</span> ITempData<span class="token operator">?</span> TempData <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
</code></pre><p>Let&rsquo;s say you&rsquo;re about to redirect your user to a different page. You can write a value to <code>TempData</code>:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">HandleSubmit</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    TempData<span class="token punctuation">[</span><span class="token string">"SuccessMessage"</span><span class="token punctuation">]</span> <span class="token operator">=</span> $<span class="token string">"Thanks {Input.Name}, your message has been sent!"</span><span class="token punctuation">;</span>
    Navigation<span class="token punctuation">.</span><span class="token function">NavigateTo</span><span class="token punctuation">(</span><span class="token string">"/contact/confirmation"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>Then pick that up on the page they&rsquo;re redirected to:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">protected</span> <span class="token keyword">override</span> <span class="token keyword">void</span> <span class="token function">OnInitialized</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">// Get() reads and marks for deletion - one-shot read</span>
    confirmationMessage <span class="token operator">=</span> TempData<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"SuccessMessage"</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token keyword">string</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>Under the hood, these values are stored in a cookie in the user&rsquo;s browser.</p><p>Once you&rsquo;ve retrieved a value via <code>Get</code>, it&rsquo;s marked for deletion. So if you want to check the value without it being deleted, you can use <code>Peek</code> instead. If you want to keep something that has been marked for deletion you can call <code>Keep</code> to cancel the deletion.</p><h2 id="ihostedservice-in-blazor-webassembly">IHostedService in Blazor WebAssembly</h2><p>If you&rsquo;re using Blazor WebAssembly, you may well have realized there&rsquo;s one thing you can&rsquo;t easily do with Blazor running in the browser: schedule jobs to run in the background.</p><p>This is a challenge because sometimes you want to separate background work from your component lifecycles. For example, you might want to poll an API (maybe a pricing or notifications endpoint).</p><p>In WASM apps, prior to .NET 11, this has been tricky to achieve, often requiring the use of timers within specific components (tied to component lifecycles and only running when the component is rendered), or singleton services with a manual timer.</p><p>.NET 11 simplifies this with <code>IHostedService</code>.</p><p>You can add a hosted service to your Blazor WASM app and it will start with the app (not a specific component), and run independently of navigation.</p><p><code>AddHostedService&lt;T&gt;()</code> now works with <code>WebAssemblyHostBuilder</code>:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">var</span> builder <span class="token operator">=</span> WebAssemblyHostBuilder<span class="token punctuation">.</span><span class="token function">CreateDefault</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
builder<span class="token punctuation">.</span>Services<span class="token punctuation">.</span><span class="token generic-method function">AddHostedService<span class="token punctuation">&lt;</span>PricePollingService<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">await</span> builder<span class="token punctuation">.</span><span class="token function">Build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">RunAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>The service itself is standard <code>BackgroundService</code>, identical to its server-side equivalent:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">PricePollingService</span><span class="token punctuation">(</span>PriceState state<span class="token punctuation">)</span> <span class="token punctuation">:</span> BackgroundService
<span class="token punctuation">{</span>
    <span class="token keyword">protected</span> <span class="token keyword">override</span> <span class="token keyword">async</span> Task <span class="token function">ExecuteAsync</span><span class="token punctuation">(</span>CancellationToken stoppingToken<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span>stoppingToken<span class="token punctuation">.</span>IsCancellationRequested<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token keyword">await</span> <span class="token function">FetchPricesAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            state<span class="token punctuation">.</span><span class="token function">NotifyUpdate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">await</span> Task<span class="token punctuation">.</span><span class="token function">Delay</span><span class="token punctuation">(</span>TimeSpan<span class="token punctuation">.</span><span class="token function">FromSeconds</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> stoppingToken<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>This example uses a <code>Singleton</code> <code>PriceState</code> service and a component which listens for updates to that state.</p><p>The <code>PriceState</code> service acts as a shared state container which the background service writes to:</p><p><strong>Program.cs</strong></p><pre class=" language-csharp"><code class="prism  language-csharp">builder<span class="token punctuation">.</span>Services<span class="token punctuation">.</span><span class="token generic-method function">AddSingleton<span class="token punctuation">&lt;</span>PriceState<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p><strong>PriceState.cs</strong></p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">PriceState</span>
<span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">event</span> Action<span class="token operator">?</span> OnChange<span class="token punctuation">;</span>

    <span class="token keyword">public</span> List<span class="token operator">&lt;</span>PriceQuote<span class="token operator">&gt;</span> Quotes <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token keyword">public</span> DateTimeOffset LastUpdated <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">UpdateQuotes</span><span class="token punctuation">(</span>List<span class="token operator">&lt;</span>PriceQuote<span class="token operator">&gt;</span> quotes<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        Quotes <span class="token operator">=</span> quotes<span class="token punctuation">;</span>
        LastUpdated <span class="token operator">=</span> DateTimeOffset<span class="token punctuation">.</span>UtcNow<span class="token punctuation">;</span>
        OnChange<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">Invoke</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>And then you can subscribe to the <code>OnChange</code> event when that data changes:</p><p><strong>PriceWatcher.razor</strong></p><pre class=" language-html"><code class="prism  language-html">@implements IDisposable
@inject PriceState State

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>Last updated: @State.LastUpdated<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>

<span class="token comment">&lt;!-- render price data here --&gt;</span>
</code></pre><pre class=" language-csharp"><code class="prism  language-csharp">@code <span class="token punctuation">{</span>
    <span class="token keyword">protected</span> <span class="token keyword">override</span> <span class="token keyword">void</span> <span class="token function">OnInitialized</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        State<span class="token punctuation">.</span>OnChange <span class="token operator">+</span><span class="token operator">=</span> HandleStateChanged<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">HandleStateChanged</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token function">InvokeAsync</span><span class="token punctuation">(</span>StateHasChanged<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        State<span class="token punctuation">.</span>OnChange <span class="token operator">-</span><span class="token operator">=</span> HandleStateChanged<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>Important note: WASM is single-threaded. BackgroundService gives you a convenient way to abstract background tasks, but not true parallelism.</p><p>I/O-bound work (polling, fetching) is typically fine because it&rsquo;s mostly waiting (<code>await</code>), which frees the thread up in the meantime. But CPU-heavy work would block the UI.</p><p>But fear not, there&rsquo;s a solution for that too!</p><h2 id="web-worker-template">Web Worker Template</h2><p>For anything CPU-heavy, you want to keep the main thread (which also handles the UI) free.</p><p>.NET 11 introduces <code>dotnet new webworker</code>, which scaffolds a Razor class library with the JS plumbing needed to run .NET code in a browser web worker. Modern web browsers support web workers as a convenient way to run tasks completely separately from your main application&rsquo;s thread.</p><p>The template will create a <code>WebWorkerClient</code> class which uses a factory pattern to create worker instances. Then you can define your worker methods using <code>[JSExport]</code>.</p><p>Here&rsquo;s an example, which computes primes (a CPU-heavy task).</p><p><strong>PrimesWorker.cs</strong></p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token punctuation">[</span><span class="token function">SupportedOSPlatform</span><span class="token punctuation">(</span><span class="token string">"browser"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">partial</span> <span class="token keyword">class</span> <span class="token class-name">PrimesWorker</span>
<span class="token punctuation">{</span>
    <span class="token punctuation">[</span>JSExport<span class="token punctuation">]</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">string</span> <span class="token function">ComputePrimes</span><span class="token punctuation">(</span><span class="token keyword">int</span> limit<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token comment">// CPU-intensive work runs on the worker thread</span>
        <span class="token comment">// UI stays responsive</span>
        <span class="token keyword">var</span> result <span class="token operator">=</span> <span class="token function">SieveOfEratosthenes</span><span class="token punctuation">(</span>limit<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> JsonSerializer<span class="token punctuation">.</span><span class="token function">Serialize</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">PrimeResult</span><span class="token punctuation">(</span>primes<span class="token punctuation">.</span>Count<span class="token punctuation">,</span> primes<span class="token punctuation">.</span><span class="token function">TakeLast</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ToArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> sw<span class="token punctuation">.</span>ElapsedMilliseconds<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">public</span> record <span class="token function">PrimeResult</span><span class="token punctuation">(</span><span class="token keyword">int</span> Count<span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span> LastFive<span class="token punctuation">,</span> <span class="token keyword">long</span> ElapsedMs<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>You can invoke this method from a component (via a web worker).</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">private</span> <span class="token keyword">const</span> <span class="token keyword">int</span> limit <span class="token operator">=</span> 50_000_000<span class="token punctuation">;</span>

<span class="token keyword">var</span> worker <span class="token operator">=</span> <span class="token keyword">await</span> WebWorkerClient<span class="token punctuation">.</span><span class="token function">CreateAsync</span><span class="token punctuation">(</span>JSRuntime<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> result <span class="token operator">=</span> <span class="token keyword">await</span> worker<span class="token punctuation">.</span><span class="token generic-method function">InvokeAsync<span class="token punctuation">&lt;</span>PrimeResult<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span>
    <span class="token string">"WebWorkerAppDemo.PrimesWorker.ComputePrimes"</span><span class="token punctuation">,</span>
    args<span class="token punctuation">:</span> <span class="token punctuation">[</span>limit<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>If you were to run that same prime number code directly in a component, it would lock UI updates for as long as it&rsquo;s running. Try it with the above approach (using web workers), and the UI will stay entirely responsive throughout.</p><p>Some important notes about web workers:</p><ul><li>Class must be static partial with <code>[SupportedOSPlatform("browser")]</code>.</li><li>Return types: primitives or strings only (complex types must be serialized to JSON).</li><li>Your project needs <code>&lt;AllowUnsafeBlocks&gt;true&lt;/AllowUnsafeBlocks&gt;</code> set in its <code>csproj</code>.</li><li>The worker loads a second .NET runtime, so startup is slow but compute is genuinely parallel.</li><li>Template produces a class library, which you can then reference from your main project.</li></ul><h2 id="relative-navigation">Relative Navigation</h2><p>This is one of those &ldquo;if you know, you know&rdquo; challenges.</p><p>In previous versions of .NET, when you want to render a relative link, things got tricky. Say you wanted a link to an FAQ page at <code>/faq</code>. .NET would assume you wanted to navigate to <code>/faq</code> at the app root. But if you were already on <code>/docs/</code>, you might well have wanted that link to go to <code>/docs/faq</code>.</p><p>The workaround up to now has been to use hardcoded full paths everywhere, which is asking for trouble when you start moving things around.</p><p><code>NavigationManager.NavigateTo()</code> and <code>NavLink</code> now accept <code>RelativeToCurrentUri</code>, which, when set to <code>true</code>, means relative paths will resolve against the current page path instead of the app root:</p><pre class=" language-html"><code class="prism  language-html">@page "/docs/getting-started"

@* .NET 11 - resolves to /docs/getting-started/overview *@
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NavLink</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>overview<span class="token punctuation">"</span></span> <span class="token attr-name">RelativeToCurrentUri</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Overview<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>NavLink</span><span class="token punctuation">&gt;</span></span>

@* Before - had to hardcode the full path *@
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NavLink</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>/docs/getting-started/overview<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Overview<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>NavLink</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Programmatic navigation:</p><pre class=" language-csharp"><code class="prism  language-csharp">Navigation<span class="token punctuation">.</span><span class="token function">NavigateTo</span><span class="token punctuation">(</span><span class="token string">"faq"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">NavigationOptions</span>
<span class="token punctuation">{</span>
    RelativeToCurrentUri <span class="token operator">=</span> <span class="token keyword">true</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>Note: Path must not have a leading slash for relative resolution (&ldquo;overview&rdquo; not &ldquo;/overview&rdquo;).</p><h2 id="displayname-and-label-components">DisplayName and Label Components</h2><p>This may well be one of those features that leaves you wondering how it took so long to appear, but Blazor now has a <code>Label</code> component (and a handy <code>DisplayName</code> one too).</p><p>Both components read display names from model attributes:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ProductModel</span>
<span class="token punctuation">{</span>
    <span class="token punctuation">[</span><span class="token function">Display</span><span class="token punctuation">(</span>Name <span class="token operator">=</span> <span class="token string">"Production Date"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>  <span class="token comment">// DisplayName and Label read this</span>
    <span class="token keyword">public</span> DateOnly<span class="token operator">?</span> ProductionDate <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>

    <span class="token punctuation">[</span><span class="token function">DisplayName</span><span class="token punctuation">(</span><span class="token string">"Unit Price (&pound;)"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>     <span class="token comment">// Also supported, but [Display] takes precedence</span>
    <span class="token keyword">public</span> <span class="token keyword">decimal</span> Price <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">int</span> StockCount <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>  <span class="token comment">// Falls back to raw property name</span>
<span class="token punctuation">}</span>
</code></pre><p>Here&rsquo;s how you can use them in a form:</p><pre class=" language-html"><code class="prism  language-html">@* Label wraps the input - accessible by default *@
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Label</span> <span class="token attr-name">For</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@(() =&gt; Model.ProductionDate)<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-label<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>InputDate</span> <span class="token attr-name">@bind-Value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Model.ProductionDate<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-control<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Label</span><span class="token punctuation">&gt;</span></span>

@* DisplayName standalone *@
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DisplayName</span> <span class="token attr-name">For</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@(() =&gt; Model.Price)<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Previously you had to write your own <code>&lt;label&gt;</code> components, so this is a welcome addition.</p><h2 id="environmentboundary-component">EnvironmentBoundary Component</h2><p>Ever felt the need to show different information on the screen depending on which environment your app&rsquo;s running in? (Think UI that only shows up when you&rsquo;re running locally, or on staging.)</p><p>Now you can conditionally render content based on the hosting environment:</p><pre class=" language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>EnvironmentBoundary</span> <span class="token attr-name">Include</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Development<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>Debug tools enabled<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>EnvironmentBoundary</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>EnvironmentBoundary</span> <span class="token attr-name">Exclude</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Production<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>Test banner<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>EnvironmentBoundary</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>EnvironmentBoundary</span> <span class="token attr-name">Include</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Staging,Production<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>Analytics script<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>EnvironmentBoundary</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Previously, you had to inject <code>IWebHostEnvironment</code> and write manual conditional statements. This declarative approach is cleaner (note the matching of environment is case-insensitive).</p><h2 id="basepath-component">BasePath Component</h2><p>Another small but handy change.</p><p><code>&lt;BasePath /&gt;</code> in <code>App.razor</code> replaces the hardcoded <code>&lt;base href="https://www.telerik.com/"&gt;</code>:</p><pre class=" language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">&gt;</span></span>   
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>BasePath</span> <span class="token punctuation">/&gt;</span></span>   
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>This will take the value from <code>NavigationManager.BaseUri</code> and essentially returns whatever <code>UsePathBase</code> sets (which you can configure in <strong>Program.cs</strong>).</p><p>This is handy if you&rsquo;re running your app on a subpath, as the base href will be automatically set to the correct value.</p><h2 id="signalr-configureconnection">SignalR ConfigureConnection</h2><p>If you need to configure your <code>SignalR</code> connection for Blazor Server, you now have easier config available via <code>AddInteractiveServerRenderMode</code>.</p><p>In .NET 11, it accepts a <code>ConfigureConnection</code> callback for the underlying SignalR connection:</p><pre class=" language-csharp"><code class="prism  language-csharp">app<span class="token punctuation">.</span><span class="token generic-method function">MapRazorComponents<span class="token punctuation">&lt;</span>App<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">.</span><span class="token function">AddInteractiveServerRenderMode</span><span class="token punctuation">(</span>options <span class="token operator">=</span><span class="token operator">&gt;</span>
    <span class="token punctuation">{</span>
        options<span class="token punctuation">.</span>ConfigureConnection <span class="token operator">=</span> connectionOptions <span class="token operator">=</span><span class="token operator">&gt;</span>
        <span class="token punctuation">{</span>
            connectionOptions<span class="token punctuation">.</span>ApplicationMaxBufferSize <span class="token operator">=</span> <span class="token number">512</span> <span class="token operator">*</span> <span class="token number">1024</span><span class="token punctuation">;</span>
            connectionOptions<span class="token punctuation">.</span>TransportMaxBufferSize <span class="token operator">=</span> <span class="token number">512</span> <span class="token operator">*</span> <span class="token number">1024</span><span class="token punctuation">;</span>
            connectionOptions<span class="token punctuation">.</span>Transports <span class="token operator">=</span> HttpTransportType<span class="token punctuation">.</span>WebSockets<span class="token punctuation">;</span>
          connectionOptions<span class="token punctuation">.</span>AllowStatefulReconnects <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">;</span>
            connectionOptions<span class="token punctuation">.</span>CloseOnAuthenticationExpiration <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>Previously, you had to resort to global SignalR hub config. Now you can target Blazor&rsquo;s hub specifically.</p><p>You&rsquo;ll probably find yourself spending time here if you run into errors because your components hold too much state, you want to tweak stateful reconnection logic or have other reasons to tweak how the SignalR part of Blazor Server works.</p><h2 id="what-to-watch">What to Watch</h2><p>That wraps up a quick tour of some of the highlights of .NET 11 Previews 1 and 2 for Blazor.</p><p>Here are a few things that look set to land in future previews:</p><ul><li><strong>SessionData for static SSR</strong> &ndash; The session-scoped counterpart to TempData</li><li><strong>Cache component</strong> &ndash; Component-level output caching</li><li><strong>Client-side validation without a circuit</strong> &ndash; No need to resort to Blazor Server for your statically rendered forms</li><li><strong>Aspire integration improvements</strong></li><li><strong>Virtualize with variable-height items</strong></li><li><strong><code>[SupplyParameterFromTempData]</code> attribute</strong></li></ul><p>.NET 11 will be released in November, with preview releases dropping every month until then.</p><aside><hr data-sf-ec-immutable="" /><div class="row"><div class="col-4 u-normal-full u-small-mb0"><h4 class="u-fs20 u-fw5 u-lh125 u-mb0">Build Your Own AI Application Using Prebuilt Blazor Components</h4></div><div class="col-8"><p class="u-fs16 u-mb0">With <a target="_blank" href="https://www.telerik.com/blogs/build-your-own-ai-application-using-prebuilt-blazor-components">prebuilt components, you can easily build a Blazor application</a> that connects to AI model services for chat conversations. Check it out.</p></div></div></aside><img src="https://feeds.telerik.com/link/23050/17305972.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:64742007-b953-46a8-8374-913881b24dee</id>
    <title type="text">Blazor Basics: Implementing a Theme Switch in Blazor (Dark Mode)</title>
    <summary type="text">Learn how to implement dark mode and a theme switch for Blazor web applications using standardized CSS features and no JavaScript code.</summary>
    <published>2026-03-17T20:08:55Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Claudio Bernasconi </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17301106/blazor-basics-implementing-theme-switch-blazor-dark-mode"/>
    <content type="text"><![CDATA[<p><span class="featured">Learn how to implement dark mode and a theme switch for Blazor web applications using standardized CSS features and no JavaScript code.</span></p><p>In this article, we&rsquo;ll learn how to properly implement dark mode and a theme switch for Blazor web applications.</p><h2 id="introduction">Introduction</h2><p>We want to implement a minimal yet complete example of dark mode and a theme switch for Blazor web applications.</p><p>We will keep it simple and use pure CSS to style the application and Blazor to manage the state. We do not use any JavaScript code for this solution.</p><p><strong>Hint:</strong> Although the code used in the example project is based on the .NET 10 Blazor Web Application project template, which uses Bootstrap for its sample pages, we do not use Bootstrap or any other CSS library to implement the dark mode or the theme switch.</p><p>You can <a target="_blank" href="https://github.com/claudiobernasconi/BlazorDarkMode">access the code used in this example on GitHub</a>.</p><h2 id="the-concept">The Concept</h2><p>There are three core principles we want to follow:</p><ol><li>We define all colors as CSS variables.</li><li>We use a <code>.dark-theme</code> CSS class to override/replace those base colors.</li><li>We implement a Blazor component that toggles this CSS class at runtime.</li></ol><p>This solution works for <strong>Blazor Server</strong> and <strong>Blazor WebAssembly</strong>.</p><h2 id="defining-the-css-color-variables">Defining the CSS Color Variables</h2><p>In the <code>app.css</code> file or any other CSS file referenced in the <code>index.html</code> or <code>App.razor</code> file of your Blazor web application, we add the following CSS variable definitions:</p><pre class=" language-css"><code class="prism  language-css"><span class="token selector"><span class="token pseudo-class">:root</span> </span><span class="token punctuation">{</span>
    <span class="token property">--background-color</span><span class="token punctuation">:</span> <span class="token hexcode">#FFFFFF</span><span class="token punctuation">;</span>
    <span class="token property">--text-color</span><span class="token punctuation">:</span> <span class="token hexcode">#1F1F39</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token class">.dark-theme</span> </span><span class="token punctuation">{</span>
    <span class="token property">--background-color</span><span class="token punctuation">:</span> <span class="token hexcode">#1F1F39</span><span class="token punctuation">;</span>
    <span class="token property">--text-color</span><span class="token punctuation">:</span> <span class="token hexcode">#FAFAFB</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p><strong>Hint:</strong> We keep it simple in this example and use only CSS variables for the background color and text color. In a real-world implementation, you might also want to define CSS variables for border colors, primary and secondary colors, etc.</p><h2 id="applying-the-color-variables">Applying the Color Variables</h2><p>Now that we defined the CSS variables for our desired colors, we need to apply those variables in CSS definitions. Remember that the variable definition above only defines the variables, but does not apply them.</p><pre class=" language-css"><code class="prism  language-css"><span class="token selector"><span class="token class">.theme</span> </span><span class="token punctuation">{</span>
    <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--background-color<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--text-color<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>Again, we keep it simple and apply the background color and the text color to the theme CSS class. We could go on and define colors for buttons, headings and other parts of the web application.</p><h2 id="adding-the-theme-state-to-the-layout-component">Adding the Theme State to the Layout Component</h2><p>Now that we have the basic building block for styling the component in place, we want to keep track of whether dark mode is in use.</p><p>A simple implementation alters the <code>MainLayout</code> component like this:</p><pre class=" language-html"><code class="prism  language-html">&lt;div class=@($"page theme {ThemeCSSClass}")&gt;
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sidebar<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NavMenu</span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>main</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>top-row px-4<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>btn btn-primary<span class="token punctuation">"</span></span> <span class="token attr-name">@onclick</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>ToggleTheme<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                Toggle Theme
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>https://learn.microsoft.com/aspnet/core/<span class="token punctuation">"</span></span> <span class="token attr-name">target</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>_blank<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>About<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>article</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>content px-4<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            @Body
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>article</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>main</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>We add two CSS classes to the class list of the outer <code>div</code> element. In addition to the page CSS class used in the default project template, we also want to add the previously defined <code>theme</code> class, followed by a class name managed by the component.</p><p>We also add a <code>button</code> to toggle the theme.</p><p>We add the following behavior to the code section of the component:</p><pre class=" language-csharp"><code class="prism  language-csharp">@code <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token keyword">bool</span> _darkModeEnabled <span class="token operator">=</span> <span class="token keyword">false</span><span class="token punctuation">;</span>

    <span class="token keyword">private</span> <span class="token keyword">string</span> ThemeCSSClass <span class="token operator">=</span><span class="token operator">&gt;</span> _darkModeEnabled <span class="token operator">?</span> <span class="token string">"dark-theme"</span> <span class="token punctuation">:</span> <span class="token string">""</span><span class="token punctuation">;</span>

    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">ToggleTheme</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        _darkModeEnabled <span class="token operator">=</span> <span class="token operator">!</span>_darkModeEnabled<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>The code defines a <code>_darkModeEnabled</code> variable that tracks the user&rsquo;s theme choice. We conditionally return <code>dark-theme</code> or an empty string for the <code>ThemeCSSClass</code> property, which is then rendered as part of the CSS class name list for the Layout component&rsquo;s outer <code>div</code>.</p><p>The <code>ToggleTheme</code> method is triggered when the user presses the <code>button</code> and wants to switch the theme. It flips the value of the <code>_darkModeEnabled</code> boolean variable.</p><h2 id="theming-in-action">Theming in Action</h2><p>The user can now toggle the light and dark themes using the button in the page header.</p><p><img title="Blazor web Application using light mode" src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/blazor-light-mode.png?sfvrsn=d20bcc54_2" alt="A browser with a Blazor web application using a light mode theme with a dark text color and a white background." /></p><p><img title="Blazor web Application using light mode" src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/blazor-dark-mode.png?sfvrsn=9b1faed_2" alt="A browser with a Blazor web application using a dark mode theme with a light text color and a dark background." /></p><h2 id="why-this-solution-works-well-in-blazor">Why This Solution Works Well in Blazor</h2><p>This solution leverages how Razor component rendering works. Whenever the state of a component changes, the component is re-rendered.</p><p>For the layout component, this means that whenever the user presses the button, the component&rsquo;s state changes, so it will be re-rendered. As part of the rendering process, the correct CSS classes will be applied.</p><p>A declarative user interface definition combined with state-driven component rendering is the strength of Blazor, and our solution therefore fits it perfectly.</p><h2 id="improving-the-user-experience">Improving the User Experience</h2><p>There are two main areas that could be improved to take our simple solution to the next level:</p><ul><li>The theme state is currently attached to the <code>MainLayout</code> component. It means that if the user closes the browser tab or refreshes the page, the state is lost. Persisting the theme choice using local storage is a great idea to keep the user experience consistent. Learn more about <a target="_blank" href="https://www.telerik.com/blogs/blazor-basics-accessing-browser-storage-blazor-web-applications">accessing the local storage for Blazor Server web applications</a> or how to use <a target="_blank" href="https://www.telerik.com/blogs/blazor-basics-webassembly-using-local-storage-offline-scenarios">local Storage in Blazor WebAssembly applications</a>.</li><li>You could respect the system preferences and apply them when a particular user starts the web application for the first time. CSS provides the <code>preferes-color-scheme</code> media feature. The code would look like this:</li></ul><pre class=" language-css"><code class="prism  language-css"><span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-color-scheme</span><span class="token punctuation">:</span> dark<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
    <span class="token selector"><span class="token pseudo-class">:root</span> </span><span class="token punctuation">{</span>
        <span class="token comment">/* variable definitions */</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-color-scheme</span><span class="token punctuation">:</span> light<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
    <span class="token selector"><span class="token pseudo-class">:root</span> </span><span class="token punctuation">{</span>
        <span class="token comment">/* variable definitions */</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><h2 id="the-limitations-of-this-approach">The Limitations of This Approach</h2><p>As shown in the previous chapter on improving the user experience of our simple solutions, our approach is basic and doesn&rsquo;t scale well. The following imminent limitations come to mind:</p><ul><li>Handling <strong>system preferences</strong> already adds complexity to our solution and requires more code to cleanly implement the expected behavior.</li><li>CSS variables and definitions only <strong>cascade down the DOM tree</strong>. In our example, we add the themed CSS classes to the MainLayout component. Components rendered outside the <code>MainLayout</code> component element tree are out of scope for theming and must be treated the same way (by adding the <code>theme</code> and <code>dark-mode</code> CSS classes).</li><li>Changing colors and adjusting the theme requires altering <strong>global CSS definitions</strong>, which is hard to test and can potentially have unexpected side effects. Also, making sure to apply the CSS variables in the correct applicable CSS classes doesn&rsquo;t scale.</li><li><strong>Third-party components</strong> will not automatically apply the custom CSS classes defined in the application. Meaning that if you integrate third-party components, you will need to implement additional code to integrate them with your custom theming implementation.</li><li>Implementing <strong>multiple themes</strong> becomes even harder to maintain. Working with light and dark mode should not add too much complexity, but maintaining three or four, or even 10 different themes becomes much harder.</li><li>You have to verify the selected colors work together and <strong>meet accessibility requirements</strong> (e.g., color contrast). And let&rsquo;s be honest&mdash;not all developers are good designers.</li></ul><p>For a small website, the approach shown in this article will probably work well. For larger web applications consisting of hundreds of pages and components, it can become a maintenance nightmare if the implementation is not carefully architected to properly handle state changes and apply the correct CSS classes for each component during rendering.</p><h2 id="how-telerik-ui-for-blazor-solves-theming-at-scale">How Telerik UI for Blazor Solves Theming at Scale</h2><p>In modern large-scale web applications, theming is important and helps meet accessibility requirements and expected user experience standards.</p><p>The Progress Telerik UI for <a target="_blank" href="https://www.telerik.com/blazor-ui">Blazor component library</a> provides a <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/styling-and-themes/themebuilder">Blazor ThemeBuilder</a> tool that allows visual customization (color previews), SCSS-based design tokens and built-in dark and light themes.</p><p>And most importantly, the themes are applied consistently across all components.</p><p>It is still important to understand how theming works under the hood, but for a professional web application, using a professionally implemented theming system can prevent headaches and reduce the amount of custom code required. Plus, accessibility features are baked in.</p><p>Learn more about theming from <a target="_blank" href="https://www.telerik.com/blogs/author/peter-vogel">Peter Vogel</a> in the <a target="_blank" href="https://www.telerik.com/blogs/themes-magic-telerik-ui-blazor">Themes Magic in Telerik UI for Blazor</a> article.</p><h2 id="conclusion">Conclusion</h2><p>We learned how to implement a simple solution for a theme switch and light and dark mode in a Blazor web application. This basic solution works for Blazor Server and Blazor WebAssembly because it uses standardized CSS features and no JavaScript.</p><p>We learned how to further improve the solution and what limitations it will face for a large-scale web application.</p><p>Professionally implemented user interface component libraries, such as <a target="_blank" href="https://www.telerik.com/blazor-ui">Telerik UI for Blazor</a>, implement complex theming systems that we can leverage to get around those limitations.</p><hr /><p>If you want to learn more about Blazor development, watch my <a target="_blank" href="https://www.youtube.com/playlist?list=PLwISgxnkpZGL_LhTQCWwp-WCzupv7lcp0">free Blazor Crash Course</a> on YouTube. And stay tuned to the Telerik blog for more <a target="_blank" href="https://www.telerik.com/blogs/tag/blazor-basics">Blazor Basics</a>.</p><img src="https://feeds.telerik.com/link/23050/17301106.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:9ed4819f-b7ee-4208-b031-ba0e298fab0b</id>
    <title type="text">Customizing the New ReconnectModal Component in Blazor 10</title>
    <summary type="text">Learn how to customize the reconnection modal dialog for users of your Blazor app with the ReconnectionModal component, introduced in .NET 10.</summary>
    <published>2026-03-03T16:17:41Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Héctor Pérez </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17288838/customizing-new-reconnectmodal-component-blazor-10"/>
    <content type="text"><![CDATA[<p><span class="featured">Learn how to customize the reconnection modal dialog for users of your Blazor app with the ReconnectionModal component, introduced in .NET 10.</span></p><p>.NET 10 has arrived with a lot of new features for its main development technologies. Blazor is no exception, and several features have been added that make the platform increasingly robust and customizable year after year for creating web applications.</p><p>One of these features is the addition of a customizable reconnection modal dialog, which we will discuss in depth in this article.</p><h2 id="understanding-the-new-reconnectionmodal-component-of-blazor">Understanding the New ReconnectionModal Component of Blazor</h2><p>Before .NET 10, when there were disconnection events in a Blazor application, a modal was displayed with information to the user about the reconnection status. However, the modal was not very easy to customize and caused <strong>Content Security Policy</strong> issues and injected styles.</p><p>This completely changes in .NET 10, with the incorporation of a component called <strong>ReconnectModal</strong>, consisting of a Razor file for layout, a styles file to define the design and a JS code file to utilize the logic. Among these three files, you can customize the reconnection component as much as you want, as we will see next.</p><p>A new event <code>components-reconnect-state-changed</code> has also been added to detect reconnection status changes, as well as a new reconnection status called <code>retrying</code>, which you can use to show a different design after a first reconnection attempt.</p><h2 id="general-structure-of-the-reconnectionmodal-component">General Structure of the ReconnectionModal Component</h2><p>The file <code>ReconnectModal.razor</code> contains the layout for the reconnection dialog component. The first line with a tag <code>script</code> loads the file <code>ReconnectModal.razor.js</code> that enables interactivity in the component. This file <code>js</code> can be left as is, as the logic in the file covers everything necessary for managing the reconnection dialog, including interaction buttons:</p><pre class=" language-javascript"><code class="prism  language-javascript"><span class="token operator">&lt;</span>script type<span class="token operator">=</span><span class="token string">"module"</span> src<span class="token operator">=</span><span class="token string">"@Assets["</span>Components<span class="token operator">/</span>Layout<span class="token operator">/</span>ReconnectModal<span class="token punctuation">.</span>razor<span class="token punctuation">.</span>js<span class="token string">"]"</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
</code></pre><p>In the previous tag, the expression <code>@Assets</code> allows resolving the path of a static resource that will be used in the component, commonly with the same name as the component.</p><p>Next, we find an element <code>dialog</code> that is used to show reconnection information to the user. In this element, we must leave the <code>id</code> <code>components-reconnect-modal</code>, as it will be used internally by the framework to display the reconnection message to the user.</p><pre class=" language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dialog</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>components-reconnect-modal<span class="token punctuation">"</span></span> <span class="token attr-name">data-nosnippet</span><span class="token punctuation">&gt;</span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dialog</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Within the dialog tag, we define the layout that we can modify as much as we want, as long as we limit ourselves to using code <code>HTML</code> + <code>CSS</code> + <code>JS</code>, due to the fact that this dialog must be displayed when the circuit is down.</p><p>Additionally, you should take care to reuse the <a target="_blank" href="https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/signalr?view=aspnetcore-10.0#reflect-the-server-side-connection-state-in-the-ui">classes and ids used in Blazor reconnection tracking</a>, which are defined in the <code>css</code> file:</p><ul><li><code>components-reconnect-show</code></li><li><code>components-reconnect-hide</code></li><li><code>components-reconnect-retrying</code></li><li><code>components-reconnect-failed</code></li><li><code>components-reconnect-rejected</code></li></ul><p>The previous classes are set or unset directly by Blazor when different connection status changes occur. Furthermore, in the <code>ReconnectModal.razor.js</code> file, the event <code>components-reconnect-state-changed</code> is used, which indicates when there is a change in reconnection status, carrying out the display, hiding, reloading or necessary processing according to that status:</p><pre class=" language-javascript"><code class="prism  language-javascript"><span class="token comment">// Set up event handlers</span>
<span class="token keyword">const</span> reconnectModal <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"components-reconnect-modal"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
reconnectModal<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"components-reconnect-state-changed"</span><span class="token punctuation">,</span> handleReconnectStateChanged<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">...</span>

<span class="token keyword">function</span> <span class="token function">handleReconnectStateChanged</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>detail<span class="token punctuation">.</span>state <span class="token operator">===</span> <span class="token string">"show"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        reconnectModal<span class="token punctuation">.</span><span class="token function">showModal</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>detail<span class="token punctuation">.</span>state <span class="token operator">===</span> <span class="token string">"hide"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        reconnectModal<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>detail<span class="token punctuation">.</span>state <span class="token operator">===</span> <span class="token string">"failed"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"visibilitychange"</span><span class="token punctuation">,</span> retryWhenDocumentBecomesVisible<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>detail<span class="token punctuation">.</span>state <span class="token operator">===</span> <span class="token string">"rejected"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        location<span class="token punctuation">.</span><span class="token function">reload</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token operator">...</span>
</code></pre><p>Returning to <code>ReconnectModal.razor</code>, the <code>div</code> with the class <code>components-reconnect-container</code> serves to define the graphical appearance of the container, and you can modify it or even remove it if you do not need it.</p><p>The same can be done with the classes defined in <code>ReconnectModal.razor.css</code>, such as <code>components-reconnect-first-attempt-visible</code>, <code>components-reconnect-repeated-attempt-visible</code>, etc., although to make the most of the code you can reuse them if you wish.</p><h2 id="modifying-the-loader-of-the-reconnectmodal-component">Modifying the Loader of the ReconnectModal Component</h2><p>In the file <code>ReconnectModal.razor</code>, we can see an <code>div</code> with the class <code>components-rejoining-animation</code>, which allows showing an animation to the user. If you want to modify it, you can use some premade animation from websites like <a target="_blank" href="https://loading.io/css/">Pure CSS Loaders</a>, or you can write your own CSS animations as we will do next.</p><p>For my example, in <code>ReconnectModal.razor</code>, I will change the tag with the class <code>components-rejoining-animation</code> along with its content to this:</p><pre class=" language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-progress components-reconnect-first-attempt-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>progress-bar<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-progress components-reconnect-repeated-attempt-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>progress-bar<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Next, in <code>ReconnectModal.razor.css</code>, I replace the selector <code>.components-rejoining-animation</code> along with its descendant and structural selectors with this:</p><pre class=" language-css"><code class="prism  language-css"><span class="token selector"><span class="token class">.reconnect-progress</span> </span><span class="token punctuation">{</span>
    <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
    <span class="token property">bottom</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token property">left</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">100%</span><span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">4</span>px<span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token hexcode">#e2e8f0</span><span class="token punctuation">;</span>
    <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token class">.progress-bar</span> </span><span class="token punctuation">{</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">100%</span><span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">30%</span><span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span><span class="token number">90</span>deg, <span class="token hexcode">#3b82f6</span> <span class="token number">0%</span>, <span class="token hexcode">#8b5cf6</span> <span class="token number">50%</span>, <span class="token hexcode">#3b82f6</span> <span class="token number">100%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">background-size</span><span class="token punctuation">:</span> <span class="token number">200%</span> <span class="token number">100%</span><span class="token punctuation">;</span>
    <span class="token property">animation</span><span class="token punctuation">:</span> progressMove <span class="token number">1.5</span>s ease-in-out infinite<span class="token punctuation">;</span>
    <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">2</span>px<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token atrule"><span class="token rule">@keyframes</span> progressMove</span> <span class="token punctuation">{</span>
    <span class="token selector">0% </span><span class="token punctuation">{</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateX</span><span class="token punctuation">(</span>-<span class="token number">100%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">background-position</span><span class="token punctuation">:</span> <span class="token number">0%</span> <span class="token number">50%</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector">50% </span><span class="token punctuation">{</span>
        <span class="token property">background-position</span><span class="token punctuation">:</span> <span class="token number">100%</span> <span class="token number">50%</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector">100% </span><span class="token punctuation">{</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateX</span><span class="token punctuation">(</span><span class="token number">400%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">background-position</span><span class="token punctuation">:</span> <span class="token number">0%</span> <span class="token number">50%</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>These few lines of code completely change the appearance of the loader to a more modern and professional style:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/enhancing-the-loading-animation-of-the-reconnectmodal-razor-component.gif?sfvrsn=a6c98305_2" alt="Enhancing the loading animation of the ReconnectModal.razor component" /></p><p>Now, let&rsquo;s see how to change the modal container.</p><h2 id="modifying-the-modal-container">Modifying the Modal Container</h2><p>In the previous section, you saw that the modal&rsquo;s previous size has become smaller because we removed space from the animation. To solve this, we can modify the modal properties through the class <code>components-reconnect-container</code>. To achieve this, we will go to the CSS file and modify the selector&rsquo;s content as follows:</p><pre class=" language-css"><code class="prism  language-css"><span class="token selector"><span class="token class">.components-reconnect-container</span> </span><span class="token punctuation">{</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">2.5</span>rem <span class="token number">2</span>rem <span class="token number">2</span>rem<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span>
    <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">1.5</span>rem<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>This way, when viewing the dialog, we will see more space. You can modify the class as much as you want to meet your needs:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/expanding-the-dialog-space-for-better-visibility.png?sfvrsn=9820ee59_2" alt="Expanding the dialog space for better visibility" /></p><p>Let&rsquo;s continue improving the dialog by styling more visual elements.</p><h2 id="adding-a-pulse-element">Adding a Pulse Element</h2><p>To make the dialog take better shape, we can add a set of <code>div</code> and <code>svg</code> tags to show different content according to the reconnection status. We can do this within the <code>div</code> with the class <code>components-reconnect-container</code>:</p><pre class=" language-html"><code class="prism  language-html">...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>components-reconnect-container<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-icon-container<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-pulse-ring<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-pulse-ring delay-1<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-pulse-ring delay-2<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-icon<span class="token punctuation">"</span></span> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0 0 24 24<span class="token punctuation">"</span></span> <span class="token attr-name">fill</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>none<span class="token punctuation">"</span></span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://www.w3.org/2000/svg<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>path</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>icon-path<span class="token punctuation">"</span></span> <span class="token attr-name">d</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z<span class="token punctuation">"</span></span> <span class="token attr-name">fill</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>currentColor<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-icon-error<span class="token punctuation">"</span></span> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0 0 24 24<span class="token punctuation">"</span></span> <span class="token attr-name">fill</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>none<span class="token punctuation">"</span></span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://www.w3.org/2000/svg<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>path</span> <span class="token attr-name">d</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z<span class="token punctuation">"</span></span> <span class="token attr-name">fill</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>currentColor<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-icon-pause<span class="token punctuation">"</span></span> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0 0 24 24<span class="token punctuation">"</span></span> <span class="token attr-name">fill</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>none<span class="token punctuation">"</span></span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://www.w3.org/2000/svg<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>path</span> <span class="token attr-name">d</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 14H9V8h2v8zm4 0h-2V8h2v8z<span class="token punctuation">"</span></span> <span class="token attr-name">fill</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>currentColor<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
...
</code></pre><p>In the <code>css</code> file, we must control when each element will appear by reusing the selectors for the connection states, as shown below:</p><pre class=" language-css"><code class="prism  language-css"><span class="token comment">/* Icon container */</span>
<span class="token selector"><span class="token class">.reconnect-icon-container</span> </span><span class="token punctuation">{</span>
    <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">100</span>px<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">100</span>px<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token class">.reconnect-icon</span>,
<span class="token class">.reconnect-icon-error</span>,
<span class="token class">.reconnect-icon-pause</span> </span><span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">48</span>px<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">48</span>px<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#3b82f6</span><span class="token punctuation">;</span>
    <span class="token property">z-index</span><span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">;</span>
    <span class="token property">animation</span><span class="token punctuation">:</span> iconPulse <span class="token number">2</span>s ease-in-out infinite<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token class">.reconnect-icon-error</span>,
<span class="token class">.reconnect-icon-pause</span> </span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token id">#components-reconnect-modal</span><span class="token class">.components-reconnect-failed</span> <span class="token class">.reconnect-icon</span>,
<span class="token id">#components-reconnect-modal</span><span class="token class">.components-reconnect-resume-failed</span> <span class="token class">.reconnect-icon</span> </span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token id">#components-reconnect-modal</span><span class="token class">.components-reconnect-failed</span> <span class="token class">.reconnect-icon-error</span>,
<span class="token id">#components-reconnect-modal</span><span class="token class">.components-reconnect-resume-failed</span> <span class="token class">.reconnect-icon-error</span> </span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#ef4444</span><span class="token punctuation">;</span>
    <span class="token property">animation</span><span class="token punctuation">:</span> iconShake <span class="token number">0.5</span>s ease-in-out<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token id">#components-reconnect-modal</span><span class="token class">.components-reconnect-paused</span> <span class="token class">.reconnect-icon</span> </span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token id">#components-reconnect-modal</span><span class="token class">.components-reconnect-paused</span> <span class="token class">.reconnect-icon-pause</span> </span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#f59e0b</span><span class="token punctuation">;</span>
    <span class="token property">animation</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token atrule"><span class="token rule">@keyframes</span> iconPulse</span> <span class="token punctuation">{</span>
    <span class="token selector">0%, 100% </span><span class="token punctuation">{</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector">50% </span><span class="token punctuation">{</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1.1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token atrule"><span class="token rule">@keyframes</span> iconShake</span> <span class="token punctuation">{</span>
    <span class="token selector">0%, 100% </span><span class="token punctuation">{</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateX</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector">20% </span><span class="token punctuation">{</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateX</span><span class="token punctuation">(</span>-<span class="token number">8</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector">40% </span><span class="token punctuation">{</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateX</span><span class="token punctuation">(</span><span class="token number">8</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector">60% </span><span class="token punctuation">{</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateX</span><span class="token punctuation">(</span>-<span class="token number">4</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector">80% </span><span class="token punctuation">{</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateX</span><span class="token punctuation">(</span><span class="token number">4</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">/* Pulse rings */</span>
<span class="token selector"><span class="token class">.reconnect-pulse-ring</span> </span><span class="token punctuation">{</span>
    <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">100%</span><span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">100%</span><span class="token punctuation">;</span>
    <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">50%</span><span class="token punctuation">;</span>
    <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">3</span>px solid <span class="token hexcode">#3b82f6</span><span class="token punctuation">;</span>
    <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token property">animation</span><span class="token punctuation">:</span> pulseRing <span class="token number">2</span>s <span class="token function">cubic-bezier</span><span class="token punctuation">(</span><span class="token number">0</span>, <span class="token number">0.5</span>, <span class="token number">0.5</span>, <span class="token number">1</span><span class="token punctuation">)</span> infinite<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.reconnect-pulse-ring.delay-1</span> </span><span class="token punctuation">{</span>
        <span class="token property">animation-delay</span><span class="token punctuation">:</span> <span class="token number">0.4</span>s<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.reconnect-pulse-ring.delay-2</span> </span><span class="token punctuation">{</span>
        <span class="token property">animation-delay</span><span class="token punctuation">:</span> <span class="token number">0.8</span>s<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token selector"><span class="token id">#components-reconnect-modal</span><span class="token class">.components-reconnect-failed</span> <span class="token class">.reconnect-pulse-ring</span>,
<span class="token id">#components-reconnect-modal</span><span class="token class">.components-reconnect-resume-failed</span> <span class="token class">.reconnect-pulse-ring</span>,
<span class="token id">#components-reconnect-modal</span><span class="token class">.components-reconnect-paused</span> <span class="token class">.reconnect-pulse-ring</span> </span><span class="token punctuation">{</span>
    <span class="token property">animation</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token atrule"><span class="token rule">@keyframes</span> pulseRing</span> <span class="token punctuation">{</span>
    <span class="token selector">0% </span><span class="token punctuation">{</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">0.5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector">20% </span><span class="token punctuation">{</span>
        <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">0.8</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector">100% </span><span class="token punctuation">{</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1.2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>The above code allows for a pulse effect that, along with the changes we will make later, will look phenomenal:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/adding-a-visual-pulse-effect-to-the-dialog.gif?sfvrsn=3a31b899_2" alt="Adding a visual pulse effect to the dialog" /></p><p>Now, let&rsquo;s see how to modify the content of the reconnection modal.</p><h2 id="modifying-the-reconnection-modal-content">Modifying the Reconnection Modal Content</h2><p>As I mentioned earlier, something that is recommended when modifying the <code>ReconnectModal</code> component is to reuse the template classes.</p><p>One way to do this is to use them on existing elements or by creating new tags and assigning them classes like <code>components-reconnect-first-attempt-visible</code>, <code>components-reconnect-repeated-attempt-visible</code>, etc. Here you can take the opportunity to add additional classes that you can style and animate according to your site&rsquo;s or brand&rsquo;s design:</p><pre class=" language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-content<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-title components-reconnect-first-attempt-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        Reconnecting...
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-subtitle components-reconnect-first-attempt-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        Restoring connection to the server
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-title components-reconnect-repeated-attempt-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        Retrying connection
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-subtitle components-reconnect-repeated-attempt-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        Next attempt in <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>components-seconds-to-next-attempt<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>countdown-badge<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span> seconds
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-title error components-reconnect-failed-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        Connection lost
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-subtitle components-reconnect-failed-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        Could not restore connection to the server
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-title warning components-pause-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        Session paused
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-subtitle components-pause-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        The server has temporarily paused the session
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-title error components-resume-failed-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        Resume failed
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-subtitle components-resume-failed-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        Could not resume the session. Please reload the page.
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>In the previous code, we follow the same logic of the template to show different messages according to the connection status. Additionally, we can also take advantage of separating the buttons into a new section, as in the following example:</p><pre class=" language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>reconnect-actions<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>components-reconnect-button<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>btn-primary components-reconnect-failed-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0 0 24 24<span class="token punctuation">"</span></span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>18<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>18<span class="token punctuation">"</span></span> <span class="token attr-name">fill</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>currentColor<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>path</span> <span class="token attr-name">d</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z<span class="token punctuation">"</span></span><span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">&gt;</span></span>
        Retry
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>components-resume-button<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>btn-primary components-pause-visible<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0 0 24 24<span class="token punctuation">"</span></span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>18<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>18<span class="token punctuation">"</span></span> <span class="token attr-name">fill</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>currentColor<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>path</span> <span class="token attr-name">d</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>M8 5v14l11-7z<span class="token punctuation">"</span></span><span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">&gt;</span></span>
        Resume
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Finally, we can modify and add styles to enhance the visual appearance:</p><pre class=" language-css"><code class="prism  language-css"><span class="token selector"><span class="token class">...</span>
<span class="token id">#components-reconnect-modal</span> </span><span class="token punctuation">{</span>
    <span class="token selector">background: linear-gradient(145deg, <span class="token id">#1e293b</span> 0%, <span class="token id">#0f172a</span> 100%);
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0<span class="token class">.5rem</span>;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0<span class="token class">.5</span>), 0 0 0 1px rgba(255, 255, 255, 0<span class="token class">.1</span>);
    opacity: 0;
    transition: display 0<span class="token class">.5s</span> allow-discrete, overlay 0<span class="token class">.5s</span> allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity 0<span class="token class">.5s</span> both;

    &amp;<span class="token attribute">[open]</span> </span><span class="token punctuation">{</span>
        <span class="token property">animation</span><span class="token punctuation">:</span> components-reconnect-modal-slideUp <span class="token number">1.5</span>s <span class="token function">cubic-bezier</span><span class="token punctuation">(</span><span class="token number">.05</span>, <span class="token number">.89</span>, <span class="token number">.25</span>, <span class="token number">1.02</span><span class="token punctuation">)</span> <span class="token number">0.3</span>s, components-reconnect-modal-fadeInOpacity <span class="token number">0.5</span>s ease-in-out <span class="token number">0.3</span>s<span class="token punctuation">;</span>
        <span class="token property">animation-fill-mode</span><span class="token punctuation">:</span> both<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token number">...</span>
<span class="token comment">/* Content */</span>
<span class="token selector"><span class="token class">.reconnect-content</span> </span><span class="token punctuation">{</span>
    <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">/* Titles */</span>
<span class="token selector"><span class="token class">.reconnect-title</span> </span><span class="token punctuation">{</span>
    <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">0</span> <span class="token number">0.5</span>rem<span class="token punctuation">;</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">1.5</span>rem<span class="token punctuation">;</span>
    <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">700</span><span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#f1f5f9</span><span class="token punctuation">;</span>
    <span class="token property">letter-spacing</span><span class="token punctuation">:</span> -<span class="token number">0.02</span>em<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.reconnect-title.error</span> </span><span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#f87171</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.reconnect-title.warning</span> </span><span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#fbbf24</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token selector"><span class="token class">.reconnect-subtitle</span> </span><span class="token punctuation">{</span>
    <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.95</span>rem<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#94a3b8</span><span class="token punctuation">;</span>
    <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.5</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">/* Progress */</span>
<span class="token selector"><span class="token class">.reconnect-progress</span> </span><span class="token punctuation">{</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token hexcode">#334155</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">/* Badge */</span>
<span class="token selector"><span class="token class">.countdown-badge</span> </span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> inline-flex<span class="token punctuation">;</span>
    <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token property">min-width</span><span class="token punctuation">:</span> <span class="token number">28</span>px<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">28</span>px<span class="token punctuation">;</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">8</span>px<span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span><span class="token number">135</span>deg, <span class="token hexcode">#3b82f6</span> <span class="token number">0%</span>, <span class="token hexcode">#2563eb</span> <span class="token number">100%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> white<span class="token punctuation">;</span>
    <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">700</span><span class="token punctuation">;</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.875</span>rem<span class="token punctuation">;</span>
    <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">14</span>px<span class="token punctuation">;</span>
    <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">2</span>px <span class="token number">8</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">0</span>, <span class="token number">0</span>, <span class="token number">0</span>, <span class="token number">0.6</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">/* Actions */</span>
<span class="token selector"><span class="token class">.reconnect-actions</span> </span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">0.75</span>rem<span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">100%</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token class">.btn-primary</span> </span><span class="token punctuation">{</span>
    <span class="token property">flex</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">0.5</span>rem<span class="token punctuation">;</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">0.875</span>rem <span class="token number">1.5</span>rem<span class="token punctuation">;</span>
    <span class="token property">border</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">12</span>px<span class="token punctuation">;</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">1</span>rem<span class="token punctuation">;</span>
    <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">600</span><span class="token punctuation">;</span>
    <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span>
    <span class="token property">transition</span><span class="token punctuation">:</span> all <span class="token number">0.2</span>s ease<span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span><span class="token number">135</span>deg, <span class="token hexcode">#3b82f6</span> <span class="token number">0%</span>, <span class="token hexcode">#2563eb</span> <span class="token number">100%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> white<span class="token punctuation">;</span>
    <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">4</span>px <span class="token number">14</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">59</span>, <span class="token number">130</span>, <span class="token number">246</span>, <span class="token number">0.4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token id">#components-reconnect-modal</span><span class="token class">.components-reconnect-failed</span> <span class="token class">.btn-primary.components-reconnect-failed-visible</span>,
<span class="token id">#components-reconnect-modal</span><span class="token class">.components-reconnect-paused</span> <span class="token class">.btn-primary.components-pause-visible</span> </span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> inline-flex<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token class">.btn-primary</span><span class="token pseudo-class">:hover</span> </span><span class="token punctuation">{</span>
    <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateY</span><span class="token punctuation">(</span>-<span class="token number">2</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">6</span>px <span class="token number">20</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">59</span>, <span class="token number">130</span>, <span class="token number">246</span>, <span class="token number">0.5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span><span class="token number">135</span>deg, <span class="token hexcode">#2563eb</span> <span class="token number">0%</span>, <span class="token hexcode">#1d4ed8</span> <span class="token number">100%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector"><span class="token class">.btn-primary</span><span class="token pseudo-class">:active</span> </span><span class="token punctuation">{</span>
    <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateY</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">2</span>px <span class="token number">8</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">59</span>, <span class="token number">130</span>, <span class="token number">246</span>, <span class="token number">0.4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>With the applied changes, we will have a new and improved dialog that shows the different connection states. In the following image, you can see the dialog when a connection is retried for the first time:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/improved-reconnection-component-adapted-to-a-modern-ui.gif?sfvrsn=1448dc3c_2" alt="Improved reconnection component, adapted to a modern UI" /></p><p>Next, I will show you the rendered dialog when subsequent connection retries are made after the first one:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/reconnection-dialog-showing-subsequent-reconnection-attempts-after-the-initial-failure.png?sfvrsn=2e007dc_2" alt="Reconnection dialog showing subsequent reconnection attempts after the initial failure" /></p><p>Finally, after the connection attempts have failed, you can see the dialog displaying buttons according to the actions the user can take, such as trying to reconnect the application again:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-03/dialog-displaying-action-buttons-after-all-reconnection-attempts-have-failed.png?sfvrsn=f9578b63_2" alt="Dialog displaying action buttons after all reconnection attempts have failed" /></p><p>With the above, we have finished customizing the connection modal correctly.</p><h2 id="conclusion">Conclusion</h2><p>Throughout this article, you have learned more in depth about the <strong>ReconnectionModal</strong> component, which shows how to implement reconnection state handling in Blazor. Additionally, we have turned the default template into a visually elegant modern dialog. I encourage you to create your own version of the dialog to adapt it to your own applications.</p><aside><hr data-sf-ec-immutable="" /><div class="row"><div class="col-4 u-normal-full u-small-mb0"><h4 class="u-fs20 u-fw5 u-lh125 u-mb0">Top 5 Components for Building AI-Powered Blazor Applications</h4></div><div class="col-8"><p class="u-fs16 u-mb0">These five components can help you leverage the power of <a target="_blank" href="https://www.telerik.com/blogs/top-5-components-building-ai-powered-blazor-applications">AI inside your Blazor app</a>.</p></div></div></aside><img src="https://feeds.telerik.com/link/23050/17288838.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:77ec49b2-cef0-464c-9416-0e3e7df1cfb5</id>
    <title type="text">Build Your Own AI Application Using Prebuilt Blazor Components</title>
    <summary type="text">With prebuilt components, you can easily build a Blazor application that connects to AI model services for chat conversations. Check it out.</summary>
    <published>2026-02-25T00:17:09Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Héctor Pérez </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17283200/build-your-own-ai-application-using-prebuilt-blazor-components"/>
    <content type="text"><![CDATA[<p><span class="featured">With prebuilt components, you can easily build a Blazor application that connects to AI model services for chat conversations. Check it out.</span></p><p>If you&rsquo;ve ever had the opportunity to use applications that allow you to converse with a large language model (an LLM) such as ChatGPT, Gemini, DeepSeek, etc., you know about the potential and usefulness they offer.</p><p>Additionally, if you&rsquo;re a software developer, you should know that there are APIs that allow you to create your own applications based on your requirements, making even better use of AI models in a personalized way. In this article, I will show you how to create your own AI application thanks to some pre-created components for Blazor.</p><h2 id="creating-the-chat-project-using-blazor">Creating the Chat Project Using Blazor</h2><p>The first step to creating your own chat application is to create a project using Blazor. In this case, let&rsquo;s use a <strong>Blazor Web App</strong> template, specifying an <strong>Interactive render mode</strong> equal to <strong>Server</strong> and an <strong>Interactivity location</strong> equal to <strong>Global</strong>.</p><p>Next, you should follow the <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/getting-started/web-app">Progress Telerik UI for Blazor components installation guide</a>, which consists of a wide variety of flexible and easy-to-use components that you can implement in just a few minutes to achieve a spectacular graphical interface.</p><h2 id="configuring-the-connection-to-an-ai-model-service">Configuring the Connection to an AI Model Service</h2><p>Once the project has been created, you need to configure a service that can be injected across the pages and that you can reuse to invoke your preferred AI service.</p><p>In this case, we will use <strong>Microsoft.Extensions.AI</strong>, which allows us to easily connect to both Azure OpenAI and OpenAI services, and there are even independent projects like Bruno Capuano&rsquo;s that <a target="_blank" href="https://github.com/elbruno/elbruno-extensions-ai-claude">allows the use of Claude models on Azure</a> using these extensions. In our case, we will install the packages:</p><ul><li><code>Azure.AI.OpenAI</code></li><li><code>Microsoft.Extensions.AI</code></li><li><code>Microsoft.Extensions.AIMicrosoft.Extensions.AI</code></li></ul><p>After installing the packages, we need to go to <code>Program.cs</code> to make the service configuration, which, if it&rsquo;s for OpenAI, can be done like this:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">var</span> key <span class="token operator">=</span> builder<span class="token punctuation">.</span>Configuration<span class="token punctuation">[</span><span class="token string">"OPENAI_API_KEY"</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    builder<span class="token punctuation">.</span>Services
        <span class="token punctuation">.</span><span class="token function">AddChatClient</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">OpenAIClient</span><span class="token punctuation">(</span>
            <span class="token keyword">new</span> <span class="token class-name">ApiKeyCredential</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">GetChatClient</span><span class="token punctuation">(</span><span class="token string">"gpt-4o-mini"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AsIChatClient</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span>
<span class="token punctuation">{</span>
    Debug<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Warning: OPENAI_API_KEY not configured. AI features will not be available."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>Or if you prefer Azure OpenAI, the configuration would look like this:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">var</span> key <span class="token operator">=</span> builder<span class="token punctuation">.</span>Configuration<span class="token punctuation">[</span><span class="token string">"AZURE_OPENAI_API_KEY"</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    builder<span class="token punctuation">.</span>Services
        <span class="token punctuation">.</span><span class="token function">AddChatClient</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">AzureOpenAIClient</span><span class="token punctuation">(</span>
                <span class="token keyword">new</span> <span class="token class-name">Uri</span><span class="token punctuation">(</span><span class="token string">"https://your-endpoint.openai.azure.com/"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>            
            <span class="token keyword">new</span> <span class="token class-name">ApiKeyCredential</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">GetChatClient</span><span class="token punctuation">(</span><span class="token string">"gpt-4.1"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AsIChatClient</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span>
<span class="token punctuation">{</span>
    Debug<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Warning: AZURE_OPENAI_API_KEY not configured. AI features will not be available."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>With the AI model configuration ready, we can proceed to create the main graphical interface.</p><h2 id="initial-setup-of-the-chat-page">Initial Setup of the Chat Page</h2><p>The next step in the project is to create a new page component where we will implement the chat. In this new page, we will replace the content with the following:</p><pre class=" language-xml"><code class="prism  language-xml">@page "/chat"

@using Microsoft.Extensions.AI
@inject IChatClient ChatClient

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>PageTitle</span><span class="token punctuation">&gt;</span></span>AI Chat<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>PageTitle</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>In the code above, we are defining the route for the new page, as well as injecting a reference of type <code>IChatClient</code> (previously configured) using <code>ChatClient</code>. We also specify the title of the page, which you can change as you see fit.</p><h2 id="using-blazor-appbar-to-create-the-application-header">Using Blazor AppBar to Create the Application Header</h2><p>The first prebuilt component we will use is a <a target="_blank" href="https://www.telerik.com/blazor-ui/appbar">Blazor AppBar</a>, which allows us to define sections that can configure actions or visual elements to indicate some type of status in the application.</p><p>To add it, simply define a <code>TelerikAppBar</code> tag, specifying parameters such as <code>ThemeColor</code> and <code>Class</code>:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex flex-column bg-light rounded-3 overflow-hidden shadow-lg<span class="token punctuation">"</span></span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">80</span>vh<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikAppBar</span> <span class="token attr-name">ThemeColor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.AppBar.ThemeColor.Dark<span class="token punctuation">"</span></span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>rounded-top flex-shrink-0<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
       
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikAppBar</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>As part of a <code>TelerikAppBar</code>, <code>AppBarSection</code> type tags must be created to define the sections of the AppBar. In the following example, I will show you how to define three <code>AppBarSection</code>s:</p><pre class=" language-xml"><code class="prism  language-xml">...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div...</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikAppBar</span> <span class="token attr-name">ThemeColor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.AppBar.ThemeColor.Dark<span class="token punctuation">"</span></span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>rounded-top flex-shrink-0<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>AppBarSection</span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>flex-grow-1<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Comment<span class="token punctuation">"</span></span> <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.SvgIcon.Size.Large<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>fw-semibold fs-5 ms-2<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>MyOwnChat<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>AppBarSection</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>AppBarSection</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikDropDownList</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ModelOptions<span class="token punctuation">"</span></span>
                                    <span class="token attr-name">@bind-Value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SelectedModel<span class="token punctuation">"</span></span>
                                    <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>180px<span class="token punctuation">"</span></span>
                                    <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.DropDownList.Size.Small<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikDropDownList</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>AppBarSection</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>AppBarSection</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikButton</span> <span class="token attr-name">OnClick</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ClearChat<span class="token punctuation">"</span></span>
                            <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Trash<span class="token punctuation">"</span></span>
                            <span class="token attr-name">Title</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>New conversation<span class="token punctuation">"</span></span>
                            <span class="token attr-name">ThemeColor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Button.ThemeColor.Light<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikButton</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>AppBarSection</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikAppBar</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

@code{
    private List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>string</span><span class="token punctuation">&gt;</span></span> ModelOptions { get; set; } = new()
    {
        "GPT-5.2",
        "Gemini 2.5",
        "Claude Opus 4.5"
    };
    private string SelectedModel { get; set; } = "GPT-5.2";
    
    private void ClearChat()
    {
    }
}
</code></pre><p>In the code above, the <code>AppBarSection</code>s show the following:</p><ol><li>The first one defines the name of the application.</li><li>The second shows a dropdown that allows selecting an LLM, in case multiple options are available (in the app it works demonstratively).</li><li>The last one allows clearing the conversation.</li></ol><p>Additionally, you can also see the use of other very useful components such as the <a target="_blank" href="https://www.telerik.com/blazor-ui/dropdownlist">Blazor DropDownList</a>, which only needs to be bound to a list of strings, as well as a Button that allows executing actions. The result with just a few lines of code is as follows:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-02/using-the-telerik-appbar-component-to-display-information-in-a-blazor-chat-application.png?sfvrsn=1212c580_2" alt="Using the Telerik AppBar component to display information in a Blazor chat application" /></p><h2 id="building-an-initial-suggestions-list-using-components-for-blazor">Building an Initial Suggestions List Using Components for Blazor</h2><p>The main part of the chat section is divided into two parts. The first determines whether the user has previously interacted with the AI model. This can be done by defining a list of <code>ChatMessage</code>s where the conversation history will be accumulated. If this list is empty, we can make use of a <a target="_blank" href="https://www.telerik.com/blazor-ui/card">Blazor Card</a> that appears in the center with predefined prompt suggestions.</p><p>We can start by defining a <code>CardHeader</code> that displays an icon and some welcome text:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikCard</span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shadow border-0<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardTitle</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Sparkles<span class="token punctuation">"</span></span> <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.SvgIcon.Size.ExtraLarge<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>How can I help you today?<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardTitle</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikCard</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Next, we need to build the body of the card using the <code>CardBody</code> tag. It is important to mention that this component is highly flexible and allows you to insert other components within it, making the interface as complex as you wish.</p><p>For example, we have used a <a target="_blank" href="https://www.telerik.com/blazor-ui/tilelayout">Blazor TileLayout</a> component to define multiple options for the user to press, which is fully configurable. Additionally, you can configure the <code>TileLayoutItems</code> tag within a <code>TelerikTileLayout</code>, where you can define the content for each of these elements.</p><p>In our case, we combined the use of a <a target="_blank" href="https://www.telerik.com/blazor-ui/buttons">Blazor Button</a> together with a <code>span</code> to display the content, resulting in the final code as follows:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>flex-grow-1 bg-white position-relative<span class="token punctuation">"</span></span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">min-height</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    @if (ChatData.Count == 0)
    {
        @* Welcome screen when there are no messages *@
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex align-items-center justify-content-center h-100 p-4 bg-light<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">max-width</span><span class="token punctuation">:</span> <span class="token number">700</span>px<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">100%</span><span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikCard</span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shadow border-0<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardTitle</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Sparkles<span class="token punctuation">"</span></span> <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.SvgIcon.Size.ExtraLarge<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>How can I help you today?<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardTitle</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardBody</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>text-secondary fs-5 mb-4 lh-base text-center<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            I'm your AI assistant. I can help you with questions, analysis, creative writing, and much more.
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikTileLayout</span> <span class="token attr-name">Columns</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>2<span class="token punctuation">"</span></span>
                                           <span class="token attr-name">ColumnWidth</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span>
                                           <span class="token attr-name">RowHeight</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>auto<span class="token punctuation">"</span></span>
                                           <span class="token attr-name">Reorderable</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span>
                                           <span class="token attr-name">Resizable</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span>
                                           <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mt-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TileLayoutItems</span><span class="token punctuation">&gt;</span></span>
                                @foreach (var suggestion in QuickSuggestions)
                                {
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TileLayoutItem</span><span class="token punctuation">&gt;</span></span>
                                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Content</span><span class="token punctuation">&gt;</span></span>
                                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikButton</span> <span class="token attr-name">OnClick</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@(() =&gt; UseSuggestion(suggestion.Text))<span class="token punctuation">"</span></span>
                                                           <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>w-100 text-start d-flex align-items-center gap-2 p-3 border rounded-3<span class="token punctuation">"</span></span>
                                                           <span class="token attr-name">ThemeColor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Button.ThemeColor.Base<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@suggestion.Icon<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>@suggestion.Text<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikButton</span><span class="token punctuation">&gt;</span></span>
                                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Content</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TileLayoutItem</span><span class="token punctuation">&gt;</span></span>
                                }
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TileLayoutItems</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikTileLayout</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardBody</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikCard</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    }
    else
    {
        
    }
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

@code{

    private List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ChatMessage</span><span class="token punctuation">&gt;</span></span> ChatData { get; set; } = new();
    private List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>SuggestionItem</span><span class="token punctuation">&gt;</span></span> QuickSuggestions { get; set; } = new()
    {
        new SuggestionItem { Text = "Explain a concept simply", Icon = SvgIcon.Book },
        new SuggestionItem { Text = "Write a professional email", Icon = SvgIcon.Envelope },
        new SuggestionItem { Text = "Get creative project ideas", Icon = SvgIcon.Palette },
        new SuggestionItem { Text = "Review and improve code", Icon = SvgIcon.Code }
    };

    private async Task UseSuggestion(string suggestion)
    {
        
    }
    ...
    public class SuggestionItem
    {
        public string Text { get; set; } = string.Empty;
        public ISvgIcon Icon { get; set; } = SvgIcon.Star;
    }
}
...
</code></pre><p>The result of rendering with the previous changes gives us the following:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-02/creating-an-initial-suggestions-list-in-an-ai-powered-chat-app-using-prebuilt-telerik-components.png?sfvrsn=f9d2d880_2" alt="Creating an initial suggestions list in an AI-powered chat app using prebuilt Telerik components" /></p><p>You can see that the application begins to take shape, showing an initial suggestions section for the user to interact with the LLM as quickly as possible.</p><h2 id="sending-messages-to-the-llm">Sending Messages to the LLM</h2><p>At this point, let&rsquo;s make the initial suggestion buttons send an instruction to the chat section. To do this, we will define some pieces of code that will be necessary for the graphical interface to function:</p><p><strong>Properties:</strong></p><ul><li><code>IsProcessing</code>: Property to indicate to the application whether a request is being processed to the AI model.</li><li><code>CurrentUserId</code>: ID of the current user. While we will set it as <em>user</em>, you could adapt it for the user to input their own nickname.</li><li><code>ConversationHistory</code>: A second list that allows interaction with the service that hosts the LLM. We use this because <code>ChatData</code> has an incompatible structure with the methods within <code>Microsoft.Extensions.AI</code>.</li><li><code>ChatSuggestions</code>: List that will be used by the Chat component to show the user prompt suggestions they can use during the conversation.</li></ul><p><strong>Methods:</strong></p><ul><li><code>UseSuggestion</code>: Method used from each <code>TelerikButton</code> defined in <code>TelerikTileLayout</code>, which invokes the <code>OnSendMessage</code> method.</li><li><code>OnSendMessage</code>: This is where the magic happens. The method serves to mark <code>IsProcessing</code> as true, indicating that processing of the prompt has started. Then, two elements of type <code>ChatMessage</code> are generated, the first called <code>userMessage</code>, which defines the user&rsquo;s query, and the second called <code>aiTypingMessage</code>, which will contain the response from the AI model. Next, within a <code>try</code>/<code>catch</code>/<code>finally</code>, the AI model service is invoked and the information in <code>aiTypingMessage</code> is updated.</li><li><code>UpdateSuggestions</code>: Method that allows updating the suggestions list <code>ChatSuggestions</code> that will be used by the Chat component in real time. These suggestions are fixed in the example, but you could modify the method to suggest a new list to the user based on the flow of information generated by AI.</li></ul><p><strong>Classes:</strong></p><ul><li><code>ChatMessage</code>: Class that will be used in the Chat component, allowing the management of information about a chat message such as the author&rsquo;s name, author&rsquo;s image, text, whether the status is typing, etc.</li></ul><p>The code updates are as follows:</p><pre class=" language-csharp"><code class="prism  language-csharp">@code<span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">bool</span> IsProcessing <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">false</span><span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">string</span> CurrentUserId <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token string">"user"</span><span class="token punctuation">;</span>
    <span class="token keyword">private</span> List<span class="token operator">&lt;</span>Microsoft<span class="token punctuation">.</span>Extensions<span class="token punctuation">.</span>AI<span class="token punctuation">.</span>ChatMessage<span class="token operator">&gt;</span> ConversationHistory <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">new</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">private</span> List<span class="token operator">&lt;</span><span class="token keyword">string</span><span class="token operator">&gt;</span> ChatSuggestions <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">new</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>

    <span class="token keyword">private</span> <span class="token keyword">async</span> Task <span class="token function">UseSuggestion</span><span class="token punctuation">(</span><span class="token keyword">string</span> suggestion<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">var</span> args <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ChatSendMessageEventArgs</span> <span class="token punctuation">{</span> Message <span class="token operator">=</span> suggestion <span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token keyword">await</span> <span class="token function">OnSendMessage</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">async</span> Task <span class="token function">OnSendMessage</span><span class="token punctuation">(</span>ChatSendMessageEventArgs args<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrWhiteSpace</span><span class="token punctuation">(</span>args<span class="token punctuation">.</span>Message<span class="token punctuation">)</span> <span class="token operator">||</span> IsProcessing<span class="token punctuation">)</span>
            <span class="token keyword">return</span><span class="token punctuation">;</span>

        IsProcessing <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">;</span>
        
        <span class="token keyword">var</span> userMessage <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ChatMessage</span>
        <span class="token punctuation">{</span>
            Id <span class="token operator">=</span> Guid<span class="token punctuation">.</span><span class="token function">NewGuid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            AuthorId <span class="token operator">=</span> CurrentUserId<span class="token punctuation">,</span>
            AuthorName <span class="token operator">=</span> <span class="token string">"You"</span><span class="token punctuation">,</span>
            AuthorImageUrl <span class="token operator">=</span> <span class="token string">"https://api.dicebear.com/7.x/avataaars/svg?seed=user"</span><span class="token punctuation">,</span>
            Text <span class="token operator">=</span> args<span class="token punctuation">.</span>Message<span class="token punctuation">,</span>
            Timestamp <span class="token operator">=</span> DateTime<span class="token punctuation">.</span>Now<span class="token punctuation">,</span>
            Status <span class="token operator">=</span> <span class="token string">"Sent"</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
        ChatData<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>userMessage<span class="token punctuation">)</span><span class="token punctuation">;</span>
        
        ConversationHistory<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Microsoft<span class="token punctuation">.</span>Extensions<span class="token punctuation">.</span>AI<span class="token punctuation">.</span>ChatMessage</span><span class="token punctuation">(</span>ChatRole<span class="token punctuation">.</span>User<span class="token punctuation">,</span> args<span class="token punctuation">.</span>Message<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        
        <span class="token keyword">var</span> aiTypingMessage <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ChatMessage</span>
        <span class="token punctuation">{</span>
            Id <span class="token operator">=</span> Guid<span class="token punctuation">.</span><span class="token function">NewGuid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            AuthorId <span class="token operator">=</span> <span class="token string">"ai"</span><span class="token punctuation">,</span>
            AuthorName <span class="token operator">=</span> <span class="token string">"AI Assistant"</span><span class="token punctuation">,</span>
            AuthorImageUrl <span class="token operator">=</span> <span class="token string">"https://api.dicebear.com/7.x/bottts/svg?seed=ai"</span><span class="token punctuation">,</span>
            Text <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">,</span>
            Timestamp <span class="token operator">=</span> DateTime<span class="token punctuation">.</span>Now<span class="token punctuation">,</span>
            IsTyping <span class="token operator">=</span> <span class="token keyword">true</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
        ChatData<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>aiTypingMessage<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">RefreshChat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">try</span>
        <span class="token punctuation">{</span>            
            <span class="token keyword">var</span> response <span class="token operator">=</span> <span class="token keyword">await</span> ChatClient<span class="token punctuation">.</span><span class="token function">GetResponseAsync</span><span class="token punctuation">(</span>ConversationHistory<span class="token punctuation">)</span><span class="token punctuation">;</span>
            
            aiTypingMessage<span class="token punctuation">.</span>IsTyping <span class="token operator">=</span> <span class="token keyword">false</span><span class="token punctuation">;</span>
            aiTypingMessage<span class="token punctuation">.</span>Text <span class="token operator">=</span> response<span class="token punctuation">.</span>Text <span class="token operator">?</span><span class="token operator">?</span> <span class="token string">"Sorry, I couldn't generate a response."</span><span class="token punctuation">;</span>
            aiTypingMessage<span class="token punctuation">.</span>Status <span class="token operator">=</span> <span class="token string">"Delivered"</span><span class="token punctuation">;</span>
            
            ConversationHistory<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Microsoft<span class="token punctuation">.</span>Extensions<span class="token punctuation">.</span>AI<span class="token punctuation">.</span>ChatMessage</span><span class="token punctuation">(</span>ChatRole<span class="token punctuation">.</span>Assistant<span class="token punctuation">,</span> aiTypingMessage<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token function">UpdateSuggestions</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">ShowNotification</span><span class="token punctuation">(</span><span class="token string">"Response received"</span><span class="token punctuation">,</span> ThemeConstants<span class="token punctuation">.</span>Notification<span class="token punctuation">.</span>ThemeColor<span class="token punctuation">.</span>Success<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> ex<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            aiTypingMessage<span class="token punctuation">.</span>IsTyping <span class="token operator">=</span> <span class="token keyword">false</span><span class="token punctuation">;</span>
            aiTypingMessage<span class="token punctuation">.</span>Text <span class="token operator">=</span> $<span class="token string">"Error processing the request: {ex.Message}"</span><span class="token punctuation">;</span>
            aiTypingMessage<span class="token punctuation">.</span>Status <span class="token operator">=</span> <span class="token string">"Error"</span><span class="token punctuation">;</span>

            <span class="token function">ShowNotification</span><span class="token punctuation">(</span><span class="token string">"Processing error"</span><span class="token punctuation">,</span> ThemeConstants<span class="token punctuation">.</span>Notification<span class="token punctuation">.</span>ThemeColor<span class="token punctuation">.</span>Error<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">finally</span>
        <span class="token punctuation">{</span>
            IsProcessing <span class="token operator">=</span> <span class="token keyword">false</span><span class="token punctuation">;</span>
            <span class="token function">RefreshChat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">ClearChat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
    <span class="token punctuation">}</span>


    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">RefreshChat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>        
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">ShowNotification</span><span class="token punctuation">(</span><span class="token keyword">string</span> message<span class="token punctuation">,</span> <span class="token keyword">string</span> themeColor<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
    <span class="token punctuation">}</span>

    
    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">UpdateSuggestions</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>ChatData<span class="token punctuation">.</span>Count <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            ChatSuggestions <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span><span class="token keyword">string</span><span class="token operator">&gt;</span>
            <span class="token punctuation">{</span>
                <span class="token string">"What can you do?"</span><span class="token punctuation">,</span>
                <span class="token string">"Tell me a fun fact"</span><span class="token punctuation">,</span>
                <span class="token string">"Help me with code"</span>
            <span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">else</span>
        <span class="token punctuation">{</span>
            ChatSuggestions <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span><span class="token keyword">string</span><span class="token operator">&gt;</span>
            <span class="token punctuation">{</span>
                <span class="token string">"Continue"</span><span class="token punctuation">,</span>
                <span class="token string">"Explain more"</span><span class="token punctuation">,</span>
                <span class="token string">"Give me an example"</span><span class="token punctuation">,</span>
                <span class="token string">"Summarize please"</span>
            <span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>

    <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ChatMessage</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> Id <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> AuthorId <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> AuthorName <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> AuthorImageUrl <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> Text <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>
        <span class="token keyword">public</span> DateTime Timestamp <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> Status <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>
        <span class="token keyword">public</span> <span class="token keyword">bool</span> IsTyping <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
        <span class="token keyword">public</span> <span class="token keyword">bool</span> IsPinned <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>The execution of the application gives us the following result:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-02/the-chat-application-built-with-prebuilt-components-ready-to-display-a-conversation-with-an-ai-model.gif?sfvrsn=8bdbae4_2" alt="The chat application built with prebuilt components, ready to display a conversation with an AI model" /></p><p>In the previous image, you can see the transition that occurs when there are elements in ChatData, which would allow the Chat component to be displayed.</p><h2 id="defining-the-chat-section">Defining the Chat Section</h2><p>In the previous section, we left everything set up to start a chat conversation. Now, we&rsquo;re going to use the <a target="_blank" href="https://www.telerik.com/blazor-ui/chat-(conversational-ui)">Blazor Chat</a> component from Progress Telerik to manage the conversation with the LLM in a straightforward way, as this component is highly customizable and has all the necessary functionality for rapid implementation.</p><p>The code we&rsquo;ll add in the UI is as follows:</p><pre class=" language-xml"><code class="prism  language-xml">else
{    
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikChat</span> <span class="token attr-name">@ref</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ChatRef<span class="token punctuation">"</span></span>
                 <span class="token attr-name">TItem</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>ChatMessage<span class="token punctuation">"</span></span>
                 <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ChatData<span class="token punctuation">"</span></span>
                 <span class="token attr-name">AuthorId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@CurrentUserId<span class="token punctuation">"</span></span>
                 <span class="token attr-name">OnSendMessage</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@OnSendMessage<span class="token punctuation">"</span></span>
                 <span class="token attr-name">Suggestions</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ChatSuggestions<span class="token punctuation">"</span></span>
                 <span class="token attr-name">OnSuggestionClick</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@OnSuggestionClick<span class="token punctuation">"</span></span>
                 <span class="token attr-name">SuggestionsLayoutMode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ChatSuggestionsLayoutMode.ScrollButtons<span class="token punctuation">"</span></span>                         
                 <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span>
                 <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span>
                 <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>border-0 bg-white<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>HeaderTemplate</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex align-items-center gap-3 px-3 py-2 bg-light border-bottom<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikChip</span> <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Chip.Size.Small<span class="token punctuation">"</span></span>
                             <span class="token attr-name">ThemeColor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Chip.ThemeColor.Success<span class="token punctuation">"</span></span>
                             <span class="token attr-name">Rounded</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Chip.Rounded.Full<span class="token punctuation">"</span></span>
                             <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.CheckCircle<span class="token punctuation">"</span></span>
                             <span class="token attr-name">Text</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Connected<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikChip</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>small text-secondary<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@ChatData.Count messages<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>HeaderTemplate</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ReceiverMessageContentTemplate</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>lh-lg<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                @if (context.Message.IsTyping)
                {
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikLoader</span> <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Loader.Size.Small<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikLoader</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>ms-2 text-secondary fst-italic<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Thinking...<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                }
                else
                {
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>MarkdownContent</span> <span class="token attr-name">Message</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@context.Message.Text<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                }
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ReceiverMessageContentTemplate</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>AuthorMessageContentTemplate</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>lh-lg<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                @context.Message.Text
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>AuthorMessageContentTemplate</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NoDataTemplate</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex flex-column align-items-center justify-content-center p-5 text-secondary<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Comment<span class="token punctuation">"</span></span> <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.SvgIcon.Size.ExtraLarge<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mt-3 fs-5<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>No messages yet. Start a conversation!<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>NoDataTemplate</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikChat</span><span class="token punctuation">&gt;</span></span>
}
</code></pre><p>In the code above, as part of the <code>else</code> that is shown if <code>ChatData</code> contains items, a <code>TelerikChat</code> bound to <code>ChatData</code> is created, which contains all the conversation information. Additionally, properties such as <code>Suggestions</code>, <code>AuthorId</code>, among others, are used to configure the component.</p><p>In addition to configuring the component through parameters, other tags like <code>HeaderTemplate</code> can also be defined to display the connection status to the service, as well as the number of messages within the conversation.</p><p><code>ReceiverMessageContentTemplate</code> is also used to define the content depending on the status of the request to the AI service. If the message is awaited, a <a target="_blank" href="https://www.telerik.com/blazor-ui/loader">Blazor Loader</a> component is used to show a loading state. If a response is available, the content is displayed in the chat.</p><p>At this point, we have defined a component called <code>MarkdownContent</code>, which is based on the NuGet package <a target="_blank" href="https://github.com/xoofx/markdig"><code>Markdig</code></a> that allows converting the markdown text received from the LLM into a <code>HTML</code> version, enabling the correct format for each markdown element in the conversation.</p><p>In addition to the above, <code>AuthorMessageContentTemplate</code> is also specified to define the template for user messages and <code>NoDataTemplate</code> in case we want to show content when there are no chat messages in the conversation.</p><p>In the code section, we need to add a reference to the component <code>TelerikChat</code>, which allows us to execute the method <code>Refresh</code> from the method <code>RefreshChat</code>, in addition to the event handler definition <code>OnSuggestionClick</code>, which allows handling the suggestions from the component (different from the options at the beginning of execution), as follows:</p><pre class=" language-csharp"><code class="prism  language-csharp">@code<span class="token punctuation">{</span>

    <span class="token keyword">private</span> TelerikChat<span class="token operator">&lt;</span>ChatMessage<span class="token operator">&gt;</span><span class="token operator">?</span> ChatRef <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">async</span> Task <span class="token function">OnSuggestionClick</span><span class="token punctuation">(</span>ChatSuggestionClickEventArgs args<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">await</span> <span class="token function">UseSuggestion</span><span class="token punctuation">(</span>args<span class="token punctuation">.</span>Suggestion<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">RefreshChat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        ChatRef<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">Refresh</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">StateHasChanged</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token punctuation">}</span>
</code></pre><p>With the code above, we already have a Chat section that allows us to interact with an LLM:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-02/the-chat-app-displaying-the-telerikchat-component-enabling-conversations-with-an-llm-model.gif?sfvrsn=8bdaa5dc_2" alt="The chat app displaying the TelerikChat component, enabling conversations with an LLM" /></p><p>With this, you have been able to see that the chat implementation is already working correctly.</p><h2 id="creating-a-toolbar-like-footer">Creating a ToolBar-like Footer</h2><p>The last section we will work on is the footer. We will do this using a <a target="_blank" href="https://www.telerik.com/blazor-ui/toolbar">Blazor ToolBar</a>, which allows us to add a toolbar for buttons, separators, and even custom content. Our code looks as follows:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>bg-white border-top flex-shrink-0<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikToolBar</span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>bg-transparent border-0 px-3 py-2<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ToolBarButton</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.InfoCircle<span class="token punctuation">"</span></span> <span class="token attr-name">OnClick</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ShowAboutDialog<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>About<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ToolBarButton</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ToolBarSeparator</span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ToolBarTemplateItem</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex align-items-center gap-1 text-secondary small<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Clock<span class="token punctuation">"</span></span> <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.SvgIcon.Size.Small<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                @DateTime.Now.ToString("HH:mm")
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ToolBarTemplateItem</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ToolBarSpacer</span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ToolBarTemplateItem</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikChip</span> <span class="token attr-name">ThemeColor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Chip.ThemeColor.Info<span class="token punctuation">"</span></span>
                            <span class="token attr-name">Rounded</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Chip.Rounded.Full<span class="token punctuation">"</span></span>
                            <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Chip.Size.Small<span class="token punctuation">"</span></span>
                            <span class="token attr-name">Selectable</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span>
                            <span class="token attr-name">Text</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SelectedModel<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikChip</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ToolBarTemplateItem</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikToolBar</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

...

@code {

    private bool ShowAboutDialogVisible { get; set; } = false;

    private void ShowAboutDialog()
    {
        ShowAboutDialogVisible = true;
    }
    ...
}
</code></pre><p>In the code above, we see the following elements in sequence:</p><ul><li><code>ToolBarButton</code> to display a button that we can press to show an information window about the app.</li><li><code>ToolBarSeparator</code> to display a separator line between elements.</li><li><code>ToolBarTemplateItem</code> to show custom content, specifically the current time.</li><li><code>ToolBarSpacer</code> to push the subsequent elements to the right of the main control.</li><li><code>ToolBarTemplateItem</code> to display custom content. In this case, we are using a <a target="_blank" href="https://www.telerik.com/blazor-ui/chip"><code>TelerikChip</code></a>, which allows displaying tag-like elements that we use to show the selected model.</li></ul><p>In addition to the above, we have prepared the logic to display application information through the definition of the <code>ShowAboutDialogVisible</code> property and the <code>ShowAboutDialog</code> method.</p><p>The result of running the application after applying the changes is as follows:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-02/implementing-a-toolbar-in-the-chat-application-using-the-teleriktoolbar-component.png?sfvrsn=c99acbd2_2" alt="Implementing a toolbar in the chat application using the TelerikToolBar component" /></p><h2 id="displaying-application-information">Displaying Application Information</h2><p>In most applications, it is essential to be able to show application information to users, whether to specify the version, usage quotas, payment information, etc. We can easily achieve this by using the <a target="_blank" href="https://www.telerik.com/blazor-ui/dialog">Blazor Dialog</a> component, which we can show and hide at will, customizing its content thanks to the <code>DialogContent</code> tag.</p><p>In our case, we used a <code>TelerikCard</code> to show information about the application as follows:</p><pre><code>...
&lt;TelerikDialog @bind-Visible="@ShowAboutDialogVisible"
               Title="About MyOwnChat"
               Width="400px"&gt;
    &lt;DialogContent&gt;
        &lt;TelerikCard&gt;
            &lt;CardBody&gt;
                &lt;div class="text-center p-3"&gt;
                    &lt;TelerikSvgIcon Icon="@SvgIcon.Sparkles" Size="@ThemeConstants.SvgIcon.Size.ExtraLarge" /&gt;
                    &lt;h3 class="mt-3 mb-2"&gt;MyOwnChat&lt;/h3&gt;
                    &lt;p class="text-secondary mb-4"&gt;An AI-powered chat interface, built with Blazor and Telerik UI.&lt;/p&gt;
                    &lt;TelerikChipList Data="@AboutChips"
                                     SelectionMode="@ChipListSelectionMode.None"&gt;
                    &lt;/TelerikChipList&gt;
                &lt;/div&gt;
            &lt;/CardBody&gt;
        &lt;/TelerikCard&gt;
    &lt;/DialogContent&gt;
    &lt;DialogButtons&gt;
        &lt;TelerikButton OnClick="@(() =&gt; ShowAboutDialogVisible = false)"
                       ThemeColor="@ThemeConstants.Button.ThemeColor.Dark"&gt;
            Close
        &lt;/TelerikButton&gt;
    &lt;/DialogButtons&gt;
&lt;/TelerikDialog&gt;

@code {


    private List&lt;ChipItem&gt; AboutChips { get; set; } = new()
    {
        new ChipItem { Text = "Blazor" },
        new ChipItem { Text = "Telerik UI" },
        new ChipItem { Text = "AI Powered" }
    };

    ...

    public class ChipItem
    {
        public string Text { get; set; } = string.Empty;
    }
}
</code></pre><p>The previous code results in the following interaction:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-02/displaying-chat-application-information-in-a-separate-dialog-using-the-telerikdialog-component.gif?sfvrsn=328d3802_2" alt="Displaying chat application information in a separate dialog using the TelerikDialog component" /></p><p>Now, let&rsquo;s look at the last component that allows us to show notifications.</p><h2 id="displaying-notifications-in-the-blazor-chat-app">Displaying Notifications in the Blazor Chat App</h2><p>The last component we will use for our chat application is <a target="_blank" href="https://www.telerik.com/blazor-ui/notification">Blazor Notification</a>, which allows displaying notifications to users to keep them informed about the status of actions in the application. Defining it is very simple:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikNotification</span> <span class="token attr-name">@ref</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@NotificationRef<span class="token punctuation">"</span></span>
                     <span class="token attr-name">VerticalPosition</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@NotificationVerticalPosition.Top<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikNotification</span><span class="token punctuation">&gt;</span></span>

@code {

    private TelerikNotification? NotificationRef { get; set; }
    ...
    private void ShowNotification(string message, string themeColor)
    {
        NotificationRef?.Show(new NotificationModel
        {
            Text = message,
            ThemeColor = themeColor,
            CloseAfter = 3000
        });
    }
}
</code></pre><p>In the code above, the <code>TelerikNotification</code> tag is defined by assigning the <code>@ref</code> parameter a property defined in the code, which allows displaying a notification. Within <code>ShowNotification</code>, the <code>Show</code> method is invoked, where we specify the message to display, color and how long the notification should be shown:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-02/displaying-notifications-in-the-chat-app-using-the-teleriknotification-component.png?sfvrsn=8bf3416e_2" alt="Displaying notifications in the chat app using the TelerikNotification component" /></p><h2 id="clearing-the-chat">Clearing the Chat</h2><p>To finish the application, we will complete the implementation of the <code>ClearChat</code> method so that the user can restart a conversation from scratch:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">ClearChat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    ChatData<span class="token punctuation">.</span><span class="token function">Clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    ConversationHistory<span class="token punctuation">.</span><span class="token function">Clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">UpdateSuggestions</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">ShowNotification</span><span class="token punctuation">(</span><span class="token string">"Conversation cleared"</span><span class="token punctuation">,</span> ThemeConstants<span class="token punctuation">.</span>Notification<span class="token punctuation">.</span>ThemeColor<span class="token punctuation">.</span>Info<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>In the code above, the conversation lists are reset, the suggestions are updated with the initials, and a message is displayed to the user regarding the clearing of conversations.</p><h2 id="conclusion">Conclusion</h2><p>Throughout this article, we have selected prebuilt Telerik components for Blazor that allowed us to create a chat application that connects to AI model services for chat conversations.</p><p>Using prebuilt components helps make your development faster by providing a wide list of parameters that assist in customizing the graphical interface, as we have seen throughout the article. Additionally, you can be assured that the components are robust and are constantly updated, improving them through user feedback.</p><p>If you aren't already using Telerik UI for Blazor, you can try it free for 30 days:</p><p><a href="https://www.telerik.com/try/ui-for-blazor" target="_blank" class="Btn">Try Now</a></p><img src="https://feeds.telerik.com/link/23050/17283200.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:6424c9d1-f6fa-4231-9a0c-5ebc5fbe5b6f</id>
    <title type="text">Creating Drag-and-Drop ListBoxes in Blazor</title>
    <summary type="text">See how the Telerik UI for Blazor ListBox makes implementing dragging and dropping items between lists easy—based on a real-life case!</summary>
    <published>2026-02-16T17:12:19Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Héctor Pérez </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17277349/creating-drag-drop-listboxes-blazor"/>
    <content type="text"><![CDATA[<p><span class="featured">See how the Telerik UI for Blazor ListBox makes implementing dragging and dropping items between lists easy&mdash;based on a real-life case!</span></p><p>There are applications that require very specific use cases to solve real problems. One such case is the need to implement functionality to drag and drop items between different list-like controls.</p><p>This functionality can be found natively in the <a target="_blank" href="https://www.telerik.com/blazor-ui/listbox">Blazor ListBox</a> component from Progress Telerik, making it an excellent option in these scenarios, which is why I will show you how to implement drag and drop between several components of this type.</p><h2 id="dragging-items-between-listboxes-in-blazor-a-practical-case">Dragging Items Between ListBoxes in Blazor: A Practical Case</h2><p>I have to admit that the idea for this post was born from a real-life case, which I will share to provide you with its background. I teach online software development courses, several of which are hosted on a fairly popular platform. This platform offers instructors the convenience of creating coupons using a graphical interface from the dashboard of a particular course.</p><p>The problem arises when the instructor has many courses on the platform and wants to create coupons in bulk quickly. The platform has a system based on <code>.csv</code> files to solve this problem, although it is not the best option for someone who is not involved in the technology field.</p><p>The first <code>.csv</code> file provided by the platform is a file containing the list of all the instructor&rsquo;s courses, from which data such as course ID, course name, among other data can be extracted, and it looks like this:</p><pre class=" language-csv"><code class="prism  language-csv">"course_id","course_name","currency","best_price_value","min_custom_price","max_custom_price","coupons_remaining"
1234567,".NET MAUI: Advanced UI and Custom Control Techniques","USD",9.99,12.99,79.99,3
</code></pre><p>The second <code>.csv</code> file provided is a template to fill in the information for the coupons to be created, in which information such as the discount to be applied, course ID, coupon start date, among other data must be included:</p><pre class=" language-csv"><code class="prism  language-csv">course_id,coupon_type,coupon_code,price,start_date,start_time,custom_price
1234567,best_price,DEVJUN1,9.99,2025-06-16,19:44,
</code></pre><p>Now, here comes the important part. The data <code>coupon_type</code> specifies whether the coupon is paid or free, specified in four possible values:</p><ul><li>best_price</li><li>custom_price</li><li>free_targeted</li><li>free_open</li></ul><p>Once the csv template is filled with the courses that will have a coupon applied, it can be uploaded on the same portal for the bulk generation of the coupons. The previous process can be quite complicated for instructors not involved in technology, which we can simplify thanks to the use of the Telerik UI for Blazor ListBox component.</p><h2 id="creating-a-component-page-using-listbox">Creating a Component Page Using ListBox</h2><p>The ListBox component is a quite powerful tool that allows you to display lists of selectable, reorderable, deletable items and more. One thing I really like about this component is that you can customize it as much as you want through the tag <code>ItemTemplate</code>.</p><p>For our demonstration, I have created a page-type component applying various styles, so you can see the potential of using the ListBox component in action:</p><pre class=" language-xml"><code class="prism  language-xml">@page "/"


<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>PageTitle</span><span class="token punctuation">&gt;</span></span>Drag &amp; Drop Demo<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>PageTitle</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikRootComponent</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>demo-container<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>demo-header<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">&gt;</span></span>Drag and Drop Demo<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>lists-container<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>source-column<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>list-card available-card<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>list-header<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h4</span><span class="token punctuation">&gt;</span></span>Available Courses<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h4</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>badge<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@AvailableCourses.Count<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikListBox</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@AvailableCourses<span class="token punctuation">"</span></span>
                                    <span class="token attr-name">TextField</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@nameof(Course.Name)<span class="token punctuation">"</span></span>
                                    <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>400px<span class="token punctuation">"</span></span>
                                    <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ListBoxToolBarSettings</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ListBoxToolBar</span> <span class="token attr-name">Visible</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ListBoxToolBarSettings</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ItemTemplate</span><span class="token punctuation">&gt;</span></span>
                            @{
                                var course = context;
                            }
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-item<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-info<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-name<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@course.Name<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-price<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@course.Currency @course.Price.ToString("N2")<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-category<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@course.Category<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ItemTemplate</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikListBox</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>destination-columns<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>coupon-grid<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>                    
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>list-card best-price-card<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>list-header<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h4</span><span class="token punctuation">&gt;</span></span>Best Price<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h4</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>badge<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@BestPriceCourses.Count<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikListBox</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@BestPriceCourses<span class="token punctuation">"</span></span>
                                        <span class="token attr-name">TextField</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@nameof(Course.Name)<span class="token punctuation">"</span></span>
                                        <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span>
                                        <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>200px<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ListBoxToolBarSettings</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ListBoxToolBar</span> <span class="token attr-name">Visible</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ListBoxToolBarSettings</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ItemTemplate</span><span class="token punctuation">&gt;</span></span>
                                @{
                                    var course = context;
                                }
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-item-mini<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-name<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@course.Name<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-tag best-price<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@course.Currency @course.Price.ToString("N2")<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ItemTemplate</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NoDataTemplate</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>no-data<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>Drop courses here<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>NoDataTemplate</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikListBox</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                    
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>list-card custom-price-card<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>list-header<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h4</span><span class="token punctuation">&gt;</span></span>Custom Price<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h4</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>badge<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@CustomPriceCourses.Count<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikListBox</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@CustomPriceCourses<span class="token punctuation">"</span></span>
                                        <span class="token attr-name">TextField</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@nameof(Course.Name)<span class="token punctuation">"</span></span>                                        
                                        <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span>
                                        <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>200px<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ListBoxToolBarSettings</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ListBoxToolBar</span> <span class="token attr-name">Visible</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ListBoxToolBarSettings</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ItemTemplate</span><span class="token punctuation">&gt;</span></span>
                                @{
                                    var course = context;
                                }
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-item-mini<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-name<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@course.Name<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-tag custom-price<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@course.Currency @course.Price.ToString("N2")<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ItemTemplate</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NoDataTemplate</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>no-data<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>Drop courses here<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>NoDataTemplate</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikListBox</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                    
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>list-card free-open-card<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>list-header<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h4</span><span class="token punctuation">&gt;</span></span>Free Open<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h4</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>badge<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@FreeOpenCourses.Count<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikListBox</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@FreeOpenCourses<span class="token punctuation">"</span></span>
                                        <span class="token attr-name">TextField</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@nameof(Course.Name)<span class="token punctuation">"</span></span>                                        
                                        <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span>
                                        <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>200px<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ListBoxToolBarSettings</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ListBoxToolBar</span> <span class="token attr-name">Visible</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ListBoxToolBarSettings</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ItemTemplate</span><span class="token punctuation">&gt;</span></span>
                                @{
                                    var course = context;
                                }
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-item-mini<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-name<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@course.Name<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-tag free<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>FREE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ItemTemplate</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NoDataTemplate</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>no-data<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>Drop courses here<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>NoDataTemplate</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikListBox</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                    
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>list-card free-targeted-card<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>list-header<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h4</span><span class="token punctuation">&gt;</span></span>Free Targeted<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h4</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>badge<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@FreeTargetedCourses.Count<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikListBox</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@FreeTargetedCourses<span class="token punctuation">"</span></span>
                                        <span class="token attr-name">TextField</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@nameof(Course.Name)<span class="token punctuation">"</span></span>                                        
                                        <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span>
                                        <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>200px<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ListBoxToolBarSettings</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ListBoxToolBar</span> <span class="token attr-name">Visible</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ListBoxToolBarSettings</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ItemTemplate</span><span class="token punctuation">&gt;</span></span>
                                @{
                                    var course = context;
                                }
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-item-mini<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-name<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@course.Name<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>course-tag targeted<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>TARGETED<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ItemTemplate</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NoDataTemplate</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>no-data<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>Drop courses here<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>NoDataTemplate</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikListBox</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikRootComponent</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">&gt;</span></span><span class="token style language-css">
    <span class="token selector"><span class="token pseudo-class">:root</span> </span><span class="token punctuation">{</span>
        <span class="token property">--bg-color</span><span class="token punctuation">:</span> <span class="token hexcode">#1e1e1e</span><span class="token punctuation">;</span>
        <span class="token property">--bg-accent</span><span class="token punctuation">:</span> <span class="token hexcode">#252526</span><span class="token punctuation">;</span>
        <span class="token property">--card-glass</span><span class="token punctuation">:</span> <span class="token hexcode">#252526</span><span class="token punctuation">;</span>
        <span class="token property">--border-glass</span><span class="token punctuation">:</span> <span class="token hexcode">#3c3c3c</span><span class="token punctuation">;</span>
        <span class="token property">--accent-blue</span><span class="token punctuation">:</span> <span class="token hexcode">#4ec9b0</span><span class="token punctuation">;</span>
        <span class="token property">--accent-purple</span><span class="token punctuation">:</span> <span class="token hexcode">#c586c0</span><span class="token punctuation">;</span>
        <span class="token property">--accent-green</span><span class="token punctuation">:</span> <span class="token hexcode">#608b4e</span><span class="token punctuation">;</span>
        <span class="token property">--accent-amber</span><span class="token punctuation">:</span> <span class="token hexcode">#d7ba7d</span><span class="token punctuation">;</span>
        <span class="token property">--accent-red</span><span class="token punctuation">:</span> <span class="token hexcode">#f48771</span><span class="token punctuation">;</span>
        <span class="token property">--text-main</span><span class="token punctuation">:</span> <span class="token hexcode">#d4d4d4</span><span class="token punctuation">;</span>
        <span class="token property">--text-muted</span><span class="token punctuation">:</span> <span class="token hexcode">#858585</span><span class="token punctuation">;</span>
        <span class="token property">--shadow-soft</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">8</span>px <span class="token number">16</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">0</span>, <span class="token number">0</span>, <span class="token number">0</span>, <span class="token number">0.45</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">--radius-lg</span><span class="token punctuation">:</span> <span class="token number">10</span>px<span class="token punctuation">;</span>
        <span class="token property">--radius-md</span><span class="token punctuation">:</span> <span class="token number">8</span>px<span class="token punctuation">;</span>
        <span class="token property">--transition-fast</span><span class="token punctuation">:</span> <span class="token number">0.15</span>s ease-out<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.demo-container</span> </span><span class="token punctuation">{</span>
        <span class="token property">min-height</span><span class="token punctuation">:</span> <span class="token function">calc</span><span class="token punctuation">(</span><span class="token number">100</span>vh - <span class="token number">40</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">max-width</span><span class="token punctuation">:</span> <span class="token number">1440</span>px<span class="token punctuation">;</span>
        <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span> auto<span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">24</span>px <span class="token number">20</span>px <span class="token number">32</span>px<span class="token punctuation">;</span>
        <span class="token property">font-family</span><span class="token punctuation">:</span> system-ui, -apple-system, BlinkMacSystemFont, <span class="token string">'Segoe UI'</span>, sans-serif<span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--text-main<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
        <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--bg-color<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

        <span class="token selector"><span class="token class">.demo-container</span><span class="token pseudo-element">::before</span> </span><span class="token punctuation">{</span>
            <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">""</span><span class="token punctuation">;</span>
            <span class="token property">position</span><span class="token punctuation">:</span> fixed<span class="token punctuation">;</span>
            <span class="token property">inset</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--bg-color<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token property">z-index</span><span class="token punctuation">:</span> -<span class="token number">2</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token selector"><span class="token class">.demo-container</span><span class="token pseudo-element">::after</span> </span><span class="token punctuation">{</span>
            <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">""</span><span class="token punctuation">;</span>
            <span class="token property">position</span><span class="token punctuation">:</span> fixed<span class="token punctuation">;</span>
            <span class="token property">inset</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token property">background</span><span class="token punctuation">:</span> transparent<span class="token punctuation">;</span>
            <span class="token property">z-index</span><span class="token punctuation">:</span> -<span class="token number">1</span><span class="token punctuation">;</span>
            <span class="token property">pointer-events</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.demo-header</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span>
        <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">6</span>px<span class="token punctuation">;</span>
        <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">22</span>px<span class="token punctuation">;</span>
        <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

        <span class="token selector"><span class="token class">.demo-header</span> h2 </span><span class="token punctuation">{</span>
            <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">1.9</span>rem<span class="token punctuation">;</span>
            <span class="token property">letter-spacing</span><span class="token punctuation">:</span> <span class="token number">0.02</span>em<span class="token punctuation">;</span>
            <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">650</span><span class="token punctuation">;</span>
            <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--text-main<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.demo-subtitle</span> </span><span class="token punctuation">{</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.95</span>rem<span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--text-muted<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">max-width</span><span class="token punctuation">:</span> <span class="token number">620</span>px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.lists-container</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> grid<span class="token punctuation">;</span>
        <span class="token property">grid-template-columns</span><span class="token punctuation">:</span> <span class="token function">minmax</span><span class="token punctuation">(</span><span class="token number">320</span>px, <span class="token number">360</span>px<span class="token punctuation">)</span> <span class="token function">minmax</span><span class="token punctuation">(</span><span class="token number">0</span>, <span class="token number">1</span>fr<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">18</span>px<span class="token punctuation">;</span>
        <span class="token property">align-items</span><span class="token punctuation">:</span> stretch<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.source-column</span>,
    <span class="token class">.destination-columns</span> </span><span class="token punctuation">{</span>
        <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
        <span class="token property">z-index</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.list-card</span> </span><span class="token punctuation">{</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--radius-lg<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--card-glass<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span>px solid <span class="token function">var</span><span class="token punctuation">(</span>--border-glass<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">box-shadow</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
        <span class="token property">backdrop-filter</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
        <span class="token property">-webkit-backdrop-filter</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
        <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span>
        <span class="token property">transition</span><span class="token punctuation">:</span> border-color <span class="token function">var</span><span class="token punctuation">(</span>--transition-fast<span class="token punctuation">)</span>, background-color <span class="token function">var</span><span class="token punctuation">(</span>--transition-fast<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.list-header</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">10</span>px<span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">12</span>px <span class="token number">16</span>px <span class="token number">10</span>px<span class="token punctuation">;</span>
        <span class="token property">border-bottom</span><span class="token punctuation">:</span> <span class="token number">1</span>px solid <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">148</span>, <span class="token number">163</span>, <span class="token number">184</span>, <span class="token number">0.3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

        <span class="token selector"><span class="token class">.list-header</span> h4 </span><span class="token punctuation">{</span>
            <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token property">flex</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">;</span>
            <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.92</span>rem<span class="token punctuation">;</span>
            <span class="token property">text-transform</span><span class="token punctuation">:</span> uppercase<span class="token punctuation">;</span>
            <span class="token property">letter-spacing</span><span class="token punctuation">:</span> <span class="token number">0.08</span>em<span class="token punctuation">;</span>
            <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#e5e7eb</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.badge</span> </span><span class="token punctuation">{</span>
        <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token hexcode">#333333</span><span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--text-main<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">2</span>px <span class="token number">9</span>px<span class="token punctuation">;</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">999</span>px<span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.74</span>rem<span class="token punctuation">;</span>
        <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">600</span><span class="token punctuation">;</span>
        <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span>px solid <span class="token function">var</span><span class="token punctuation">(</span>--border-glass<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">box-shadow</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.coupon-grid</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> grid<span class="token punctuation">;</span>
        <span class="token property">grid-template-columns</span><span class="token punctuation">:</span> <span class="token function">repeat</span><span class="token punctuation">(</span><span class="token number">2</span>, <span class="token function">minmax</span><span class="token punctuation">(</span><span class="token number">0</span>, <span class="token number">1</span>fr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">14</span>px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.course-item</span> </span><span class="token punctuation">{</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">10</span>px <span class="token number">12</span>px <span class="token number">8</span>px<span class="token punctuation">;</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">4</span>px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.course-info</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">justify-content</span><span class="token punctuation">:</span> space-between<span class="token punctuation">;</span>
        <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">10</span>px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.course-name</span> </span><span class="token punctuation">{</span>
        <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">600</span><span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#2d2d30</span><span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.95</span>rem<span class="token punctuation">;</span>
        <span class="token property">white-space</span><span class="token punctuation">:</span> nowrap<span class="token punctuation">;</span>
        <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span>
        <span class="token property">text-overflow</span><span class="token punctuation">:</span> ellipsis<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.course-price</span> </span><span class="token punctuation">{</span>
        <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">600</span><span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--accent-green<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.86</span>rem<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.course-category</span> </span><span class="token punctuation">{</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.8</span>rem<span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#6e6e6e</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token pseudo-class">:deep(.k-listbox)</span> </span><span class="token punctuation">{</span>
        <span class="token property">border</span><span class="token punctuation">:</span> none <span class="token important">!important</span><span class="token punctuation">;</span>
        <span class="token property">background</span><span class="token punctuation">:</span> transparent<span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--text-main<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token pseudo-class">:deep(.k-listbox .k-list-content)</span> </span><span class="token punctuation">{</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--radius-md<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">8</span>px<span class="token punctuation">;</span>
        <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token hexcode">#1e1e1e</span><span class="token punctuation">;</span>
        <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span>px solid <span class="token function">var</span><span class="token punctuation">(</span>--border-glass<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token pseudo-class">:deep(.k-listbox .k-list-item)</span> </span><span class="token punctuation">{</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">4</span>px<span class="token punctuation">;</span>
        <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">2</span>px <span class="token number">3</span>px<span class="token punctuation">;</span>
        <span class="token property">transition</span><span class="token punctuation">:</span> background-color <span class="token function">var</span><span class="token punctuation">(</span>--transition-fast<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--text-main<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token pseudo-class">:deep(.k-listbox .k-list-item:hover)</span> </span><span class="token punctuation">{</span>
        <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token hexcode">#2d2d30</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token pseudo-class">:deep(.k-listbox .k-list-item.k-selected)</span> </span><span class="token punctuation">{</span>
        <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--accent-blue<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#1e1e1e</span><span class="token punctuation">;</span>
        <span class="token property">box-shadow</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token pseudo-class">:deep(.k-listbox .k-list-item.k-selected .course-name)</span>,
    <span class="token pseudo-class">:deep(.k-listbox .k-list-item.k-selected .course-price)</span>,
    <span class="token pseudo-class">:deep(.k-listbox .k-list-item.k-selected .course-category)</span> </span><span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#1e1e1e</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    @<span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 1200px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
        <span class="token selector"><span class="token class">.lists-container</span> </span><span class="token punctuation">{</span>
            <span class="token property">grid-template-columns</span><span class="token punctuation">:</span> <span class="token function">minmax</span><span class="token punctuation">(</span><span class="token number">0</span>, <span class="token number">1</span>fr<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token selector"><span class="token class">.coupon-grid</span> </span><span class="token punctuation">{</span>
            <span class="token property">grid-template-columns</span><span class="token punctuation">:</span> <span class="token function">repeat</span><span class="token punctuation">(</span><span class="token number">2</span>, <span class="token function">minmax</span><span class="token punctuation">(</span><span class="token number">0</span>, <span class="token number">1</span>fr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    @<span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 768px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
        <span class="token selector"><span class="token class">.demo-container</span> </span><span class="token punctuation">{</span>
            <span class="token property">padding-inline</span><span class="token punctuation">:</span> <span class="token number">14</span>px<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token selector"><span class="token class">.lists-container</span> </span><span class="token punctuation">{</span>
            <span class="token property">grid-template-columns</span><span class="token punctuation">:</span> <span class="token function">minmax</span><span class="token punctuation">(</span><span class="token number">0</span>, <span class="token number">1</span>fr<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">14</span>px<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token selector"><span class="token class">.coupon-grid</span> </span><span class="token punctuation">{</span>
            <span class="token property">grid-template-columns</span><span class="token punctuation">:</span> <span class="token function">minmax</span><span class="token punctuation">(</span><span class="token number">0</span>, <span class="token number">1</span>fr<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>

@code {
    public class Course
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public string Category { get; set; } = string.Empty;
        public decimal Price { get; set; }
        public string Currency { get; set; } = "USD";
    }

    private List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> AvailableCourses { get; set; } = new();
    private List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> BestPriceCourses { get; set; } = new();
    private List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> CustomPriceCourses { get; set; } = new();
    private List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> FreeOpenCourses { get; set; } = new();
    private List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> FreeTargetedCourses { get; set; } = new();

    protected override void OnInitialized()
    {
        LoadSampleData();
    }

    private void LoadSampleData()
    {
        AvailableCourses = new List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span>
        {
            new() { Id = 1, Name = "Blazor Fundamentals", Category = "Web Development", Price = 19.99m, Currency = "USD" },
            new() { Id = 2, Name = "C# Advanced Patterns", Category = "Programming", Price = 24.99m, Currency = "USD" },
            new() { Id = 3, Name = "ASP.NET Core API", Category = "Backend", Price = 29.99m, Currency = "USD" },
            new() { Id = 4, Name = "Entity Framework Core", Category = "Database", Price = 14.99m, Currency = "USD" },
            new() { Id = 5, Name = "Azure DevOps Pipeline", Category = "DevOps", Price = 34.99m, Currency = "USD" },
            new() { Id = 6, Name = "Docker &amp; Kubernetes", Category = "Infrastructure", Price = 39.99m, Currency = "USD" },
            new() { Id = 7, Name = "React with TypeScript", Category = "Frontend", Price = 22.99m, Currency = "USD" },
            new() { Id = 8, Name = "SQL Server Mastery", Category = "Database", Price = 27.99m, Currency = "USD" },
            new() { Id = 9, Name = "Git &amp; GitHub Pro", Category = "Tools", Price = 12.99m, Currency = "USD" },
            new() { Id = 10, Name = "Machine Learning Basics", Category = "AI/ML", Price = 44.99m, Currency = "USD" }
        };
        BestPriceCourses = new();
        CustomPriceCourses = new();
        FreeOpenCourses = new();
        FreeTargetedCourses = new();
    }
}
</code></pre><p>In the code above, you can see that we used several <code>TelerikListBox</code> tags to render the ListBox components, as well as the use of <code>ItemTemplate</code> to apply styles to each item within the ListBox.</p><p>Similarly, I have created a class <code>Course</code> that represents a course, which is useful for filling and binding the lists to each ListBox through the <code>Data</code> parameter of the component to display the information, as shown below:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-02/page-displaying-listboxes-for-blazor-that-will-be-used-to-transfer-items-between-them.png?sfvrsn=969c108b_2" alt="Page displaying ListBoxes for Blazor that will be used to transfer items between them" /></p><p>The result is fascinating and undoubtedly demonstrates the potential of the component.</p><h2 id="enabling-drag--drop-functionality">Enabling Drag &amp; Drop Functionality</h2><p>The <code>TelerikListBox</code> component has several parameters that we need to configure so that we can drag and drop items between ListBoxes, following these steps. It is worth mentioning that I will show you the configuration for just one, although the implementation for the others is similar.</p><ol><li>Each of the ListBoxes that will be used to transfer items must have an id of type <code>string</code>, which should be set in the <code>Id</code> parameter. This is essential for knowing from which component the item is coming and where it is going. An example of this configuration is shown below:</li></ol><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikListBox</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@AvailableCourses<span class="token punctuation">"</span></span>
                <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ListBoxIdAvailable<span class="token punctuation">"</span></span>
                <span class="token attr-name">...</span><span class="token punctuation">&gt;</span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikListBox</span><span class="token punctuation">&gt;</span></span>
@code {
    ...
    private const string ListBoxIdAvailable = "availableCourses";
    ...
}
</code></pre><ol start="2"><li>The second step is to create <code>@ref</code> references, which allows invoking the <code>Rebind</code> method to carry out a data update every time we move items between the lists:</li></ol><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikListBox</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@AvailableCourses<span class="token punctuation">"</span></span>
                <span class="token attr-name">@ref</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ListBoxRefAvailable<span class="token punctuation">"</span></span>
                <span class="token attr-name">...</span><span class="token punctuation">&gt;</span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikListBox</span><span class="token punctuation">&gt;</span></span>
@code {
    ...
    private TelerikListBox<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> ListBoxRefAvailable { get; set; } = null!;
    ...
}
</code></pre><ol start="3"><li>You must be able to obtain the selected elements from each ListBox, which is possible by creating a list for each ListBox and binding them through the <code>SelectedItems</code> property. Also, make sure to specify the appropriate <code>SelectionMode</code> type, as well as assign the <code>SelectedItemsChanged</code> parameter to update these lists:</li></ol><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikListBox</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@AvailableCourses<span class="token punctuation">"</span></span>
                <span class="token attr-name">SelectionMode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ListBoxSelectionMode.Multiple<span class="token punctuation">"</span></span>
                <span class="token attr-name">SelectedItems</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SelectedItemsAvailable<span class="token punctuation">"</span></span>
                <span class="token attr-name">SelectedItemsChanged</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@((IEnumerable&lt;Course&gt; items) =&gt; OnSelectedItemsChanged(items, ListBoxIdAvailable))<span class="token punctuation">"</span></span>
                <span class="token attr-name">...</span><span class="token punctuation">&gt;</span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikListBox</span><span class="token punctuation">&gt;</span></span>
@code {
    ...
    private IEnumerable<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> SelectedItemsAvailable { get; set; } = new List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span>();
    private IEnumerable<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> SelectedItems1 { get; set; } = new List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span>();
    private IEnumerable<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> SelectedItems2 { get; set; } = new List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span>();
    private IEnumerable<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> SelectedItems3 { get; set; } = new List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span>();
    private IEnumerable<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> SelectedItems4 { get; set; } = new List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span>();
    ...
    private void OnSelectedItemsChanged(IEnumerable<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Course</span><span class="token punctuation">&gt;</span></span> items, string listBoxId)
    {
        switch (listBoxId)
        {
            case ListBoxIdAvailable:
                SelectedItemsAvailable = items;
                break;
            case ListBoxId1:
                SelectedItems1 = items;
                break;
            case ListBoxId2:
                SelectedItems2 = items;
                break;
            case ListBoxId3:
                SelectedItems3 = items;
                break;
            case ListBoxId4:
                SelectedItems4 = items;
                break;
        }
    }        
    ...
}
</code></pre><ol start="4"><li>You must assign a <code>true</code> value to the <code>Draggable</code> parameter, indicating that the ListBoxes will be able to send and receive items between them.</li></ol><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikListBox</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@AvailableCourses<span class="token punctuation">"</span></span>
                <span class="token attr-name">Draggable</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span>
                <span class="token attr-name">...</span><span class="token punctuation">&gt;</span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikListBox</span><span class="token punctuation">&gt;</span></span>
</code></pre><ol start="5"><li>Enable the <code>DropSources</code> parameter, which is a list of Ids of the ListBoxes.</li></ol><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikListBox</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@AvailableCourses<span class="token punctuation">"</span></span>
                <span class="token attr-name">DropSources</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ListBoxDropSources<span class="token punctuation">"</span></span>
                <span class="token attr-name">...</span><span class="token punctuation">&gt;</span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikListBox</span><span class="token punctuation">&gt;</span></span>
@code {
    ...
    private List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>string</span><span class="token punctuation">&gt;</span></span> ListBoxDropSources =&gt; new()
    {
        ListBoxIdAvailable,
        ListBoxId1,
        ListBoxId2,
        ListBoxId3,
        ListBoxId4
    };
    ...
}
</code></pre><ol start="6"><li>Specify the <code>OnDrop</code> parameter, which is an <code>EventCallback</code> that is triggered when a drag-and-drop interaction occurs, expecting a delegate that receives an argument <code>ListBoxDropEventArgs&lt;T&gt;</code>. This argument contains a property <code>Items</code> with the elements being moved between ListBoxes, a <code>DestinationIndex</code> that represents the index within the destination ListBox where the item was dropped, and finally <code>DestinationListBoxId</code>, which allows knowing in which ListBox we dropped the items. Additionally, we can add information like the <code>Id</code> of the ListBox from which the operation is being performed:</li></ol><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikListBox</span> <span class="token attr-name">Data</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@AvailableCourses<span class="token punctuation">"</span></span>
                <span class="token attr-name">OnDrop</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@((ListBoxDropEventArgs&lt;Course&gt; args) =&gt; OnDropHandler(args, ListBoxIdAvailable))<span class="token punctuation">"</span></span>
                <span class="token attr-name">...</span><span class="token punctuation">&gt;</span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikListBox</span><span class="token punctuation">&gt;</span></span>
</code></pre><ol start="7"><li>Create the event handler where the processing takes place when the items are dropped. This method is the most complex, but I will explain the main parts:</li></ol><pre class=" language-csharp"><code class="prism  language-csharp">@code <span class="token punctuation">{</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">OnDropHandler</span><span class="token punctuation">(</span>ListBoxDropEventArgs<span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span> args<span class="token punctuation">,</span> <span class="token keyword">string</span> sourceListBoxId<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token comment">// A. </span>
        <span class="token keyword">var</span> draggedItem <span class="token operator">=</span> args<span class="token punctuation">.</span>Items<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">FirstOrDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>draggedItem <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span>                    
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>sourceListBoxId<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span>
        <span class="token keyword">var</span> destinationId <span class="token operator">=</span> args<span class="token punctuation">.</span>DestinationListBoxId<span class="token punctuation">;</span>
        <span class="token keyword">var</span> destinationIndex <span class="token operator">=</span> args<span class="token punctuation">.</span>DestinationIndex <span class="token operator">?</span><span class="token operator">?</span> <span class="token number">0</span><span class="token punctuation">;</span>        
        <span class="token keyword">var</span> sourceList <span class="token operator">=</span> <span class="token function">GetListById</span><span class="token punctuation">(</span>sourceListBoxId<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">var</span> destinationList <span class="token operator">=</span> <span class="token function">GetListById</span><span class="token punctuation">(</span>destinationId<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>sourceList <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">||</span> destinationList <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span>        
        <span class="token keyword">var</span> selectedItems <span class="token operator">=</span> <span class="token function">GetSelectedItemsFromListBox</span><span class="token punctuation">(</span>sourceListBoxId<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">// B.</span>
        List<span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span> itemsToMove<span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>selectedItems<span class="token punctuation">.</span><span class="token function">Any</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> selectedItems<span class="token punctuation">.</span><span class="token function">Any</span><span class="token punctuation">(</span>item <span class="token operator">=</span><span class="token operator">&gt;</span> item<span class="token punctuation">.</span>Id <span class="token operator">==</span> draggedItem<span class="token punctuation">.</span>Id<span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            itemsToMove <span class="token operator">=</span> selectedItems<span class="token punctuation">.</span><span class="token function">ToList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">else</span>
        <span class="token punctuation">{</span>
            itemsToMove <span class="token operator">=</span> args<span class="token punctuation">.</span>Items<span class="token punctuation">.</span><span class="token function">ToList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token comment">// C. </span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>destinationId <span class="token operator">==</span> sourceListBoxId<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>            
            <span class="token function">ReorderItems</span><span class="token punctuation">(</span>itemsToMove<span class="token punctuation">,</span> sourceList<span class="token punctuation">,</span> destinationIndex<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">else</span>
        <span class="token punctuation">{</span>            
            <span class="token function">MoveItems</span><span class="token punctuation">(</span>itemsToMove<span class="token punctuation">,</span> sourceList<span class="token punctuation">,</span> destinationList<span class="token punctuation">,</span> destinationIndex<span class="token punctuation">)</span><span class="token punctuation">;</span>            
            <span class="token function">ClearSelectedItems</span><span class="token punctuation">(</span>sourceListBoxId<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        
        <span class="token function">RebindAllListBoxes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token punctuation">}</span>
</code></pre><p>A. The variables <code>draggedItem</code>, <code>destinationId</code>, <code>destinationIndex</code>, <code>sourceList</code>, <code>destinationList</code> and <code>selectedItems</code> are created, which will serve to perform different operations such as validations, reordering, etc.</p><p>B. The variable <code>itemsToMove</code> is created, which will establish which items will be moved. The check allows specifying which items will be moved, whether the selected ones or some different ones. For example, suppose you select the first two items, and for some reason, you prefer not to move them, but instead, you prefer to move Item 3. In this case, only Item 3 will be moved and not the selected ones.</p><p>C. The <code>if</code> allows knowing if the movement of items has been made within the same list or if an attempt is being made to move between different lists. If it is within the same list, reordering is done according to the <code>destinationIndex</code>. If the transfer is made between lists, the items are moved between the lists and deselected. Finally, a <code>Rebind</code> is carried out to update any pending interface changes.</p><p>Lastly, I show you the helper methods used:</p><pre class=" language-csharp"><code class="prism  language-csharp">@code <span class="token punctuation">{</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    
    <span class="token keyword">private</span> List<span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token operator">?</span> <span class="token function">GetListById</span><span class="token punctuation">(</span><span class="token keyword">string</span> listBoxId<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">return</span> listBoxId <span class="token keyword">switch</span>
        <span class="token punctuation">{</span>
            ListBoxIdAvailable <span class="token operator">=</span><span class="token operator">&gt;</span> AvailableCourses<span class="token punctuation">,</span>
            ListBoxId1 <span class="token operator">=</span><span class="token operator">&gt;</span> BestPriceCourses<span class="token punctuation">,</span>
            ListBoxId2 <span class="token operator">=</span><span class="token operator">&gt;</span> CustomPriceCourses<span class="token punctuation">,</span>
            ListBoxId3 <span class="token operator">=</span><span class="token operator">&gt;</span> FreeOpenCourses<span class="token punctuation">,</span>
            ListBoxId4 <span class="token operator">=</span><span class="token operator">&gt;</span> FreeTargetedCourses<span class="token punctuation">,</span>
            _ <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token keyword">null</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> IEnumerable<span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span> <span class="token function">GetSelectedItemsFromListBox</span><span class="token punctuation">(</span><span class="token keyword">string</span> listBoxId<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">return</span> listBoxId <span class="token keyword">switch</span>
        <span class="token punctuation">{</span>
            ListBoxIdAvailable <span class="token operator">=</span><span class="token operator">&gt;</span> SelectedItemsAvailable <span class="token operator">?</span><span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            ListBoxId1 <span class="token operator">=</span><span class="token operator">&gt;</span> SelectedItems1 <span class="token operator">?</span><span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            ListBoxId2 <span class="token operator">=</span><span class="token operator">&gt;</span> SelectedItems2 <span class="token operator">?</span><span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            ListBoxId3 <span class="token operator">=</span><span class="token operator">&gt;</span> SelectedItems3 <span class="token operator">?</span><span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            ListBoxId4 <span class="token operator">=</span><span class="token operator">&gt;</span> SelectedItems4 <span class="token operator">?</span><span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            _ <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">ReorderItems</span><span class="token punctuation">(</span>List<span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span> items<span class="token punctuation">,</span> List<span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span> collection<span class="token punctuation">,</span> <span class="token keyword">int</span> destinationIndex<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>        
        <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token keyword">var</span> item <span class="token keyword">in</span> items<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            collection<span class="token punctuation">.</span><span class="token function">RemoveAll</span><span class="token punctuation">(</span>x <span class="token operator">=</span><span class="token operator">&gt;</span> x<span class="token punctuation">.</span>Id <span class="token operator">==</span> item<span class="token punctuation">.</span>Id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        
        <span class="token keyword">if</span> <span class="token punctuation">(</span>destinationIndex <span class="token operator">&gt;=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> destinationIndex <span class="token operator">&lt;=</span> collection<span class="token punctuation">.</span>Count<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token keyword">var</span> index <span class="token operator">=</span> destinationIndex<span class="token punctuation">;</span>
            <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token keyword">var</span> item <span class="token keyword">in</span> items<span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                collection<span class="token punctuation">.</span><span class="token function">Insert</span><span class="token punctuation">(</span>index<span class="token punctuation">,</span> item<span class="token punctuation">)</span><span class="token punctuation">;</span>
                index<span class="token operator">++</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">else</span>
        <span class="token punctuation">{</span>
            collection<span class="token punctuation">.</span><span class="token function">AddRange</span><span class="token punctuation">(</span>items<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>    

    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">MoveItems</span><span class="token punctuation">(</span>List<span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span> items<span class="token punctuation">,</span> List<span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span> sourceList<span class="token punctuation">,</span> List<span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span> destinationList<span class="token punctuation">,</span> <span class="token keyword">int</span> destinationIndex<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>        
        <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token keyword">var</span> item <span class="token keyword">in</span> items<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            sourceList<span class="token punctuation">.</span><span class="token function">RemoveAll</span><span class="token punctuation">(</span>x <span class="token operator">=</span><span class="token operator">&gt;</span> x<span class="token punctuation">.</span>Id <span class="token operator">==</span> item<span class="token punctuation">.</span>Id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        
        <span class="token keyword">var</span> insertIndex <span class="token operator">=</span> destinationIndex <span class="token operator">&gt;=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> destinationIndex <span class="token operator">&lt;=</span> destinationList<span class="token punctuation">.</span>Count
            <span class="token operator">?</span> destinationIndex
            <span class="token punctuation">:</span> destinationList<span class="token punctuation">.</span>Count<span class="token punctuation">;</span>

        <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token keyword">var</span> item <span class="token keyword">in</span> items<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            destinationList<span class="token punctuation">.</span><span class="token function">Insert</span><span class="token punctuation">(</span>insertIndex<span class="token punctuation">,</span> item<span class="token punctuation">)</span><span class="token punctuation">;</span>
            insertIndex<span class="token operator">++</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">ClearSelectedItems</span><span class="token punctuation">(</span><span class="token keyword">string</span> listBoxId<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">switch</span> <span class="token punctuation">(</span>listBoxId<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token keyword">case</span> ListBoxIdAvailable<span class="token punctuation">:</span>
                SelectedItemsAvailable <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">break</span><span class="token punctuation">;</span>
            <span class="token keyword">case</span> ListBoxId1<span class="token punctuation">:</span>
                SelectedItems1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">break</span><span class="token punctuation">;</span>
            <span class="token keyword">case</span> ListBoxId2<span class="token punctuation">:</span>
                SelectedItems2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">break</span><span class="token punctuation">;</span>
            <span class="token keyword">case</span> ListBoxId3<span class="token punctuation">:</span>
                SelectedItems3 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">break</span><span class="token punctuation">;</span>
            <span class="token keyword">case</span> ListBoxId4<span class="token punctuation">:</span>
                SelectedItems4 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>Course<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>    

    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">RebindAllListBoxes</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        ListBoxRefAvailable<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">Rebind</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        ListBoxRef1<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">Rebind</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        ListBoxRef2<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">Rebind</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        ListBoxRef3<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">Rebind</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        ListBoxRef4<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">Rebind</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>With the above code implemented, we now have drag and drop on the page, working with both individual elements and multiple elements as shown below:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-02/demonstration-of-drag-and-drop-functionality-across-multiple-listboxes-in-blazor.gif?sfvrsn=6ca54571_2" alt="Demonstration of drag-and-drop functionality across multiple ListBoxes in Blazor" /></p><p>With this, we have finished implementing the drag-and-drop functionality. Finally, we could obtain the list of courses in each of the bound lists in the ListBoxes to get their classification, thus generating a final CSV file to create coupons in bulk easily, which greatly simplifies coupon generation.</p><h2 id="conclusion">Conclusion</h2><p>The creation of applications should always be oriented toward enabling users to solve their problems without worrying about performing complex steps.</p><p>In this article, we have seen how to solve a real-world problem through the implementation of drag and drop using the <code>TelerikListBox</code> component. You have learned the steps involved in enabling it and some methods that can help you carry out this implementation more easily. I hope this is very helpful to you and that at some point you can implement it to assist your users.</p><p>Ready to try out this component and 120 others in the Telerik UI for Blazor library? The trial is free for 30 days!</p><p><a href="https://www.telerik.com/try/ui-for-blazor" target="_blank" class="Btn">Try Now</a></p><img src="https://feeds.telerik.com/link/23050/17277349.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:e37aebd6-64f1-4cc0-910c-d54c50275d54</id>
    <title type="text">Customizing Validation Messages in Blazor Forms</title>
    <summary type="text">These Blazor components can help you create custom form experiences, so users feel right at home inside your app.</summary>
    <published>2026-02-10T14:59:23Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Héctor Pérez </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17273669/customizing-validation-messages-blazor-forms"/>
    <content type="text"><![CDATA[<p><span class="featured">These Blazor components can help you create custom form experiences, so users feel right at home inside your app.</span></p><p>Having forms in web applications is something that is essential in any application. Whether to enable a way to contact or to edit information, the correct display of errors will define a good or bad user experience.</p><p>That is why today I will talk to you about how to customize validation messages in forms within your Blazor applications, thanks to the <a target="_blank" href="https://www.telerik.com/blazor-ui/validation-message">Validation Tools</a> available in the Progress Telerik UI for Blazor library.</p><h2 id="implementing-validation-in-a-blazor-application">Implementing Validation in a Blazor Application</h2><p>In case you are not yet experienced in Blazor form validation, you should know that as part of the framework there are ways to validate forms natively. To do this, you need the following parts:</p><ol><li>A model with <strong>Data Annotations</strong> that specify the validation rules for each property of the model, like the following:</li></ol><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token punctuation">[</span><span class="token function">Required</span><span class="token punctuation">(</span>ErrorMessage <span class="token operator">=</span> <span class="token string">"First name is required"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
<span class="token punctuation">[</span><span class="token function">StringLength</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">,</span> MinimumLength <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span> ErrorMessage <span class="token operator">=</span> <span class="token string">"First name must be between 2 and 50 characters"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
<span class="token keyword">public</span> <span class="token keyword">string</span> FirstName <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>
</code></pre><ol start="2"><li>An <code>EditForm</code> with the <code>Model</code> parameter bound to an instance of the model, as follows:</li></ol><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>EditForm</span> <span class="token attr-name">Model</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@userModel<span class="token punctuation">"</span></span> <span class="token attr-name">OnValidSubmit</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@HandleValidSubmit<span class="token punctuation">"</span></span> <span class="token attr-name">FormName</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>userRegistrationForm<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
</code></pre><ol start="3"><li>A set of form components, such as an <code>InputText</code>, <code>InputNumber</code>, <code>InputCheckBox</code>, etc., as in the following code:</li></ol><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>InputText</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>firstName<span class="token punctuation">"</span></span> <span class="token attr-name">@bind-Value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>userModel.FirstName<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-control<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre><p>With the above structure ready, the next step is to use the pre-built components for validation. First, the <code>DataAnnotationsValidator</code> component allows you to activate validation through <strong>DataAnnotations</strong> in the form, so it is essential to add it to perform validations.</p><p>Next, we can use the component called <code>ValidationSummary</code>, which shows a summary of all validation errors in the form of a list.</p><p>The other component you can use is <code>ValidationMessage</code>, which allows you to be more specific and display an error message for each validated data, according to the Data Annotations of the model property, as in the following example:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>firstName<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-label<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>First Name:<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>InputText</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>firstName<span class="token punctuation">"</span></span> <span class="token attr-name">@bind-Value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>userModel.FirstName<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-control<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ValidationMessage</span> <span class="token attr-name">For</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@(() =&gt; userModel.FirstName)<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>The form validation looks as follows:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/demo-of-form-validation-using-pre-built-components-in-blazor.png?sfvrsn=c379cb39_2" alt="Demo of form validation using pre-built components in Blazor" /></p><p>The complete initial code would look like this:</p><pre class=" language-csharp"><code class="prism  language-csharp">@page <span class="token string">"/form-example"</span>
@<span class="token keyword">using</span> System<span class="token punctuation">.</span>ComponentModel<span class="token punctuation">.</span>DataAnnotations

<span class="token operator">&lt;</span>PageTitle<span class="token operator">&gt;</span>Form Example<span class="token operator">&lt;</span><span class="token operator">/</span>PageTitle<span class="token operator">&gt;</span>

<span class="token operator">&lt;</span>h1<span class="token operator">&gt;</span>User Registration Form<span class="token operator">&lt;</span><span class="token operator">/</span>h1<span class="token operator">&gt;</span>

<span class="token operator">&lt;</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"row"</span><span class="token operator">&gt;</span>
    <span class="token operator">&lt;</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"col-md-6"</span><span class="token operator">&gt;</span>
        <span class="token operator">&lt;</span>EditForm Model<span class="token operator">=</span><span class="token string">"@userModel"</span> OnValidSubmit<span class="token operator">=</span><span class="token string">"@HandleValidSubmit"</span> FormName<span class="token operator">=</span><span class="token string">"userRegistrationForm"</span><span class="token operator">&gt;</span>
            <span class="token operator">&lt;</span>DataAnnotationsValidator <span class="token operator">/</span><span class="token operator">&gt;</span>
            <span class="token operator">&lt;</span>ValidationSummary <span class="token operator">/</span><span class="token operator">&gt;</span>

            <span class="token operator">&lt;</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"mb-3"</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>label <span class="token keyword">for</span><span class="token operator">=</span><span class="token string">"firstName"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-label"</span><span class="token operator">&gt;</span>First Name<span class="token punctuation">:</span><span class="token operator">&lt;</span><span class="token operator">/</span>label<span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>InputText id<span class="token operator">=</span><span class="token string">"firstName"</span> @bind<span class="token operator">-</span>Value<span class="token operator">=</span><span class="token string">"userModel.FirstName"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-control"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>ValidationMessage For<span class="token operator">=</span><span class="token string">"@(() =&gt; userModel.FirstName)"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
            <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>

            <span class="token operator">&lt;</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"mb-3"</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>label <span class="token keyword">for</span><span class="token operator">=</span><span class="token string">"lastName"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-label"</span><span class="token operator">&gt;</span>Last Name<span class="token punctuation">:</span><span class="token operator">&lt;</span><span class="token operator">/</span>label<span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>InputText id<span class="token operator">=</span><span class="token string">"lastName"</span> @bind<span class="token operator">-</span>Value<span class="token operator">=</span><span class="token string">"userModel.LastName"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-control"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>ValidationMessage For<span class="token operator">=</span><span class="token string">"@(() =&gt; userModel.LastName)"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
            <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>

            <span class="token operator">&lt;</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"mb-3"</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>label <span class="token keyword">for</span><span class="token operator">=</span><span class="token string">"email"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-label"</span><span class="token operator">&gt;</span>Email<span class="token punctuation">:</span><span class="token operator">&lt;</span><span class="token operator">/</span>label<span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>InputText id<span class="token operator">=</span><span class="token string">"email"</span> type<span class="token operator">=</span><span class="token string">"email"</span> @bind<span class="token operator">-</span>Value<span class="token operator">=</span><span class="token string">"userModel.Email"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-control"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>ValidationMessage For<span class="token operator">=</span><span class="token string">"@(() =&gt; userModel.Email)"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
            <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>

            <span class="token operator">&lt;</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"mb-3"</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>label <span class="token keyword">for</span><span class="token operator">=</span><span class="token string">"age"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-label"</span><span class="token operator">&gt;</span>Age<span class="token punctuation">:</span><span class="token operator">&lt;</span><span class="token operator">/</span>label<span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>InputNumber id<span class="token operator">=</span><span class="token string">"age"</span> @bind<span class="token operator">-</span>Value<span class="token operator">=</span><span class="token string">"userModel.Age"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-control"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>ValidationMessage For<span class="token operator">=</span><span class="token string">"@(() =&gt; userModel.Age)"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
            <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>

            <span class="token operator">&lt;</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"mb-3"</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>label <span class="token keyword">for</span><span class="token operator">=</span><span class="token string">"phone"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-label"</span><span class="token operator">&gt;</span>Phone<span class="token punctuation">:</span><span class="token operator">&lt;</span><span class="token operator">/</span>label<span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>InputText id<span class="token operator">=</span><span class="token string">"phone"</span> @bind<span class="token operator">-</span>Value<span class="token operator">=</span><span class="token string">"userModel.PhoneNumber"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-control"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>ValidationMessage For<span class="token operator">=</span><span class="token string">"@(() =&gt; userModel.PhoneNumber)"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
            <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>

            <span class="token operator">&lt;</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"mb-3 form-check"</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>InputCheckbox id<span class="token operator">=</span><span class="token string">"terms"</span> @bind<span class="token operator">-</span>Value<span class="token operator">=</span><span class="token string">"userModel.AcceptTerms"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-check-input"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>label <span class="token keyword">for</span><span class="token operator">=</span><span class="token string">"terms"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"form-check-label"</span><span class="token operator">&gt;</span>I accept the terms and conditions<span class="token operator">&lt;</span><span class="token operator">/</span>label<span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>ValidationMessage For<span class="token operator">=</span><span class="token string">"@(() =&gt; userModel.AcceptTerms)"</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
            <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>

            <span class="token operator">&lt;</span>button type<span class="token operator">=</span><span class="token string">"submit"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"btn btn-primary"</span><span class="token operator">&gt;</span>Submit<span class="token operator">&lt;</span><span class="token operator">/</span>button<span class="token operator">&gt;</span>
            <span class="token operator">&lt;</span>button type<span class="token operator">=</span><span class="token string">"button"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"btn btn-secondary ms-2"</span> @onclick<span class="token operator">=</span><span class="token string">"ResetForm"</span><span class="token operator">&gt;</span>Reset<span class="token operator">&lt;</span><span class="token operator">/</span>button<span class="token operator">&gt;</span>
        <span class="token operator">&lt;</span><span class="token operator">/</span>EditForm<span class="token operator">&gt;</span>

        @<span class="token keyword">if</span> <span class="token punctuation">(</span>submitted<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token operator">&lt;</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"alert alert-success mt-3"</span> role<span class="token operator">=</span><span class="token string">"alert"</span><span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>h4 <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"alert-heading"</span><span class="token operator">&gt;</span>Form submitted successfully<span class="token operator">!</span><span class="token operator">&lt;</span><span class="token operator">/</span>h4<span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>p<span class="token operator">&gt;</span><span class="token operator">&lt;</span>strong<span class="token operator">&gt;</span>Name<span class="token punctuation">:</span><span class="token operator">&lt;</span><span class="token operator">/</span>strong<span class="token operator">&gt;</span> @userModel<span class="token punctuation">.</span>FirstName @userModel<span class="token punctuation">.</span>LastName<span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>p<span class="token operator">&gt;</span><span class="token operator">&lt;</span>strong<span class="token operator">&gt;</span>Email<span class="token punctuation">:</span><span class="token operator">&lt;</span><span class="token operator">/</span>strong<span class="token operator">&gt;</span> @userModel<span class="token punctuation">.</span>Email<span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>p<span class="token operator">&gt;</span><span class="token operator">&lt;</span>strong<span class="token operator">&gt;</span>Age<span class="token punctuation">:</span><span class="token operator">&lt;</span><span class="token operator">/</span>strong<span class="token operator">&gt;</span> @userModel<span class="token punctuation">.</span>Age<span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">&gt;</span>
                <span class="token operator">&lt;</span>p<span class="token operator">&gt;</span><span class="token operator">&lt;</span>strong<span class="token operator">&gt;</span>Phone<span class="token punctuation">:</span><span class="token operator">&lt;</span><span class="token operator">/</span>strong<span class="token operator">&gt;</span> @userModel<span class="token punctuation">.</span>PhoneNumber<span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">&gt;</span>
            <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
        <span class="token punctuation">}</span>
    <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>

@code <span class="token punctuation">{</span>
    <span class="token punctuation">[</span>SupplyParameterFromForm<span class="token punctuation">]</span>
    <span class="token keyword">private</span> UserModel userModel <span class="token operator">=</span> <span class="token keyword">new</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">bool</span> submitted <span class="token operator">=</span> <span class="token keyword">false</span><span class="token punctuation">;</span>

    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">HandleValidSubmit</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        submitted <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">ResetForm</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        userModel <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UserModel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        submitted <span class="token operator">=</span> <span class="token keyword">false</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserModel</span>
    <span class="token punctuation">{</span>
        <span class="token punctuation">[</span><span class="token function">Required</span><span class="token punctuation">(</span>ErrorMessage <span class="token operator">=</span> <span class="token string">"First name is required"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
        <span class="token punctuation">[</span><span class="token function">StringLength</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">,</span> MinimumLength <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span> ErrorMessage <span class="token operator">=</span> <span class="token string">"First name must be between 2 and 50 characters"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> FirstName <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>

        <span class="token punctuation">[</span><span class="token function">Required</span><span class="token punctuation">(</span>ErrorMessage <span class="token operator">=</span> <span class="token string">"Last name is required"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
        <span class="token punctuation">[</span><span class="token function">StringLength</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">,</span> MinimumLength <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span> ErrorMessage <span class="token operator">=</span> <span class="token string">"Last name must be between 2 and 50 characters"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> LastName <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>

        <span class="token punctuation">[</span><span class="token function">Required</span><span class="token punctuation">(</span>ErrorMessage <span class="token operator">=</span> <span class="token string">"Email is required"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
        <span class="token punctuation">[</span><span class="token function">EmailAddress</span><span class="token punctuation">(</span>ErrorMessage <span class="token operator">=</span> <span class="token string">"Invalid email address"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> Email <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>

        <span class="token punctuation">[</span><span class="token function">Required</span><span class="token punctuation">(</span>ErrorMessage <span class="token operator">=</span> <span class="token string">"Age is required"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
        <span class="token punctuation">[</span><span class="token function">Range</span><span class="token punctuation">(</span><span class="token number">18</span><span class="token punctuation">,</span> <span class="token number">120</span><span class="token punctuation">,</span> ErrorMessage <span class="token operator">=</span> <span class="token string">"Age must be between 18 and 120"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
        <span class="token keyword">public</span> <span class="token keyword">int</span> Age <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>

        <span class="token punctuation">[</span><span class="token function">Required</span><span class="token punctuation">(</span>ErrorMessage <span class="token operator">=</span> <span class="token string">"Phone number is required"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
        <span class="token punctuation">[</span><span class="token function">Phone</span><span class="token punctuation">(</span>ErrorMessage <span class="token operator">=</span> <span class="token string">"Invalid phone number"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> PhoneNumber <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>

        <span class="token punctuation">[</span><span class="token function">Range</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token keyword">bool</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"true"</span><span class="token punctuation">,</span> <span class="token string">"true"</span><span class="token punctuation">,</span> ErrorMessage <span class="token operator">=</span> <span class="token string">"You must accept the terms and conditions"</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
        <span class="token keyword">public</span> <span class="token keyword">bool</span> AcceptTerms <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>Now let&rsquo;s see how to customize each of these error messages.</p><h2 id="customizing-validation-messages-in-blazor">Customizing Validation Messages in Blazor</h2><p>The native Blazor validation components are fine for small, quick applications that do not require customization. However, they lack parameters that can be modified for customization.</p><p>Although there are ways to achieve some customization, these can increase the complexity of the project and limit us when trying to adapt the style to our own, so it is better to look for alternatives.</p><p>One of the best options can be found in the Telerik validation components for Blazor, which allow for customization in various ways, which we will explore below.</p><h2 id="the-telerik-validation-summary-component-for-blazor">The Telerik Validation Summary Component for Blazor</h2><p>Let&rsquo;s start by analyzing the enhanced component for displaying the error summary, which we must use via the <code>TelerikValidationSummary</code> tag either along with a <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/validation/summary#using-with-telerikform">TelerikForm</a> or with a standard <code>EditForm</code> from Blazor. To utilize this component in our example, I will simply replace the <code>ValidationSummary</code> tag with <code>TelerikValidationSummary</code> as follows:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>EditForm</span> <span class="token attr-name">Model</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@userModel<span class="token punctuation">"</span></span> <span class="token attr-name">OnValidSubmit</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@HandleValidSubmit<span class="token punctuation">"</span></span> <span class="token attr-name">FormName</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>userRegistrationForm<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DataAnnotationsValidator</span> <span class="token punctuation">/&gt;</span></span>      
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikValidationSummary</span> <span class="token punctuation">/&gt;</span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>EditForm</span><span class="token punctuation">&gt;</span></span>    
</code></pre><p>Since we made the change, we can notice a more elaborate visual change:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/the-telerikvalidationsummary-component-displaying-an-attractive-professional-design.png?sfvrsn=34604de8_2" alt="The TelerikValidationSummary component displaying an attractive, professional design" /></p><p>Apart from the default professional design, we can also further customize its appearance through the <code>Template</code> parameter, within which we can add HTML code to customize the error messages.</p><p>This is possible thanks to the <code>Context</code> property, which is a collection of the type <code>IEnumerable&lt;string&gt;</code> containing all the messages from the validated model.</p><p>This means you could make the message section as complex as you want, creating your own design from scratch and personalized as shown below:</p><pre class=" language-xml"><code class="prism  language-xml">...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">&gt;</span></span><span class="token style language-css">
    <span class="token selector"><span class="token class">.validation-alert-modern</span> </span><span class="token punctuation">{</span>
        <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span><span class="token number">135</span>deg, <span class="token hexcode">#fff5f5</span> <span class="token number">0%</span>, <span class="token hexcode">#ffe5e5</span> <span class="token number">100%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">2</span>px solid <span class="token hexcode">#ff6b6b</span><span class="token punctuation">;</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">12</span>px<span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">1.5</span>rem<span class="token punctuation">;</span>
        <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">2</span>rem<span class="token punctuation">;</span>
        <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">4</span>px <span class="token number">12</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">107</span>, <span class="token number">107</span>, <span class="token number">0.15</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">animation</span><span class="token punctuation">:</span> slideIn <span class="token number">0.3</span>s ease-out<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.validation-header</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">0.75</span>rem<span class="token punctuation">;</span>
        <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">1</span>rem<span class="token punctuation">;</span>
        <span class="token property">padding-bottom</span><span class="token punctuation">:</span> <span class="token number">0.75</span>rem<span class="token punctuation">;</span>
        <span class="token property">border-bottom</span><span class="token punctuation">:</span> <span class="token number">1</span>px solid <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">107</span>, <span class="token number">107</span>, <span class="token number">0.3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.validation-header</span> <span class="token class">.k-svg-icon</span> </span><span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#ff6b6b</span><span class="token punctuation">;</span>
        <span class="token property">flex-shrink</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.validation-title</span> </span><span class="token punctuation">{</span>
        <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">1.1</span>rem<span class="token punctuation">;</span>
        <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">600</span><span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#c92a2a</span><span class="token punctuation">;</span>
        <span class="token property">letter-spacing</span><span class="token punctuation">:</span> <span class="token number">0.3</span>px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.validation-body</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">0.75</span>rem<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.validation-item</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">align-items</span><span class="token punctuation">:</span> flex-start<span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">0.75</span>rem<span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">0.5</span>rem<span class="token punctuation">;</span>
        <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">0.6</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">8</span>px<span class="token punctuation">;</span>
        <span class="token property">transition</span><span class="token punctuation">:</span> all <span class="token number">0.2</span>s ease<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.validation-item</span><span class="token pseudo-class">:hover</span> </span><span class="token punctuation">{</span>
        <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">0.9</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateX</span><span class="token punctuation">(</span><span class="token number">4</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.validation-icon</span> </span><span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#ff6b6b</span><span class="token punctuation">;</span>
        <span class="token property">flex-shrink</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token number">2</span>px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.validation-text</span> </span><span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#495057</span><span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.95</span>rem<span class="token punctuation">;</span>
        <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.5</span><span class="token punctuation">;</span>
        <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">500</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    @<span class="token atrule"><span class="token rule">@keyframes</span> slideIn</span> <span class="token punctuation">{</span>
        <span class="token selector">from </span><span class="token punctuation">{</span>
            <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateY</span><span class="token punctuation">(</span>-<span class="token number">10</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token selector">to </span><span class="token punctuation">{</span>
            <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">;</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateY</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>

...

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikValidationSummary</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Template</span> <span class="token attr-name">Context</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validationMessages<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        @if (validationMessages.Any())
        {
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validation-alert-modern<span class="token punctuation">"</span></span> <span class="token attr-name">role</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>alert<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validation-header<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.XCircle<span class="token punctuation">"</span></span> <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.SvgIcon.Size.Large<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h5</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validation-title<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Please Fix The Following Errors<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h5</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validation-body<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    @foreach (string message in validationMessages)
                    {
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">@key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@message<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validation-item<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.ArrowRight<span class="token punctuation">"</span></span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validation-icon<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validation-text<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@message<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                    }
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        }
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikValidationSummary</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>The result of using the <code>Template</code> parameter with the custom code is as follows:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/the-telerikvalidationsummary-component-showcasing-a-modern-design-by-leveraging-the-template-parameter.png?sfvrsn=a2125c1c_2" alt="The TelerikValidationSummary component showcasing a modern design by leveraging the Template parameter" /></p><p>In case the customizations you wish to make are minor, you can also use the <code>CSS</code> parameter, in which case you should create a custom CSS class for the <code>div.k-validation-summary</code> container as in the following example:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikValidationSummary</span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>bold-blue<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">&gt;</span></span><span class="token style language-css">
    <span class="token selector">div<span class="token class">.bold-blue.k-validation-summary</span> </span><span class="token punctuation">{</span>
        <span class="token property">font-weight</span><span class="token punctuation">:</span> bold<span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> blue<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Now let&rsquo;s see how to customize error messages for each form element.</p><h2 id="the-telerik-validation-message-component-for-blazor">The Telerik Validation Message Component for Blazor</h2><p>If you need to customize the messages for each item in the form, the ideal option is to use the <code>TelerikValidationMessage</code> component. To use it, you should replace the <code>ValidationMessage</code> tag with <code>TelerikValidationMessage</code>, as in the following example:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>firstName<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-label<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>First Name:<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>InputText</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>firstName<span class="token punctuation">"</span></span> <span class="token attr-name">@bind-Value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>userModel.FirstName<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-control<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikValidationMessage</span> <span class="token attr-name">For</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@(() =&gt; userModel.FirstName)<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>If you want to customize the error messages of the form for each input control, you can use the <code>Template</code> parameter along with the <code>Context</code> property that contains the collection of validation messages for the model property you are validating. An example of this customization is the following code:</p><pre class=" language-xml"><code class="prism  language-xml">...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">&gt;</span></span><span class="token style language-css">
    <span class="token selector"><span class="token class">.field-validation-error</span> </span><span class="token punctuation">{</span>
        <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">0.75</span>rem<span class="token punctuation">;</span>
        <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span><span class="token number">135</span>deg, <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">239</span>, <span class="token number">68</span>, <span class="token number">68</span>, <span class="token number">0.15</span><span class="token punctuation">)</span> <span class="token number">0%</span>, <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">220</span>, <span class="token number">38</span>, <span class="token number">38</span>, <span class="token number">0.08</span><span class="token punctuation">)</span> <span class="token number">100%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">backdrop-filter</span><span class="token punctuation">:</span> <span class="token function">blur</span><span class="token punctuation">(</span><span class="token number">10</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span>px solid <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">239</span>, <span class="token number">68</span>, <span class="token number">68</span>, <span class="token number">0.3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">0.875</span>rem <span class="token number">1.125</span>rem<span class="token punctuation">;</span>
        <span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token number">0.625</span>rem<span class="token punctuation">;</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">12</span>px<span class="token punctuation">;</span>
        <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">4</span>px <span class="token number">16</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">239</span>, <span class="token number">68</span>, <span class="token number">68</span>, <span class="token number">0.12</span><span class="token punctuation">)</span>, inset <span class="token number">0</span> <span class="token number">1</span>px <span class="token number">0</span> <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">0.5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">animation</span><span class="token punctuation">:</span> errorSlideIn <span class="token number">0.4</span>s <span class="token function">cubic-bezier</span><span class="token punctuation">(</span><span class="token number">0.68</span>, -<span class="token number">0.55</span>, <span class="token number">0.265</span>, <span class="token number">1.55</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

        <span class="token selector"><span class="token class">.field-validation-error</span><span class="token pseudo-element">::before</span> </span><span class="token punctuation">{</span>
            <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">''</span><span class="token punctuation">;</span>
            <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
            <span class="token property">left</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token property">top</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">4</span>px<span class="token punctuation">;</span>
            <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">100%</span><span class="token punctuation">;</span>
            <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span><span class="token number">180</span>deg, <span class="token hexcode">#ef4444</span> <span class="token number">0%</span>, <span class="token hexcode">#dc2626</span> <span class="token number">100%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token property">animation</span><span class="token punctuation">:</span> pulseBar <span class="token number">2</span>s ease-in-out infinite<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token selector"><span class="token class">.field-validation-error</span><span class="token pseudo-element">::after</span> </span><span class="token punctuation">{</span>
            <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">''</span><span class="token punctuation">;</span>
            <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
            <span class="token property">right</span><span class="token punctuation">:</span> -<span class="token number">50</span>px<span class="token punctuation">;</span>
            <span class="token property">top</span><span class="token punctuation">:</span> -<span class="token number">50</span>px<span class="token punctuation">;</span>
            <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">100</span>px<span class="token punctuation">;</span>
            <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">100</span>px<span class="token punctuation">;</span>
            <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">radial-gradient</span><span class="token punctuation">(</span>circle, <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">239</span>, <span class="token number">68</span>, <span class="token number">68</span>, <span class="token number">0.15</span><span class="token punctuation">)</span> <span class="token number">0%</span>, transparent <span class="token number">70%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">50%</span><span class="token punctuation">;</span>
            <span class="token property">animation</span><span class="token punctuation">:</span> floatCircle <span class="token number">3</span>s ease-in-out infinite<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.field-validation-icon</span> </span><span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#dc2626</span><span class="token punctuation">;</span>
        <span class="token property">flex-shrink</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token property">filter</span><span class="token punctuation">:</span> <span class="token function">drop-shadow</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token number">2</span>px <span class="token number">4</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">220</span>, <span class="token number">38</span>, <span class="token number">38</span>, <span class="token number">0.3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">animation</span><span class="token punctuation">:</span> iconPulse <span class="token number">2</span>s ease-in-out infinite<span class="token punctuation">;</span>
        <span class="token property">z-index</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.field-validation-text</span> </span><span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#991b1b</span><span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.9</span>rem<span class="token punctuation">;</span>
        <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">600</span><span class="token punctuation">;</span>
        <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token property">letter-spacing</span><span class="token punctuation">:</span> <span class="token number">0.3</span>px<span class="token punctuation">;</span>
        <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.4</span><span class="token punctuation">;</span>
        <span class="token property">z-index</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">;</span>
        <span class="token property">text-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">1</span>px <span class="token number">2</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">0.8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    @<span class="token atrule"><span class="token rule">@keyframes</span> errorSlideIn</span> <span class="token punctuation">{</span>
        <span class="token selector">0% </span><span class="token punctuation">{</span>
            <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateY</span><span class="token punctuation">(</span>-<span class="token number">10</span>px<span class="token punctuation">)</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">0.95</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token selector">50% </span><span class="token punctuation">{</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateY</span><span class="token punctuation">(</span><span class="token number">2</span>px<span class="token punctuation">)</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1.02</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token selector">100% </span><span class="token punctuation">{</span>
            <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">;</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateY</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    @<span class="token atrule"><span class="token rule">@keyframes</span> pulseBar</span> <span class="token punctuation">{</span>
        <span class="token selector">0%, 100% </span><span class="token punctuation">{</span>
            <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">;</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scaleY</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token selector">50% </span><span class="token punctuation">{</span>
            <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">0.7</span><span class="token punctuation">;</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scaleY</span><span class="token punctuation">(</span><span class="token number">0.95</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    @<span class="token atrule"><span class="token rule">@keyframes</span> iconPulse</span> <span class="token punctuation">{</span>
        <span class="token selector">0%, 100% </span><span class="token punctuation">{</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token selector">50% </span><span class="token punctuation">{</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1.1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    @<span class="token atrule"><span class="token rule">@keyframes</span> floatCircle</span> <span class="token punctuation">{</span>
        <span class="token selector">0%, 100% </span><span class="token punctuation">{</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translate</span><span class="token punctuation">(</span><span class="token number">0</span>, <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token selector">50% </span><span class="token punctuation">{</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translate</span><span class="token punctuation">(</span>-<span class="token number">10</span>px, <span class="token number">10</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>row<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>col-md-6<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>EditForm</span> <span class="token attr-name">Model</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@userModel<span class="token punctuation">"</span></span> <span class="token attr-name">OnValidSubmit</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@HandleValidSubmit<span class="token punctuation">"</span></span> <span class="token attr-name">FormName</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>userRegistrationForm<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        ...
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>firstName<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-label<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>First Name:<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>InputText</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>firstName<span class="token punctuation">"</span></span> <span class="token attr-name">@bind-Value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>userModel.FirstName<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-control<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikValidationMessage</span> <span class="token attr-name">For</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@(() =&gt; userModel.FirstName)<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Template</span> <span class="token attr-name">Context</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validationMessages<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        @foreach (var message in validationMessages)
                        {
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>field-validation-error<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.ExclamationCircle<span class="token punctuation">"</span></span> <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.SvgIcon.Size.Large<span class="token punctuation">"</span></span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>field-validation-icon<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>field-validation-text<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@message<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                        }
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Template</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikValidationMessage</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
            ...
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>EditForm</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>        
...
</code></pre><p>After compiling and running the application, we can see a customization of the error message:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/customizing-a-text-box-error-message-using-the-telerikvalidationmessage-component.png?sfvrsn=b0bb8014_2" alt="Customizing a text box error message using the TelerikValidationMessage component" /></p><p>Now, to avoid repeatedly writing the same HTML error code, you could create a new component to define the layout and behavior as follows:</p><pre class=" language-xml"><code class="prism  language-xml">@using System.Linq.Expressions
@typeparam TProperty

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikValidationMessage</span> <span class="token attr-name">For</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>For<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Template</span> <span class="token attr-name">Context</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validationMessages<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        @foreach (var message in validationMessages)
        {
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>field-validation-error<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.ExclamationCircle<span class="token punctuation">"</span></span>
                                <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.SvgIcon.Size.Large<span class="token punctuation">"</span></span>
                                <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>field-validation-icon<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>field-validation-text<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@message<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        }
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikValidationMessage</span><span class="token punctuation">&gt;</span></span>

@code {
    [Parameter, EditorRequired]
    public Expression&lt;Func<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TProperty</span><span class="token punctuation">&gt;</span></span>&gt; For { get; set; }
}
</code></pre><p>Finally, you could reuse the component, which in my case I have named <code>CustomError</code>, wherever needed, as in other parts of the form:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-3 form-check<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>InputCheckbox</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>terms<span class="token punctuation">"</span></span> <span class="token attr-name">@bind-Value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>userModel.AcceptTerms<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-check-input<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>terms<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-check-label<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>I accept the terms and conditions<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span>
    @* <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ValidationMessage</span> <span class="token attr-name">For</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@(() =&gt; userModel.AcceptTerms)<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span> *@
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CustomError</span> <span class="token attr-name">For</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@(() =&gt; userModel.AcceptTerms)<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>With this, we achieve a centralized place to modify the appearance of the error template if we need to.</p><h2 id="the-telerik-validation-tooltip-component-for-blazor">The Telerik Validation Tooltip Component for Blazor</h2><p>The last component we will discuss is the <strong>Validation Tooltip for Blazor</strong>, which serves the same purpose as the <strong>Validation Message</strong> component but differs in that it does not take up space on the page. Instead, it appears as a tooltip on the form element that requires attention.</p><p>To use it, you should add a tag <code>TelerikValidationTooltip</code> replacing any <code>ValidationMessage</code> or <code>TelerikValidationMessage</code> component, specifying through the <code>For</code> parameter the property to validate, the <code>Position</code> parameter the tooltip location (<code>Top</code>, <code>Bottom</code>, <code>Right</code> or <code>Left</code>), and the <code>TargetSelector</code> parameter that points to the desired element in the Form, as shown below:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>firstName<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-label<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>First Name:<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>InputText</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>firstName<span class="token punctuation">"</span></span> <span class="token attr-name">@bind-Value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>userModel.FirstName<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>form-control<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikValidationTooltip</span> <span class="token attr-name">For</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@(() =&gt; userModel.FirstName)<span class="token punctuation">"</span></span>
                                <span class="token attr-name">TargetSelector</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>#firstName<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Once again, this component has a parameter called <code>Template</code> that allows you to customize its appearance, as in the following example:</p><pre class=" language-xml"><code class="prism  language-xml">...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">&gt;</span></span><span class="token style language-css">
<span class="token selector"><span class="token class">...</span>
    <span class="token class">.validation-tooltip-modern</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">0.5</span>rem<span class="token punctuation">;</span>
        <span class="token property">min-width</span><span class="token punctuation">:</span> <span class="token number">220</span>px<span class="token punctuation">;</span>
        <span class="token property">max-width</span><span class="token punctuation">:</span> <span class="token number">320</span>px<span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">1</span>rem <span class="token number">1.25</span>rem<span class="token punctuation">;</span>
        <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span><span class="token number">145</span>deg, <span class="token hexcode">#1e1e2e</span> <span class="token number">0%</span>, <span class="token hexcode">#2d2d44</span> <span class="token number">100%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">14</span>px<span class="token punctuation">;</span>
        <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span>px solid <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">100</span>, <span class="token number">100</span>, <span class="token number">0.4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">10</span>px <span class="token number">40</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">0</span>, <span class="token number">0</span>, <span class="token number">0</span>, <span class="token number">0.4</span><span class="token punctuation">)</span>, <span class="token number">0</span> <span class="token number">0</span> <span class="token number">20</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">100</span>, <span class="token number">100</span>, <span class="token number">0.15</span><span class="token punctuation">)</span>, inset <span class="token number">0</span> <span class="token number">1</span>px <span class="token number">0</span> <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">0.05</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">animation</span><span class="token punctuation">:</span> tooltipBounceIn <span class="token number">0.35</span>s <span class="token function">cubic-bezier</span><span class="token punctuation">(</span><span class="token number">0.68</span>, -<span class="token number">0.55</span>, <span class="token number">0.265</span>, <span class="token number">1.55</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
        <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

        <span class="token selector"><span class="token class">.validation-tooltip-modern</span><span class="token pseudo-element">::before</span> </span><span class="token punctuation">{</span>
            <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">''</span><span class="token punctuation">;</span>
            <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
            <span class="token property">top</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token property">left</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token property">right</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">3</span>px<span class="token punctuation">;</span>
            <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span><span class="token number">90</span>deg, <span class="token hexcode">#ff6b6b</span>, <span class="token hexcode">#ff8e8e</span>, <span class="token hexcode">#ff6b6b</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token property">background-size</span><span class="token punctuation">:</span> <span class="token number">200%</span> <span class="token number">100%</span><span class="token punctuation">;</span>
            <span class="token property">animation</span><span class="token punctuation">:</span> shimmer <span class="token number">2</span>s linear infinite<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.tooltip-header</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">0.625</span>rem<span class="token punctuation">;</span>
        <span class="token property">padding-bottom</span><span class="token punctuation">:</span> <span class="token number">0.625</span>rem<span class="token punctuation">;</span>
        <span class="token property">border-bottom</span><span class="token punctuation">:</span> <span class="token number">1</span>px solid <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">255</span>, <span class="token number">0.1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.tooltip-icon-wrapper</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
        <span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
        <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">28</span>px<span class="token punctuation">;</span>
        <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">28</span>px<span class="token punctuation">;</span>
        <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span><span class="token number">135</span>deg, <span class="token hexcode">#ff6b6b</span> <span class="token number">0%</span>, <span class="token hexcode">#ee5a5a</span> <span class="token number">100%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">8</span>px<span class="token punctuation">;</span>
        <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">2</span>px <span class="token number">8</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">107</span>, <span class="token number">107</span>, <span class="token number">0.4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">animation</span><span class="token punctuation">:</span> iconGlow <span class="token number">2</span>s ease-in-out infinite<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

        <span class="token selector"><span class="token class">.tooltip-icon-wrapper</span> <span class="token class">.k-svg-icon</span> </span><span class="token punctuation">{</span>
            <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#fff</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.tooltip-title</span> </span><span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#ff8a8a</span><span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.75</span>rem<span class="token punctuation">;</span>
        <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">700</span><span class="token punctuation">;</span>
        <span class="token property">text-transform</span><span class="token punctuation">:</span> uppercase<span class="token punctuation">;</span>
        <span class="token property">letter-spacing</span><span class="token punctuation">:</span> <span class="token number">1</span>px<span class="token punctuation">;</span>
        <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.tooltip-message-item</span> </span><span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
        <span class="token property">align-items</span><span class="token punctuation">:</span> flex-start<span class="token punctuation">;</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">0.5</span>rem<span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">0.5</span>rem <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.tooltip-bullet</span> </span><span class="token punctuation">{</span>
        <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">6</span>px<span class="token punctuation">;</span>
        <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">6</span>px<span class="token punctuation">;</span>
        <span class="token property">background</span><span class="token punctuation">:</span> <span class="token hexcode">#ff6b6b</span><span class="token punctuation">;</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">50%</span><span class="token punctuation">;</span>
        <span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token number">6</span>px<span class="token punctuation">;</span>
        <span class="token property">flex-shrink</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">0</span> <span class="token number">8</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">107</span>, <span class="token number">107</span>, <span class="token number">0.6</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">animation</span><span class="token punctuation">:</span> bulletPulse <span class="token number">1.5</span>s ease-in-out infinite<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.tooltip-message-text</span> </span><span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode">#e4e4e7</span><span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token number">0.875</span>rem<span class="token punctuation">;</span>
        <span class="token property">font-weight</span><span class="token punctuation">:</span> <span class="token number">500</span><span class="token punctuation">;</span>
        <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.5</span><span class="token punctuation">;</span>
        <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    @<span class="token atrule"><span class="token rule">@keyframes</span> tooltipBounceIn</span> <span class="token punctuation">{</span>
        <span class="token selector">0% </span><span class="token punctuation">{</span>
            <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">0.8</span><span class="token punctuation">)</span> <span class="token function">translateY</span><span class="token punctuation">(</span><span class="token number">10</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token selector">50% </span><span class="token punctuation">{</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1.02</span><span class="token punctuation">)</span> <span class="token function">translateY</span><span class="token punctuation">(</span>-<span class="token number">2</span>px<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token selector">100% </span><span class="token punctuation">{</span>
            <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">;</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token function">translateY</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    @<span class="token atrule"><span class="token rule">@keyframes</span> shimmer</span> <span class="token punctuation">{</span>
        <span class="token selector">0% </span><span class="token punctuation">{</span>
            <span class="token property">background-position</span><span class="token punctuation">:</span> -<span class="token number">200%</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token selector">100% </span><span class="token punctuation">{</span>
            <span class="token property">background-position</span><span class="token punctuation">:</span> <span class="token number">200%</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    @<span class="token atrule"><span class="token rule">@keyframes</span> iconGlow</span> <span class="token punctuation">{</span>
        <span class="token selector">0%, 100% </span><span class="token punctuation">{</span>
            <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">2</span>px <span class="token number">8</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">107</span>, <span class="token number">107</span>, <span class="token number">0.4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token selector">50% </span><span class="token punctuation">{</span>
            <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">2</span>px <span class="token number">16</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">255</span>, <span class="token number">107</span>, <span class="token number">107</span>, <span class="token number">0.7</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    @<span class="token atrule"><span class="token rule">@keyframes</span> bulletPulse</span> <span class="token punctuation">{</span>
        <span class="token selector">0%, 100% </span><span class="token punctuation">{</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token selector">50% </span><span class="token punctuation">{</span>
            <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">1.3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">0.7</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikValidationTooltip</span> <span class="token attr-name">For</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@(() =&gt; userModel.FirstName)<span class="token punctuation">"</span></span>
                            <span class="token attr-name">TargetSelector</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>#firstName<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Template</span> <span class="token attr-name">Context</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validationMessages<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        @if (validationMessages.Any())
        {
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>validation-tooltip-modern<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tooltip-header<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tooltip-icon-wrapper<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.ExclamationCircle<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tooltip-title<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Validation Error<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                @foreach (var message in validationMessages)
                {
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tooltip-message-item<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tooltip-bullet<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tooltip-message-text<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@message<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                }
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        }
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikValidationTooltip</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>The above code shows a tooltip that looks quite elaborate as shown below:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/displaying-a-custom-error-message-as-a-tooltip-using-the-telerikvalidationtooltip-component.gif?sfvrsn=839fbe7_2" alt="Displaying a custom error message as a tooltip using the TelerikValidationTooltip component" /></p><p>Certainly, the previous design gives us an idea of the customization power we have thanks to the use of this component.</p><h2 id="conclusion">Conclusion</h2><p>Throughout this article, we have explored various Blazor components that will allow you to enhance your users&rsquo; experience by displaying customized layouts as complex as you need. This will enable the look and feel of these messages to adapt to the colors and theme of your project without using tricks or code that can increase the project&rsquo;s complexity.</p><p>Finally, in the examples of this article, I have used forms of type <code>EditForm</code> to keep the examples general, but it is also possible to combine them with <a target="_blank" href="https://www.telerik.com/blazor-ui/form"><strong>Blazor Form</strong></a> components, which have a greater number of features and flexibility for displaying forms.</p><p>Explore the Form, Validation and Tooltip components, plus about 120 others available in the <a target="_blank" href="https://www.telerik.com/blazor-ui">Telerik UI for Blazor</a> library, all with a free 30-day trial.</p><p><a target="_blank" href="https://www.telerik.com/try/ui-for-blazor" class="Btn">Try Now</a></p><img src="https://feeds.telerik.com/link/23050/17273669.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:520fcd7c-3f7c-4406-b049-eafd9b85053f</id>
    <title type="text">Top 5 Components for Building AI-Powered Blazor Applications</title>
    <summary type="text">These five components can help you leverage the power of AI inside your Blazor app.</summary>
    <published>2026-02-03T17:44:53Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Héctor Pérez </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17269315/top-5-components-building-ai-powered-blazor-applications"/>
    <content type="text"><![CDATA[<p><span class="featured">These five components can help you leverage the power of AI inside your Blazor app.</span></p><p>Nowadays, the <a target="_blank" href="https://www.grandviewresearch.com/industry-analysis/ai-apps-market-report">rise of AI-based applications</a> has skyrocketed, and even greater growth is expected in the coming years. Whether you&rsquo;re creating a ChatGPT clone or looking to integrate AI into your applications to help users with their tasks, it&rsquo;s always good to have components that allow you to build such applications quickly, easily and robustly.</p><p>That&rsquo;s why today I&rsquo;ll show you the best components for creating AI-based applications using Blazor.</p><h2 id="the-chat-component">The Chat Component</h2><p>When we talk about AI-powered applications, we often think of interfaces similar to ChatGPT, which allow us to have chat conversations with LLMs.</p><p>To create such applications, a reliable solution is to use the <a target="_blank" href="https://www.telerik.com/blazor-ui/chat-(conversational-ui)">Blazor Chat component</a> from Progress Telerik UI, which is tremendously useful as it comes with essential features for any chat application.</p><p>For example, the component has a set of <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/chat/data-binding#field-mapping">default chat message parameters</a> that can be configured such as <strong>AuthorId</strong>, <strong>AuthorImageUrlField</strong>, <strong>AuthorNameField</strong>, <strong>TextField</strong>, among others. These configurable parameters allow you to identify chat messages in a conversation, enabling real-time conversations between people or involving an <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/chat/integrations">AI model to respond to user queries</a>.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/.net-maui-aiprompt/chat---message-actions.png?sfvrsn=af57bb72_2" alt="Image of the Telerik Chat Component for Blazor" /></p><p>Speaking of chat messages, they can be configurable through multiple <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/chat/templates">configuration templates</a>, allowing you to customize messages to match your own theme.</p><p>Additionally, it is possible to <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/chat/quick-actions">configure a set of Quick Actions</a>, which are suggested messages that users can press to quickly send queries to the AI model. These actions are useful when introducing the user to system functionalities or when knowing there are repetitive actions that can be performed, such as document analysis, scheduling dates or requesting additional information.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/.net-maui-aiprompt/telerik-ui-for-asp-net-core---chat---ai-service-integration.gif?sfvrsn=720ec997_2" alt="Quick Actions Demonstration in the Blazor Chat Component" /></p><p>Another notable feature of the component is the ability to handle <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/chat/file-uploads-and-media">file uploads and validation</a>. Additionally, you can also <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/chat/file-uploads-and-media#speech-to-text">enable the speech-to-text feature</a> to expedite message dictation.</p><p>Some useful scenarios for using this component include:</p><ul><li>Support applications based on company documentation</li><li>Using agent patterns for selecting specialized agents to resolve user issues</li><li>Service selling applications like ChatGPT using third-party APIs</li></ul><p>Without a doubt, this is a component you should have in your arsenal when thinking about chat-type applications.</p><h2 id="the-ai-prompt-component">The AI Prompt Component</h2><p>If you need to integrate user interaction with an AI model without maintaining a conversation thread or the need to attach files, one of the best options is the <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/aiprompt/overview#creating-blazor-aiprompt">Telerik UI for Blazor AI Prompt</a> component.</p><p>This fabulous component allows the user to enter their own prompts to get responses based on the initial configuration of the component, and then interact with it through predefined commands. It is also possible to set up a series of prompt suggestions so that the user can perform quick actions.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/.net-maui-scheduler/telerik-ui-for-blazor-aiprompt-gettingstarted.gif?sfvrsn=b7e51f56_2" alt="The AIPrompt component in action, demonstrating how to create an email from a prompt suggestion" /></p><p>The component features three main configurable views:</p><ul><li><a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/aiprompt/views/prompt"><strong>Prompt View</strong></a>: Allows the user to enter prompts to interact with a previously configured AI model.</li><li><a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/aiprompt/views/output"><strong>Output View</strong></a>: Window displaying a list of previous responses generated by the AI model in card format.</li><li><a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/aiprompt/views/commands"><strong>Commands View</strong></a>: Section where predefined commands exist that the user can execute based on the model&rsquo;s generations.</li></ul><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/.net-maui-scheduler/telerik-ui-for-blazor-aiprompt-predefinedviews.gif?sfvrsn=6ed06439_2" alt="The IAPrompt component demonstrating several customized views" /></p><p>Its use is ideal in cases where a response is needed that can undergo some form of processing, such as:</p><ul><li>Content writer applications that can be improved after the first generation</li><li>Information processing applications, for example, where a video URL is pasted, the script is extracted, and a summary, posts for social media, etc. are generated</li><li>Information explaining applications that help users understand complicated concepts or technical jargon in, for instance, framework documentation or legal documents</li></ul><p>The AI Prompt component is an excellent option for providing users with tools to make the most out of the systems.</p><h2 id="the-inline-ai-prompt-component">The Inline AI Prompt Component</h2><p>If you are looking for a simplified version of the AI Prompt component, you also have the <a target="_blank" href="https://www.telerik.com/blazor-ui/inline-ai-prompt">Blazor Inline AI Prompt</a> component available. This component allows you to display an inline chat window in the graphical interface, with the advantage of positioning it wherever you desire.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/demonstration-executing-quick-actions--using-the-inlineaiprompt-blazor.gif?sfvrsn=4bdc59de_2" alt="Demonstration of executing quick actions using the InlineAIPrompt component for Blazor" /></p><p>This means you can offer your users experiences where they don&rsquo;t even have to interrupt the task they are performing. Additionally, it is also possible to add predefined commands that the user can select to easily perform an action.</p><p>Some use cases for this component include:</p><ul><li>Text editors that allow selecting a part of the text to carry out an action on it</li><li>Data applications where tabular information can be retrieved for inquiries</li><li>Educational applications, where students can ask more questions about a specific topic</li></ul><p>Certainly, this is a useful component for experiencing AI integration in your applications, making user interaction easier.</p><h2 id="the-speech-to-text-button-component">The Speech-to-Text Button Component</h2><p>One thing users want when interacting with AI models is the ability to make queries as quickly as possible. One way to make this possible is through voice dictation. While it would be possible to use an AI model for this purpose, the truth is that there are solutions that allow for speech-to-text processing without consuming much processing power or credits from using AI APIs.</p><p>One of these methods can be found in the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API">Web Speech API</a>, which allows the browser itself to recognize text through speech recognition. The <a target="_blank" href="https://www.telerik.com/blazor-ui/speech-to-text-button">Speech-to-Text Button component for Blazor</a> enables us to leverage this API to convert voice to text very easily by adding the component <code>TelerikSpeechToTextButton</code> in the application.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/demo-speechtotext-blazor.gif?sfvrsn=307079f7_2" alt="Demonstration of the SpeechToText component, showcasing how spoken input is recognized and transcribed into text" /></p><p>In addition to this, it also includes many predefined <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/speechtotextbutton/appearance">customization options</a> that allow you to configure size, background type, color, rounding, icon assignment and you can even apply a custom CSS class.</p><p>Some use cases for this component could be:</p><ul><li>Chat applications: You can add this component to chat applications, where you would allow converting speech input into text quickly.</li><li>Text editors: You could add this component to perform dictation in some type of document, facilitating text drafting or executing similar tasks.</li><li>Note-taking applications: Taking notes can be complicated if you are doing other tasks. By using this component, you can make it easier for users to create spoken notes to be immediately transcribed.</li></ul><p>So if you&rsquo;re looking for a solution that enables speech-to-text recognition in Blazor, this component is a wonderful option.</p><h2 id="the-data-grid-component">The Data Grid Component</h2><p>The last component we will discuss is the <a target="_blank" href="https://www.telerik.com/blazor-ui/grid">Blazor Data Grid</a>. This component is one of the most powerful in the Blazor component market, offering endless configurations to build your grids in the best way you see fit. Among these, we find functionalities such as paging, different editing modes, sorting, filtering, grouping, drag and drop, virtual scrolling and a bunch of other features.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blazor/blazor-data-grid.png?sfvrsn=563eea4b_2" alt="An overview of the DataGrid component, highlighting features like filtering and grouping" /></p><p>In addition to the aforementioned configuration options, it is worth mentioning that the Telerik Data Grid component for Blazor is a pioneer in AI integration in the use of information tables, featuring the so-called <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/grid/smart-ai-features/overview">Smart AI Features</a>, which allow users to write plain text prompts for the grid to display data according to the requested information, all with an AI model behind the scenes.</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/.net-maui-aiprompt/telerik-ui-for-blazor-grid---prompt-based-cell-highlighting---above-60.gif?sfvrsn=3189bb44_2" alt="Demo of the DataGrid component using Smart AI Features to highlight rows based on a text instruction" /></p><p>The operations that can be performed today include filtering, sorting, grouping, highlighting, column operations, pagination, selection and exporting.</p><p>The use of this component can be applied in any scenario where information exists, so it is undoubtedly extremely useful for providing users with a new way to interact with information quickly.</p><h2 id="conclusion">Conclusion</h2><p>Throughout this article, I have shown you a set of five super powerful components that you can use in your own AI-based applications. From the Chat component that allows interaction with AI models through chat conversations, through the AI Prompt and Inline AI Prompt components that allow you to quickly execute prompts for text generation, to the Data Grid that offers a unique experience by allowing data queries using natural language to work with tabular data.</p><p>I invite you to try them and bring the capabilities of AI models closer to your users in your own applications.</p><p><a target="_blank" href="https://www.telerik.com/try/ui-for-blazor" class="Btn">Try Telerik UI for Blazor</a></p><img src="https://feeds.telerik.com/link/23050/17269315.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:334a71c6-bb63-4124-8eef-1c7f7b1063cb</id>
    <title type="text">Getting Started with the Blazor Diagram Component</title>
    <summary type="text">Visualizing workflows, hierarchy or other figures is easy with the Blazor Diagram component. Learn how customize it for your app.</summary>
    <published>2026-01-27T20:59:19Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Héctor Pérez </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17264743/getting-started-blazor-diagram-component"/>
    <content type="text"><![CDATA[<p><span class="featured">Visualizing workflows, hierarchy or other figures is easy with the Blazor Diagram component. Learn how customize it for your app.</span></p><p>Creating diagrams in web applications becomes necessary for those that need to display hierarchical information or workflows. Therefore, it is essential that in the Blazor components ecosystem there are reliable solutions that allow creating them quickly, while also offering flexibility to customize them according to the tasks to be performed.</p><p>In this post, I will tell you about the new Progress <a target="_blank" href="https://www.telerik.com/blazor-ui/diagram">Telerk UI for Blazor Diagram</a> component, which allows you to create diagrams in a simple way.</p><h2 id="creating-your-first-figure-with-the-diagram-component">Creating Your First Figure with the Diagram Component</h2><p>The first step to be able to create diagrams in your application is to configure your project to work with the Telerik components, according to the <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/getting-started/web-app">Blazor components installation guides</a>.</p><p>Once the project has been configured, you should use the tag <code>TelerikDiagram</code>, which will be the main container where the diagram will be rendered, and where you can configure parameters such as <code>Height</code>, <code>Width</code>, <code>Zoom</code>, <code>ZoomRate</code>, <code>MinZoom</code> and <code>MaxZoom</code>. An example of its usage is the following:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikDiagram</span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>500px<span class="token punctuation">"</span></span> <span class="token attr-name">Zoom</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0.8<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikDiagram</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>When you run the application, you will see the canvas when you click on it:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/telerik-blazor-diagram-component-activated-when-the-user-clicks-on-it.gif?sfvrsn=1bcd56cf_2" alt="Telerik Blazor Diagram component, activated when the user clicks on it" /></p><p>Once we have our main container, let&rsquo;s see how to add figures to it.</p><h2 id="adding-shapes-to-the-diagram-component-for-blazor">Adding Shapes to the Diagram Component for Blazor</h2><p>To add shapes in Blazor, you should know some of the Shapes parameters:</p><ul><li><code>Id</code>: To identify the shapes and be able to relate them</li><li><code>Type</code>: Indicates the shape type</li><li><code>Width</code> and <code>Height</code>: Specify the size in pixels, with the default value being 100.</li><li><code>X</code> and <code>Y</code>: Allow placing a shape at an exact position.</li><li><code>Path</code>: Allows specifying a custom shape</li></ul><p>To add Shapes to the diagram you must define the collection of shapes through the tag <code>DiagramShapes</code>, adding to the collection a set of elements <code>DiagramShape</code>, specifying the characteristics of each shape.</p><p>Since in our current example we have not defined a <strong>Diagram layout</strong> (which we will see later), we can use the parameters <code>X</code> and <code>Y</code> to define some positions, as shown below:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikDiagram</span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>500px<span class="token punctuation">"</span></span> <span class="token attr-name">Zoom</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0.8<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShapes</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape1<span class="token punctuation">"</span></span>
                      <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@DiagramShapeType.Circle<span class="token punctuation">"</span></span>
                      <span class="token attr-name">X</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>10<span class="token punctuation">"</span></span> <span class="token attr-name">Y</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>10<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape2<span class="token punctuation">"</span></span>
                      <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@DiagramShapeType.Process<span class="token punctuation">"</span></span>
                      <span class="token attr-name">X</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100<span class="token punctuation">"</span></span> <span class="token attr-name">Y</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape3<span class="token punctuation">"</span></span>
                      <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@DiagramShapeType.Document<span class="token punctuation">"</span></span>
                      <span class="token attr-name">X</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>200<span class="token punctuation">"</span></span> <span class="token attr-name">Y</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>200<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape4<span class="token punctuation">"</span></span>
                      <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@DiagramShapeType.Display<span class="token punctuation">"</span></span>
                      <span class="token attr-name">X</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>300<span class="token punctuation">"</span></span> <span class="token attr-name">Y</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>300<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape5<span class="token punctuation">"</span></span>
                      <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@DiagramShapeType.Merge<span class="token punctuation">"</span></span>
                      <span class="token attr-name">X</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>400<span class="token punctuation">"</span></span> <span class="token attr-name">Y</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>400<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramShapes</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikDiagram</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>In the previous code, you could see that <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/api/telerik.blazor.diagramshapetype"><code>DiagramShapeType</code></a> is an enumeration with all the available shape types, which at the time of writing this article has 28 shapes available, including shapes of <code>Image</code> and <code>Text</code>. The previous code gives us the following rendering:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/the-blazor-diagram-component-showcasing-different-shapes.gif?sfvrsn=4528c54f_2" alt="The Blazor Diagram component showcasing different shapes" /></p><p>In the figure above, you can see that the shapes are displayed at the specified positions, and we can also move them as we wish.</p><h2 id="creating-connections-between-shapes">Creating Connections Between Shapes</h2><p>A feature that diagram-type controls should undoubtedly have is connections between shapes. Although users can create these connections automatically, it is also possible to create them from code. For this, the tag <code>DiagramConnections</code> must be declared, which is a list that we must fill with tags of the type <code>DiagramConnection</code>, each of which can have the following parameters:</p><ul><li><code>FromId</code> and <code>ToId</code>: These are the identifiers that will relate the connection</li><li><code>Type</code>: Determines the type of connection (either <code>DiagramConnectionType.Cascading</code> or <code>DiagramConnectionType.Polyline</code>)</li><li><code>Cap</code>: Determines the type of cap that will appear on the figure (options: <code>DiagramConnectionsEndCapType.ArrowEnd</code>, <code>DiagramConnectionsEndCapType.FilledCircle</code> or <code>DiagramConnectionsEndCapType.None</code>)</li></ul><p>You can see an example of creating these relationships in the following example:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikDiagram</span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>500px<span class="token punctuation">"</span></span> <span class="token attr-name">Zoom</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0.8<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    ...
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnections</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span>
            <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape1<span class="token punctuation">"</span></span>
            <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape2<span class="token punctuation">"</span></span>
            <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>DiagramConnectionType.Cascading<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span>
            <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape2<span class="token punctuation">"</span></span>
            <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape3<span class="token punctuation">"</span></span>
            <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>DiagramConnectionType.Polyline<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span>
            <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape3<span class="token punctuation">"</span></span>
            <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape4<span class="token punctuation">"</span></span>
            <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>DiagramConnectionType.Cascading<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span>
            <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape4<span class="token punctuation">"</span></span>
            <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape5<span class="token punctuation">"</span></span>
            <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>DiagramConnectionType.Polyline<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramConnections</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikDiagram</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>In the previous code you can see how I mixed the connection types, resulting in the following execution:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/blazor-diagram-component-displaying-predefined-connections.gif?sfvrsn=ec27e75a_2" alt="Blazor Diagram component displaying predefined connections" /></p><p>In addition to the previous parameters, it is also possible to define a <strong>Cap</strong> through the tags <code>DiagramConnectionStartCap</code> and <code>DiagramConnectionEndCap</code>, as well as a <strong>Selection Handle</strong> through the tag <code>DiagramConnectionSelection</code>. Below you can see an example of its configuration:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikDiagram</span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>500px<span class="token punctuation">"</span></span> <span class="token attr-name">Zoom</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0.8<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    ...

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnections</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span> <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape1<span class="token punctuation">"</span></span>
                           <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape5<span class="token punctuation">"</span></span>
                           <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>DiagramConnectionType.Cascading<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnectionEndCap</span> <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@DiagramConnectionsEndCapType.ArrowStart<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnectionStartCap</span> <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@DiagramConnectionsStartCapType.FilledCircle<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramConnection</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span> <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape3<span class="token punctuation">"</span></span>
                           <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape4<span class="token punctuation">"</span></span>
                           <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>DiagramConnectionType.Polyline<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnectionSelection</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnectionSelectionHandles</span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>16<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>16<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnectionSelectionHandlesFill</span> <span class="token attr-name">Color</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>lime<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnectionSelectionHandlesStroke</span> <span class="token attr-name">Color</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>green<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramConnectionSelectionHandles</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramConnectionSelection</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramConnection</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramConnections</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikDiagram</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Running the application gives us the following result:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/diagram-component-demonstrating-the-use-of-caps-and-selection-handles-in-relationships-between-shapes.gif?sfvrsn=ca07843_2" alt="Diagram component demonstrating the use of Caps and Selection Handles in relationships between shapes" /></p><p>In the previous image, you can notice the use of <code>Cap</code> on the line that goes from the circle shape to the triangle shape, while the Selection Handle is active when the relationship between the shapes <code>Document</code> and <code>Display</code> is selected.</p><h2 id="setting-a-layout-in-the-diagram">Setting a Layout in the Diagram</h2><p>Once we know the elements we can use in the Diagram component, it&rsquo;s time to talk about the predefined Layouts you can use so you don&rsquo;t have to manually arrange the shapes. There are three main Layouts:</p><ul><li><strong>Tree Layout</strong>: Allows distributing the shapes in a hierarchical form</li><li><strong>Layered Layout</strong>: Distributes the shapes focusing on a horizontal or vertical flow, minimizing distance between shapes, connection lengths and crossings between shapes</li><li><strong>Force Layout</strong>: Enables a distribution where it seems each shape is connected by invisible springs that push or pull the shapes until they reach an equilibrium position. Note that each run with this configuration will produce a different distribution every time</li></ul><p>To use one of these layouts, you must use the tag <code>DiagramLayout</code> specifying the type, and it is also recommended to remove the use of the parameters <code>X</code> and <code>Y</code> as shown below:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikDiagram</span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>500px<span class="token punctuation">"</span></span> <span class="token attr-name">Zoom</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0.8<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramLayout</span> <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@DiagramLayoutType.Tree<span class="token punctuation">"</span></span>  <span class="token punctuation">/&gt;</span></span>

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShapes</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape1<span class="token punctuation">"</span></span><span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape2<span class="token punctuation">"</span></span><span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape3<span class="token punctuation">"</span></span><span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape4<span class="token punctuation">"</span></span><span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape5<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape6<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramShapes</span><span class="token punctuation">&gt;</span></span>

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnections</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span> <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape1<span class="token punctuation">"</span></span> <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape2<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span> <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape1<span class="token punctuation">"</span></span> <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape3<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span> <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape3<span class="token punctuation">"</span></span> <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape4<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span> <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape4<span class="token punctuation">"</span></span> <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape5<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span> <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape2<span class="token punctuation">"</span></span> <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape6<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramConnections</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikDiagram</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>Aside from the main type for the layout, it is also possible, in the case of the <strong>Tree</strong> and <strong>Layered</strong> modes, to specify a <code>Subtype</code>.</p><p>For the <strong>Tree</strong> mode you can use the following values: <code>Down</code>, <code>Left</code>, <code>MindMapHorizontal</code>, <code>MindMapVertical</code>, <code>Radial</code>, <code>Right</code>, <code>TipOver</code> and <code>Up</code>.</p><p>For the <strong>Layered</strong> mode you can use the following values: <code>Down</code>, <code>Left</code>, <code>Right</code> and <code>Up</code>. An example of assigning the <code>Subtype</code> can be seen below:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramLayout</span> <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@DiagramLayoutType.Layered<span class="token punctuation">"</span></span>  <span class="token attr-name">Subtype</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>DiagramLayoutSubtype.Up<span class="token punctuation">"</span></span><span class="token punctuation">/&gt;</span></span>
</code></pre><p>In the following images I show an example of each layout type being rendered:</p><h3>Tree Layout Sample</h3><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/tree-layout-example-in-the-diagram-component.png?sfvrsn=b5add55a_2" alt="Tree Layout example in the Diagram component" /></p><h3>Layered Layout Sample</h3><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/layered-layout-example-in-the-diagram-component.png?sfvrsn=62619ad5_2" alt="Layered Layout example in the Diagram component" /></p><h3>Force Layout Sample</h3><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/force-layout-example-in-the-diagram-component.gif?sfvrsn=627cf579_2" alt="Force Layout example in the Diagram component" /></p><h2 id="adding-text-to-diagram-elements">Adding Text to Diagram Elements</h2><p>Another thing you&rsquo;ll likely want to do when working with diagrams is use text in your diagrams. Let&rsquo;s start by adding text to shapes. We can do this using the tag <code>DiagramShapeContent</code>, assigning the parameter <code>Text</code>, as shown below:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape1<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShapeContent</span> <span class="token attr-name">Text</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Shape with text<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramShape</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>The above will add text inside the shape to display it. We also have the shape <code>Text</code>, which has no border or background and occupies minimal space, and we must also use a <code>DiagramShapeContent</code> to define the text:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShape</span> <span class="token attr-name">Id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape2<span class="token punctuation">"</span></span> <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>DiagramShapeType.Text<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramShapeContent</span> <span class="token attr-name">Text</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Text Node<span class="token punctuation">"</span></span> <span class="token attr-name">Color</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>black<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramShape</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>In addition to text on shapes, it&rsquo;s also possible to add text on connections through the tag <code>DiagramConnectionContent</code>:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnection</span> <span class="token attr-name">FromId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape1<span class="token punctuation">"</span></span> <span class="token attr-name">ToId</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>shape2<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>DiagramConnectionContent</span> <span class="token attr-name">Text</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>1 to 2<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>DiagramConnection</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>The result of the previous examples gives us the following output:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/diagram-component-rendering-text-on-shapes-and-connections.png?sfvrsn=e49f6fcb_2" alt="Diagram component rendering text on shapes and connections" /></p><p>These customization options are undoubtedly very useful when creating diagram-based applications.</p><h2 id="conclusion">Conclusion</h2><p>Throughout this article you discovered the Diagram component for Telerik Blazor, which you have seen offers many customization options and flexibility to adapt it to your needs.</p><p>In this article, I covered the main features of the component, but you also have advanced customization options such as the <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/diagram/overview#define-shapes-and-connections-in-json">definition of shapes and connections in JSON</a>, adding styles for <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/diagram/shapes#styling">shapes</a> and <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/diagram/connections#styling">connections</a>, as well as more complex customization through the use of <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/components/diagram/shapes#visual-function">Visual Function</a>.</p><p>I invite you to try the component and explore its full potential in your own Blazor-based applications. Telerik UI for Blazor comes with a free 30-day trial.</p><p><a target="_blank" href="https://www.telerik.com/try/ui-for-blazor" class="Btn">Try Now</a></p><img src="https://feeds.telerik.com/link/23050/17264743.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:3c7bd07b-e3e6-401e-a220-b7d91ae21a5a</id>
    <title type="text">Getting Started with the Blazor Skeleton Component</title>
    <summary type="text">This simple component can improve the user experience of your Blazor app, providing a hint of feedback that they aren’t waiting in vain.</summary>
    <published>2026-01-21T19:07:24Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Héctor Pérez </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17259473/getting-started-blazor-skeleton-component"/>
    <content type="text"><![CDATA[<p><span class="featured">This simple component can improve the user experience of your Blazor app, providing a hint of feedback that they aren&rsquo;t waiting in vain.</span></p><p>Creating smooth experiences in Blazor applications for better interaction should always be a point to consider during their development.</p><p>One of these experiences is the feedback given to the user when processing happens behind the scenes, such as when information is being retrieved to fill a page. One of the components that can help us with this task is the Progress Telerik UI for <a target="_blank" href="https://www.telerik.com/blazor-ui/skeleton">Blazor Skeleton component</a>, which allows you to create loader-like placeholders in the spaces where information will be. Let&rsquo;s look at its features and how to integrate it into a Blazor application.</p><h2 id="exploring-the-skeleton-component-for-blazor">Exploring the Skeleton Component for Blazor</h2><p>Let&rsquo;s start by analyzing how the Skeleton component works. First of all, you need to configure the Blazor project to work with Telerik components, according to the <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/getting-started/web-app">installation guides</a>.</p><p>The next step is to go to the page where you want to use the component, where you can add it via the <code>TelerikSkeleton</code> tag as shown below:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">min-height</span><span class="token punctuation">:</span><span class="token number">100</span>vh<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span>flex<span class="token punctuation">;</span> <span class="token property">align-items</span><span class="token punctuation">:</span>center<span class="token punctuation">;</span> <span class="token property">justify-content</span><span class="token punctuation">:</span>center<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">width</span><span class="token punctuation">:</span><span class="token number">240</span>px<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span><span class="token number">48</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>In the code above, I have added some styles to center the component on the page, resulting in the following:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/the-telerik-skeleton-component-for-blazor-displayed-in-its-simplest-form.gif?sfvrsn=46e255ee_2" alt="The Telerik Skeleton component for Blazor, displayed in its simplest form" /></p><p>Now, you should consider that the component has the following parameters that you can use to configure it:</p><ul><li><code>ShapeType</code> (<em>enum</em>): Allows you to select a predefined shape</li><li><code>AnimationType</code> (<em>enum</em>): Allows you to select a predefined animation</li><li><code>Visible</code> (<em>bool</em>): Specifies whether the component should be visible on the page or not</li><li><code>Width</code> (<em>string</em>) and <code>Height</code> (<em>string</em>): Specify the width and height of the component</li><li><code>Class</code> (<em>string</em>): Allows rendering a custom class in the component</li></ul><p>From the previous properties, you can configure <code>ShapeType</code> with the values <code>SkeletonShapeType.Text</code> (by default), <code>SkeletonShapeType.Rectangle</code> and <code>SkeletonShapeType.Circle</code>, as well as <code>AnimationType</code> with the values <code>SkeletonAnimationType.None</code>, <code>SkeletonAnimationType.Pulse</code> (by default) and <code>SkeletonAnimationType.Wave</code>.</p><p>An example of the Skeleton component with these applied properties is as follows:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> 
    <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Circle<span class="token punctuation">"</span></span>
    <span class="token attr-name">AnimationType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonAnimationType.Pulse<span class="token punctuation">"</span></span>
    <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100px<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100px<span class="token punctuation">"</span></span> <span class="token attr-name">Visible</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikSkeleton</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>When visualizing the component, it looks as follows:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/the-skeleton-component-displaying-a-pulsing-circular-animation.gif?sfvrsn=548ff4d6_2" alt="The Skeleton component displaying a pulsing circular animation" /></p><p>Although the control is quite simple to use, its power lies in combining several of these components to recreate interfaces where we want to provide feedback to the user about a loading of information, as we will see next.</p><h2 id="adding-the-skeleton-component-to-a-real-case">Adding the Skeleton Component to a Real Case</h2><p>So far we have seen the features of the Skeleton component. Now, you may be wondering how to integrate it into your application&mdash;that is, how to build an interface using several Skeleton components while data is being loaded, and then show the real data once it has been loaded.</p><p>To make this more realistic, let&rsquo;s assume we have created an application using several Blazor components that simulate a social network. This is the homepage:</p><pre class=" language-xml"><code class="prism  language-xml">@page "/feed"

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>feed-container<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Feed<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">&gt;</span></span>

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>composer card p-3 mb-4<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex align-items-start gap-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikAvatar</span> <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>AvatarType.Text<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span> <span class="token attr-name">Rounded</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Avatar.Rounded.Full<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>HP<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikAvatar</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>flex-grow-1<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikTextArea</span> <span class="token attr-name">Rows</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>3<span class="token punctuation">"</span></span> <span class="token attr-name">Placeholder</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>What<span class="token punctuation">'</span>s on your mind?<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mt-2 d-flex gap-2 justify-content-end<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikButton</span> <span class="token attr-name">ThemeColor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>primary<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.PaperPlane<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikSvgIcon</span><span class="token punctuation">&gt;</span></span> Post
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikButton</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>feed<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        @foreach (var post in Posts)
        {
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikCard</span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-4<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex align-items-center gap-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikAvatar</span> <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>AvatarType.Text<span class="token punctuation">"</span></span> <span class="token attr-name">Rounded</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Avatar.Rounded.Full<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@GetInitials(post.UserName)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikAvatar</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>flex-grow-1 w-100<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>fw-semibold<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@post.UserName<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>text-muted small<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@post.PostedAt.ToLocalTime().ToString("g")<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardBody</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@post.Content<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
                    @if (!string.IsNullOrWhiteSpace(post.ImageUrl))
                    {
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@post.ImageUrl<span class="token punctuation">"</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>post image<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>img-fluid rounded<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                    }
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardBody</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardFooter</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex gap-2<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikButton</span> <span class="token attr-name">ThemeColor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>primary<span class="token punctuation">"</span></span> <span class="token attr-name">FillMode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Telerik.Blazor.ThemeConstants.Button.FillMode.Outline<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Heart<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikSvgIcon</span><span class="token punctuation">&gt;</span></span> Like
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikButton</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikButton</span> <span class="token attr-name">FillMode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Telerik.Blazor.ThemeConstants.Button.FillMode.Outline<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Comment<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikSvgIcon</span><span class="token punctuation">&gt;</span></span> Comment
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikButton</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikButton</span> <span class="token attr-name">FillMode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Telerik.Blazor.ThemeConstants.Button.FillMode.Outline<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Share<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikSvgIcon</span><span class="token punctuation">&gt;</span></span> Share
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikButton</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardFooter</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikCard</span><span class="token punctuation">&gt;</span></span>
        }
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

@code {    

    private List<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Post</span><span class="token punctuation">&gt;</span></span> Posts { get; set; } = new();

    protected override async Task OnInitializedAsync()
    {
        await Task.Delay(5000);
        LoadPosts();        
    }

    private void LoadPosts()
    {
        Posts = new()
        {
            new Post
            {
                Id = Guid.NewGuid(),
                UserName = "Bot Doe",
                Content = "What a great day to try the Telerik UI for Blazor Skeleton. The UX feels great while data loads!",
                ImageUrl = "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?q=80&amp;w=1200&amp;auto=format&amp;fit=crop",
                PostedAt = DateTimeOffset.UtcNow.AddMinutes(-35)
            },
            new Post
            {
                Id = Guid.NewGuid(),
                UserName = "Link",
                Content = ".NET 10 migration done &mdash; everything feels snappier.",
                ImageUrl = null,
                PostedAt = DateTimeOffset.UtcNow.AddHours(-2)
            },
            new Post
            {
                Id = Guid.NewGuid(),
                UserName = "Ada Lovelace",
                Content = "Pro tip: leverage high-level components to speed up demos.",
                ImageUrl = "https://images.unsplash.com/photo-1518837695005-2083093ee35b?q=80&amp;w=1200&amp;auto=format&amp;fit=crop",
                PostedAt = DateTimeOffset.UtcNow.AddDays(-1)
            }
        };
    }

    private static string GetInitials(string name)
    {
        if (string.IsNullOrWhiteSpace(name)) return "?";
        var parts = name.Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries);
        if (parts.Length == 1) return parts[0].Substring(0, Math.Min(1, parts[0].Length)).ToUpperInvariant();
        return (parts[0][0].ToString() + parts[^1][0].ToString()).ToUpperInvariant();
    }

    private sealed class Post
    {
        public Guid Id { get; set; }
        public string UserName { get; set; } = string.Empty;
        public string Content { get; set; } = string.Empty;
        public string? ImageUrl { get; set; }
        public DateTimeOffset PostedAt { get; set; }
    }
}

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">&gt;</span></span><span class="token style language-css">
    <span class="token selector"><span class="token class">.feed-container</span> </span><span class="token punctuation">{</span>
        <span class="token property">max-width</span><span class="token punctuation">:</span> <span class="token number">820</span>px<span class="token punctuation">;</span>
        <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span> auto<span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">1</span>rem<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.card</span> </span><span class="token punctuation">{</span>
        <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--kendo-box-shadow, <span class="token number">0</span> <span class="token number">1</span>px <span class="token number">3</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">0</span>,<span class="token number">0</span>,<span class="token number">0</span>,<span class="token number">0.08</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span>px solid <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">0</span>,<span class="token number">0</span>,<span class="token number">0</span>,<span class="token number">0.06</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">.5</span>rem<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.composer</span> <span class="token class">.k-textarea</span> </span><span class="token punctuation">{</span>
        <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">100%</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.feed</span> img </span><span class="token punctuation">{</span>
        <span class="token property">max-height</span><span class="token punctuation">:</span> <span class="token number">420</span>px<span class="token punctuation">;</span>
        <span class="token property">object-fit</span><span class="token punctuation">:</span> cover<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.gap-2</span> </span><span class="token punctuation">{</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">.5</span>rem<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token selector"><span class="token class">.gap-3</span> </span><span class="token punctuation">{</span>
        <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token number">1</span>rem<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>If we run the application right now, you can see that we have a poor user experience, as it does not provide feedback that it is trying to fetch information to fill the UI, and you have to wait until the loading is finished to see something on the screen:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/app-poor-user-interface.gif?sfvrsn=65d26963_4" alt="The application is running with a poor user interface, as it fails to inform the user in the UI that data is being fetched" /></p><p>Let&rsquo;s solve this issue by adding the Skeleton component. What you need to do is try to create a copy of the final graphical interface, but replacing each control with the Skeleton component in a suitable shape corresponding to the final component.</p><p>For example, a circular shape could be used for the profile picture, a rectangular shape for photographs, and leave the default shape for the text. The following is an example of this replacement in the header of the component <code>CardHeader</code>:</p><p><strong>Component <code>CardHeader</code> with the final components rendered</strong></p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex align-items-center gap-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikAvatar</span> <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>AvatarType.Text<span class="token punctuation">"</span></span> <span class="token attr-name">Rounded</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Avatar.Rounded.Full<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@GetInitials(post.UserName)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikAvatar</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>fw-semibold<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@post.UserName<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>text-muted small<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@post.PostedAt.ToLocalTime().ToString("g")<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
</code></pre><p><strong>Component <code>CardHeader</code> using components <code>TelerikSkeleton</code> that will show the loading effect</strong></p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex align-items-center gap-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Circle<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>flex-grow-1 w-100<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Text<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>35%<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>18px<span class="token punctuation">"</span></span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-1<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Text<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>20%<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>14px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>In the previous code, I want you to notice that each type of element has been replaced by the appropriate shape of the Skeleton. In this specific example, I was able to reuse the same containers <code>div</code> to hold the Skeleton components, but if you need to, you can change them to work better for you.</p><p>Following this same logic, I am going to create and use a property called <code>IsLoading</code>. This property will allow me to control when to show and hide the loading sections through the creation of a conditional if. In this conditional, we can validate if the loading of the information has concluded, which, if positive, will show the components with information as follows:</p><pre class=" language-xml"><code class="prism  language-xml">@page "/feed"

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>feed-container<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Feed<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">&gt;</span></span>

    ...
    
    @if (IsLoading)
    {
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>feed<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            @for (int i = 0; i &lt; 3; i++)
            {
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikCard</span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-4<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex align-items-center gap-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Circle<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>flex-grow-1 w-100<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Text<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>35%<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>18px<span class="token punctuation">"</span></span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-1<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Text<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>20%<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>14px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardBody</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Text<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>14px<span class="token punctuation">"</span></span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-1<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Text<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>90%<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>14px<span class="token punctuation">"</span></span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-1<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Text<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>80%<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>14px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Rectangle<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>220px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardBody</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardFooter</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex gap-2<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Rectangle<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>80px<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>32px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSkeleton</span> <span class="token attr-name">ShapeType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>SkeletonShapeType.Rectangle<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>90px<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>32px<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>                            
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardFooter</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikCard</span><span class="token punctuation">&gt;</span></span>
            }
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    }
    else
    {
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>feed<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            @foreach (var post in Posts)
            {
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikCard</span> <span class="token attr-name">Class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-4<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex align-items-center gap-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikAvatar</span> <span class="token attr-name">Type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>AvatarType.Text<span class="token punctuation">"</span></span> <span class="token attr-name">Rounded</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Avatar.Rounded.Full<span class="token punctuation">"</span></span> <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span> <span class="token attr-name">Height</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>48px<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@GetInitials(post.UserName)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikAvatar</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>fw-semibold<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@post.UserName<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>text-muted small<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@post.PostedAt.ToLocalTime().ToString("g")<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardHeader</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardBody</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>mb-3<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>@post.Content<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
                        @if (!string.IsNullOrWhiteSpace(post.ImageUrl))
                        {
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@post.ImageUrl<span class="token punctuation">"</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>post image<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>img-fluid rounded<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
                        }
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardBody</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>CardFooter</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>d-flex gap-2<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikButton</span> <span class="token attr-name">ThemeColor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>primary<span class="token punctuation">"</span></span> <span class="token attr-name">FillMode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Telerik.Blazor.ThemeConstants.Button.FillMode.Outline<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Heart<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikSvgIcon</span><span class="token punctuation">&gt;</span></span> Like
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikButton</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikButton</span> <span class="token attr-name">FillMode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Telerik.Blazor.ThemeConstants.Button.FillMode.Outline<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Comment<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikSvgIcon</span><span class="token punctuation">&gt;</span></span> Comment
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikButton</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikButton</span> <span class="token attr-name">FillMode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Telerik.Blazor.ThemeConstants.Button.FillMode.Outline<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikSvgIcon</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.Share<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikSvgIcon</span><span class="token punctuation">&gt;</span></span> Share
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikButton</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>CardFooter</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikCard</span><span class="token punctuation">&gt;</span></span>
            }
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    }
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

@code {    
    private bool IsLoading { get; set; } = true;
    ...

    protected override async Task OnInitializedAsync()
    {        
        ...
        IsLoading = false;
    }
}
</code></pre><p>In the previous code, you can see that once the loading of information in the method <code>OnInitializedAsync</code> is completed, the value <code>false</code> is assigned to <code>IsLoading</code>, which causes the controls with the final information to be rendered. Also, note that when showing the interface using the Skeleton components, only three items are displayed. The result of the execution is as follows:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2026/2026-01/using-the-skeleton-component-in-blazor-to-enhance-user-feedback-during-data-loading-in-the-ui.gif?sfvrsn=dd6acf6b_2" alt="Using the Skeleton component in Blazor to enhance user feedback during data loading in the UI" /></p><p>With this, you have been able to see how the loading of data in the graphical interface has been incredibly improved.</p><h2 id="conclusion">Conclusion</h2><p>In this article, you have been able to learn what the Skeleton control for Blazor from Telerik is and how to use it, which is very useful for providing feedback to the user about a process that involves obtaining information to display in the graphical interface. You have seen its different configuration options, as well as an example in a Blazor app where we implemented the component.</p><p>Now it&rsquo;s your turn to enhance the user experience in your applications by implementing the Skeleton component.</p><p>The whole <a target="_blank" href="https://www.telerik.com/blazor-ui">Telerik UI for Blazor UI library</a> is available to test in a 30-day free trial.</p><p><a target="_blank" href="https://www.telerik.com/try/ui-for-blazor" class="Btn">Try Now</a></p><img src="https://feeds.telerik.com/link/23050/17259473.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:80b35912-c8e5-41c4-a33a-1e9f65e8b660</id>
    <title type="text">Getting Started with the Blazor Inline AI Prompt Component</title>
    <summary type="text">Explore the Blazor Inline AI Prompt component, which allows for easy querying of AI models without interrupting user workflows.</summary>
    <published>2026-01-12T16:56:50Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Héctor Pérez </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17251839/getting-started-blazor-inline-ai-prompt-component"/>
    <content type="text"><![CDATA[<p><span class="featured">Explore the Blazor Inline AI Prompt component, which allows for easy querying of AI models without interrupting user workflows.</span></p><p>The idea of equipping our Blazor applications with artificial intelligence is tempting; however, we must consider ways to prevent the user from interrupting their workflow.</p><p>Fortunately, Progress Telerik UI for Blazor includes the <a target="_blank" href="https://www.telerik.com/blazor-ui/inline-ai-prompt"><strong>Inline AI Prompt</strong></a> component in its suite of <a target="_blank" href="https://www.telerik.com/blazor-ui">Blazor components</a>, allowing users to get responses from AI models without having to jump between tabs or applications. Let&rsquo;s see how it works below.</p><h2 id="initial-project-setup">Initial Project Setup</h2><p>Let&rsquo;s start from the premise that we want to create a scientific article reader, which is very likely to contain terms we don&rsquo;t know, paragraphs or information from which we want to obtain additional information or other types of data, all without the user having to leave the reader. This is an excellent use case for the new AI Prompt Component.</p><p>To use the AI Prompt Component from Telerik in your Blazor project, you first need to perform a proper installation and setup as shown in the <a target="_blank" href="https://www.telerik.com/blazor-ui/documentation/getting-started/web-app">installation guides</a>.</p><p>Next, I&rsquo;ve created a new page type component that simulates the scientific article reader, as I show you below:</p><pre class=" language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token hexcode">#f5f5f5</span><span class="token punctuation">;</span> <span class="token property">min-height</span><span class="token punctuation">:</span> <span class="token number">100</span>vh<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">40</span>px <span class="token number">20</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">max-width</span><span class="token punctuation">:</span> <span class="token number">850</span>px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span> auto<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> white<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">60</span>px <span class="token number">80</span>px<span class="token punctuation">;</span> <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token number">0</span> <span class="token number">2</span>px <span class="token number">8</span>px <span class="token function">rgba</span><span class="token punctuation">(</span><span class="token number">0</span>,<span class="token number">0</span>,<span class="token number">0</span>,<span class="token number">0.1</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>

        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">40</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Quantum Entanglement and Its Implications for Future Computing<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span>

        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token number">30</span>px<span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Abstract<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">text-align</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.6</span><span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            This groundbreaking study explores the fundamental principles of quantum entanglement and its potential
            applications in developing next-generation quantum computers. Through extensive experimental analysis and
            theoretical modeling, we demonstrate novel approaches to maintaining quantum coherence at room temperature.
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>

        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token number">30</span>px<span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Introduction<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">text-align</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.6</span><span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            Quantum entanglement, first described by Einstein, Podolsky, and Rosen in their famous 1935 paper,
            remains one of the most fascinating and counterintuitive phenomena in quantum mechanics. When particles
            become entangled, they form a unified quantum system where the quantum state of each particle cannot be
            described independently, regardless of the distance separating them.
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">text-align</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.6</span><span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            Recent advances in quantum technology have brought us closer to harnessing this phenomenon for practical
            applications, particularly in the field of quantum computing. However, significant challenges remain in
            maintaining quantum states long enough to perform useful computations.
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>

        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token number">30</span>px<span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Theoretical Background<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">text-align</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.6</span><span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            The mathematical framework underlying quantum entanglement is rooted in the superposition principle and
            the concept of quantum correlations. Unlike classical systems, where correlations arise from shared
            initial conditions, quantum correlations emerge from the inherent non-local nature of quantum mechanics.
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">text-align</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.6</span><span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            Our research builds upon the pioneering work of John Bell, whose inequalities provided a testable
            distinction between quantum mechanical predictions and those of local hidden variable theories. Through
            careful experimental design, we have achieved violation of Bell inequalities with unprecedented statistical
            significance, confirming the quantum nature of our entangled systems.
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>

        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token number">30</span>px<span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Experimental Methods<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">text-align</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.6</span><span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            Our experimental setup utilizes spontaneous parametric down-conversion (SPDC) to generate pairs of
            entangled photons. The source crystal, a periodically poled potassium titanyl phosphate (PPKTP), is
            pumped by a continuous-wave laser at 405 nm, producing entangled photon pairs at 810 nm.
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">text-align</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.6</span><span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            Temperature stabilization proved crucial to our success. By implementing a novel active feedback system,
            we maintained the crystal temperature within 10 millikelvins of the target temperature, significantly
            reducing thermal decoherence effects.
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>

        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token number">30</span>px<span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Results and Discussion<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">text-align</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.6</span><span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            Our measurements revealed entanglement fidelities exceeding 99.2%, representing a significant improvement
            over previous room-temperature implementations. The coherence times achieved in our system reached
            450 nanoseconds, sufficient for executing multiple quantum gate operations.
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">text-align</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.6</span><span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            These results demonstrate the viability of room-temperature quantum computing platforms for specific
            applications, particularly in quantum communication and quantum sensing. While universal quantum computing
            may still require cryogenic cooling, our findings open new possibilities for practical quantum devices.
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>

        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token number">30</span>px<span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>Conclusions<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">text-align</span><span class="token punctuation">:</span> justify<span class="token punctuation">;</span> <span class="token property">line-height</span><span class="token punctuation">:</span> <span class="token number">1.6</span><span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            This research establishes new benchmarks for room-temperature quantum entanglement and provides a roadmap
            for developing practical quantum computing devices. Future work will focus on scaling these techniques to
            multi-qubit systems and exploring novel error correction strategies.
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>The result of executing the component is as follows:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2025/2025-12/web-page-that-simulates-a-scientific-article-reader.png?sfvrsn=a970ae2a_2" alt="Web page that simulates a scientific article reader" /></p><p>With this new component ready, we can start testing the Blazor AI Prompt component.</p><h2 id="integrating-the-ai-prompt-component-into-the-project">Integrating the AI Prompt Component into the Project</h2><p>You should know that the Inline AI Prompt component is not a visual component that appears all the time in the graphical interface, so we need to configure some of its parameters to work with it correctly.</p><p>What you need to do is define the control through the <code>TelerikInlineAIPrompt</code> tag with some properties:</p><ul><li><code>@ref</code>: To obtain the instance of the component and display it at will</li><li><code>@bind-Prompt</code>: The bound property where the prompt written by the user will be stored</li><li><code>OnPromptRequest</code>: Event callback that is triggered when the user makes the request.</li><li><code>PromptContext</code>: Additional context that is passed with the prompt</li></ul><p>An implementation example with the previous properties is the following code:</p><pre class=" language-xml"><code class="prism  language-xml">@page "/"

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">...</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikInlineAIPrompt</span> <span class="token attr-name">@ref</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@InlinePromptRef<span class="token punctuation">"</span></span>
                       <span class="token attr-name">@bind-Prompt</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@UserPrompt<span class="token punctuation">"</span></span>
                       <span class="token attr-name">OnPromptRequest</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@OnPromptRequest<span class="token punctuation">"</span></span>
                       <span class="token attr-name">PromptContext</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@PromptContext<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikInlineAIPrompt</span><span class="token punctuation">&gt;</span></span>

@code {
    private string UserPrompt { get; set; } = string.Empty;
    private string PromptContext { get; set; } = string.Empty;
    private TelerikInlineAIPrompt? InlinePromptRef { get; set; }
    private void OnPromptRequest(InlineAIPromptPromptRequestEventArgs args)
    {
        args.Output = $"AI response for: {PromptContext}";
    }
}
</code></pre><p>As I mentioned earlier, this component does not appear all the time in the graphical interface, so we must have some trigger in the graphical interface to show it. In this example, I will use a <code>TelerikButton</code> floating at the bottom that is displayed all the time, so the user can quickly ask questions:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">...</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">position</span><span class="token punctuation">:</span> fixed<span class="token punctuation">;</span> <span class="token property">bottom</span><span class="token punctuation">:</span> <span class="token number">20</span>px<span class="token punctuation">;</span> <span class="token property">right</span><span class="token punctuation">:</span> <span class="token number">20</span>px<span class="token punctuation">;</span> <span class="token property">z-index</span><span class="token punctuation">:</span> <span class="token number">1000</span><span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikButton</span> <span class="token attr-name">Icon</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@SvgIcon.QuestionCircle<span class="token punctuation">"</span></span>
                   <span class="token attr-name">FillMode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Button.FillMode.Solid<span class="token punctuation">"</span></span>
                   <span class="token attr-name">ThemeColor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Button.ThemeColor.Primary<span class="token punctuation">"</span></span>
                   <span class="token attr-name">Size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Button.Size.Large<span class="token punctuation">"</span></span>
                   <span class="token attr-name">Rounded</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@ThemeConstants.Button.Rounded.Full<span class="token punctuation">"</span></span>
                   <span class="token attr-name">OnClick</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@((MouseEventArgs e) =&gt; ShowPromptAsync(e))<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        Ask the AI about the article
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikButton</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikInlineAIPrompt</span> <span class="token attr-name">...</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikInlineAIPrompt</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>In the preceding code, you can see that I defined the <code>OnClick</code> event that provides an argument of type <code>MouseEventArgs</code>, which we will use to show the Inline AI Prompt at the location of the button. Additionally, it also refers to the event handler called <code>ShowPromptAsync(e)</code>, to which we pass the mouse event arguments and which is defined as follows:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">private</span> <span class="token keyword">async</span> Task <span class="token function">ShowPromptAsync</span><span class="token punctuation">(</span>MouseEventArgs e<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">await</span> InlinePromptRef<span class="token operator">!</span><span class="token punctuation">.</span><span class="token function">ShowAsync</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>ClientX<span class="token punctuation">,</span> e<span class="token punctuation">.</span>ClientY<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>You can see that in the previous code we use the reference of the component, along with the method <code>ShowAsync</code>, which expects the coordinates where the component will be shown and which we obtain thanks to the parameter of type <code>MouseEventArgs</code>. The execution gives us the following result:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2025/2025-12/showing-the-inline-ai-prompt-component-through-a-button.gif?sfvrsn=93e5c3ca_2" alt="Showing the Inline AI Prompt component through a button" /></p><h2 id="improving-the-appearance-of-the-inline-ai-prompt-component">Improving the Appearance of the Inline AI Prompt Component</h2><p>The Blazor Inline Prompt Component has a tag called <code>InlineAIPromptSettings</code>, within which we can specify another tag <code>InlineAIPromptPopupSettings</code> that contains various configuration properties for the popup. Some of these properties are:</p><ul><li><code>AnimationDuration</code>: Defines the duration of the animation when the popup appears.</li><li><code>Width</code> and <code>Height</code>: Allow configuring the width and height of the popup.</li><li><code>MaxWidth</code> and <code>MaxHeight</code>: Define a maximum width and height for the popup.</li><li><code>AnimationType</code>: Specifies the type of animation for the appearance of the popup.</li><li><code>HorizontalCollision</code> and <code>VerticalCollision</code>: Specify what happens when the popup does not fit in the viewport. For example, with <code>Flip</code> the popup flips to the opposite side, while with <code>Fit</code> the popup moves until it is completely visible.</li><li><code>VerticalOffset</code> and <code>HorizontalOffset</code>: Specify a space between the popup and the anchor.</li></ul><p>The following code is an example of the implementation of some of the aforementioned properties:</p><pre class=" language-xml"><code class="prism  language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>TelerikInlineAIPrompt</span> <span class="token attr-name">...</span><span class="token punctuation">&gt;</span></span>    
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>InlineAIPromptSettings</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>InlineAIPromptPopupSettings</span> <span class="token attr-name">AnimationDuration</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>300<span class="token punctuation">"</span></span>                                     
                                     <span class="token attr-name">Width</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>650px<span class="token punctuation">"</span></span>                                     
                                     <span class="token attr-name">AnimationType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@AnimationType.PushLeft<span class="token punctuation">"</span></span>
                                     <span class="token attr-name">HorizontalCollision</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@PopupCollision.Fit<span class="token punctuation">"</span></span>
                                     <span class="token attr-name">VerticalCollision</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@PopupCollision.Fit<span class="token punctuation">"</span></span>
                                     <span class="token attr-name">VerticalOffset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>5<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>InlineAIPromptSettings</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>TelerikInlineAIPrompt</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>The result of the component&rsquo;s configuration can be seen in the following image:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2025/2025-12/improved-inline-ai-prompt-component-thanks-to-its-settings-configuration.gif?sfvrsn=7a724e44_2" alt="Improved Inline AI Prompt component thanks to its settings configuration" /></p><h2 id="defining-commands-for-processing-predefined-prompts">Defining Commands for Processing Predefined Prompts</h2><p>Another feature of the Inline AI Prompt component is that we can configure predefined commands, which are a series of prompts that will be processed immediately. These commands will form a sort of menu in the popup, which even allows for nested commands. To configure them, we must link the <code>Commands</code> parameter to a list of <code>InlineAIPromptCommandDescriptor</code> elements, each having the following configurable parameters:</p><ul><li><code>Id</code>: Identifier of the command</li><li><code>Title</code>: Title that will appear in the commands menu</li><li><code>Icon</code>: Icon that will appear in the commands menu</li><li><code>Prompt</code>: Predefined prompt that will be used with the AI model when the item is pressed</li><li><code>Children</code>: In the case of nested commands, we can use this property to create them</li></ul><p>You can see an example of creating and using commands in the following code:</p><pre class=" language-csharp"><code class="prism  language-csharp">@page <span class="token string">"/"</span>

<span class="token operator">&lt;</span>div <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>

<span class="token operator">&lt;</span>TelerikInlineAIPrompt <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
                       Commands<span class="token operator">=</span><span class="token string">"@Commands"</span>
                       OnCommandExecute<span class="token operator">=</span><span class="token string">"@OnCommandExecute"</span><span class="token operator">&gt;</span>
    <span class="token operator">&lt;</span>InlineAIPromptSettings<span class="token operator">&gt;</span>
        <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    <span class="token operator">&lt;</span><span class="token operator">/</span>InlineAIPromptSettings<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>TelerikInlineAIPrompt<span class="token operator">&gt;</span>

@code <span class="token punctuation">{</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>

    <span class="token keyword">private</span> List<span class="token operator">&lt;</span>InlineAIPromptCommandDescriptor<span class="token operator">&gt;</span> Commands <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">new</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">new</span> <span class="token class-name">InlineAIPromptCommandDescriptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            Id <span class="token operator">=</span> <span class="token string">"summarize"</span><span class="token punctuation">,</span>
            Title <span class="token operator">=</span> <span class="token string">"Summarize Article"</span><span class="token punctuation">,</span>
            Icon <span class="token operator">=</span> SvgIcon<span class="token punctuation">.</span>FreeText<span class="token punctuation">,</span>
            Prompt <span class="token operator">=</span> <span class="token string">"Provide a clear summary of this scientific article, highlighting the main findings and relevance."</span><span class="token punctuation">,</span>
            Children <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>InlineAIPromptCommandDescriptor<span class="token operator">&gt;</span>
            <span class="token punctuation">{</span>
                <span class="token keyword">new</span> <span class="token class-name">InlineAIPromptCommandDescriptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token punctuation">{</span>
                    Id <span class="token operator">=</span> <span class="token string">"summarize-methods"</span><span class="token punctuation">,</span>
                    Title <span class="token operator">=</span> <span class="token string">"Summarize Methods"</span><span class="token punctuation">,</span>
                    Icon <span class="token operator">=</span> SvgIcon<span class="token punctuation">.</span>ListOrdered<span class="token punctuation">,</span>
                    Prompt <span class="token operator">=</span> <span class="token string">"Explain the methods used in this article in a simple way."</span>
                <span class="token punctuation">}</span><span class="token punctuation">,</span>
                <span class="token keyword">new</span> <span class="token class-name">InlineAIPromptCommandDescriptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token punctuation">{</span>
                    Id <span class="token operator">=</span> <span class="token string">"summarize-results"</span><span class="token punctuation">,</span>
                    Title <span class="token operator">=</span> <span class="token string">"Summarize Results"</span><span class="token punctuation">,</span>
                    Icon <span class="token operator">=</span> SvgIcon<span class="token punctuation">.</span>ChartBarRange<span class="token punctuation">,</span>
                    Prompt <span class="token operator">=</span> <span class="token string">"Describe the main results and conclusions of the study in an accessible way."</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token keyword">new</span> <span class="token class-name">InlineAIPromptCommandDescriptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            Id <span class="token operator">=</span> <span class="token string">"explainSimply"</span><span class="token punctuation">,</span>
            Title <span class="token operator">=</span> <span class="token string">"Explain Simply"</span><span class="token punctuation">,</span>
            Icon <span class="token operator">=</span> SvgIcon<span class="token punctuation">.</span>QuestionSolid<span class="token punctuation">,</span>
            Prompt <span class="token operator">=</span> <span class="token string">"Explain the content of this scientific text in simple words, as if you were telling it to a high school student."</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token keyword">new</span> <span class="token class-name">InlineAIPromptCommandDescriptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            Id <span class="token operator">=</span> <span class="token string">"defineTerms"</span><span class="token punctuation">,</span>
            Title <span class="token operator">=</span> <span class="token string">"Define Terms"</span><span class="token punctuation">,</span>
            Icon <span class="token operator">=</span> SvgIcon<span class="token punctuation">.</span>WholeWord<span class="token punctuation">,</span>
            Prompt <span class="token operator">=</span> <span class="token string">"Identify technical or complex terms and provide simple definitions."</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token keyword">new</span> <span class="token class-name">InlineAIPromptCommandDescriptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            Id <span class="token operator">=</span> <span class="token string">"highlightKeyPoints"</span><span class="token punctuation">,</span>
            Title <span class="token operator">=</span> <span class="token string">"Highlight Key Points"</span><span class="token punctuation">,</span>
            Icon <span class="token operator">=</span> SvgIcon<span class="token punctuation">.</span>Star<span class="token punctuation">,</span>
            Prompt <span class="token operator">=</span> <span class="token string">"List the most important points of this scientific text in easy-to-read bullet points."</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token keyword">new</span> <span class="token class-name">InlineAIPromptCommandDescriptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            Id <span class="token operator">=</span> <span class="token string">"practicalImplications"</span><span class="token punctuation">,</span>
            Title <span class="token operator">=</span> <span class="token string">"Practical Implications"</span><span class="token punctuation">,</span>
            Icon <span class="token operator">=</span> SvgIcon<span class="token punctuation">.</span>User<span class="token punctuation">,</span>
            Prompt <span class="token operator">=</span> <span class="token string">"Explain how the findings of this article can be applied in real life or in the professional field."</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>

    <span class="token keyword">private</span> <span class="token keyword">async</span> Task <span class="token function">OnCommandExecute</span><span class="token punctuation">(</span>InlineAIPromptCommandExecuteEventArgs args<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">await</span> Task<span class="token punctuation">.</span><span class="token function">Delay</span><span class="token punctuation">(</span><span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        args<span class="token punctuation">.</span>Output <span class="token operator">=</span> $<span class="token string">"AI-generated content for: {args.Command.Title} ({PromptContext})"</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>When running the application with the added commands, you can see them in action in the following image:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2025/2025-12/predefined-prompt-commands-displayed-in-the-inline-ai-prompt-as-a-menu.gif?sfvrsn=7af8adc2_2" alt="Predefined prompt commands displayed in the Inline AI Prompt as a menu" /></p><h2 id="integrating-ai-services-for-use-with-the-inline-ai-prompt">Integrating AI Services for Use with the Inline AI Prompt</h2><p>So far, we have analyzed different options of the Inline AI Prompt control without using any AI model. You should know that you can use any model from any provider that interests you in your application. In my case, I will use <code>Microsoft.Extensions.AI</code>, in addition to <code>Azure OpenAI</code>, carrying out its <a target="_blank" href="https://www.telerik.com/blogs/getting-started-blazor-ai-prompt-component#adding-an-ai-model-to-the-blazor-project-for-use-with-aiprompt">respective configuration</a>.</p><p>Once this is done, in the component, I will create a method that allows me to easily obtain a response from the AI model:</p><pre class=" language-csharp"><code class="prism  language-csharp">@page <span class="token string">"/"</span>
@<span class="token keyword">using</span> Microsoft<span class="token punctuation">.</span>Extensions<span class="token punctuation">.</span>AI
@inject IChatClient ChatClient
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token keyword">private</span> <span class="token keyword">async</span> Task<span class="token operator">&lt;</span><span class="token keyword">string</span><span class="token operator">&gt;</span> <span class="token function">CallOpenAIApi</span><span class="token punctuation">(</span><span class="token keyword">string</span> message<span class="token punctuation">,</span> <span class="token keyword">string</span> context <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">var</span> options <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ChatOptions</span>
    <span class="token punctuation">{</span>
        Instructions <span class="token operator">=</span> $<span class="token string">"The following is the context: {context}"</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>

    <span class="token keyword">var</span> answer <span class="token operator">=</span> <span class="token keyword">await</span> ChatClient<span class="token punctuation">.</span><span class="token function">GetResponseAsync</span><span class="token punctuation">(</span>message<span class="token punctuation">,</span> options<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">return</span> answer<span class="token punctuation">.</span>Text<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>In the previous method, I define the parameter to receive a message and an optional parameter to receive context. Now, I will modify the <code>OnPromptRequest</code> method to process any user request:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">private</span> <span class="token keyword">async</span> Task <span class="token function">OnPromptRequest</span><span class="token punctuation">(</span>InlineAIPromptPromptRequestEventArgs args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">var</span> answer <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">CallOpenAIApi</span><span class="token punctuation">(</span>UserPrompt<span class="token punctuation">)</span><span class="token punctuation">;</span>
    args<span class="token punctuation">.</span>Output <span class="token operator">=</span> $<span class="token string">"{answer}"</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>Once the above modifications are made, we can make queries to the AI model, as seen in the following example:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2025/2025-12/querying-an-ai-model-via-the-inline-ai-prompt-component.gif?sfvrsn=50e4f6c2_2" alt="Querying an AI model via the Inline AI Prompt component" /></p><p>Although the component is already functional, the truth is that it is not very useful at the moment since we cannot quickly add article context to ask questions or execute a command.</p><p>To solve this, as part of our application, I will implement a feature so that the selected text from the article is copied to the component&rsquo;s context. I will do this by creating within <code>wwwroot</code> a file called <code>site.js</code>, which looks like this:</p><pre class=" language-js"><code class="prism  language-js">window<span class="token punctuation">.</span><span class="token function-variable function">getSelectedText</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> selection <span class="token operator">=</span> window<span class="token punctuation">.</span><span class="token function">getSelection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> selection <span class="token operator">?</span> selection<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token string">''</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre><p>This new file needs to be registered in <code>App.razor</code> as follows:</p><pre class=" language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">&gt;</span></span>
    ...
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>_framework/blazor.web.js<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token script language-javascript"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>site.js<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token script language-javascript"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>With these changes, we can use <a href="https://www.telerik.com/blogs/blazor-basics-blazor-javascript-interop-calling-javascript-net" target="_blank">JS interoperability</a> to obtain the selected text and quickly add it as context using <code>PromptContext</code>, which we will do every time we open the popup, in the <code>ShowPromptAsync</code> method:</p><pre class=" language-csharp"><code class="prism  language-csharp">@inject IJSRuntime JS
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token keyword">private</span> <span class="token keyword">async</span> Task <span class="token function">ShowPromptAsync</span><span class="token punctuation">(</span>MouseEventArgs e<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">string</span> selectedText <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span>
    <span class="token keyword">try</span>
    <span class="token punctuation">{</span>
        selectedText <span class="token operator">=</span> <span class="token keyword">await</span> JS<span class="token punctuation">.</span><span class="token generic-method function">InvokeAsync<span class="token punctuation">&lt;</span><span class="token keyword">string</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token string">"getSelectedText"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> ex<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>$<span class="token string">"Error copying to clipboard: {ex.Message}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    PromptContext <span class="token operator">=</span> $<span class="token string">"{selectedText}"</span><span class="token punctuation">;</span>
    <span class="token keyword">await</span> InlinePromptRef<span class="token operator">!</span><span class="token punctuation">.</span><span class="token function">ShowAsync</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>ClientX<span class="token punctuation">,</span> e<span class="token punctuation">.</span>ClientY<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>With the above code implemented, we will pass the newly assigned context to the <code>OnPromptRequest</code> method as follows:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">private</span> <span class="token keyword">async</span> Task <span class="token function">OnPromptRequest</span><span class="token punctuation">(</span>InlineAIPromptPromptRequestEventArgs args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">var</span> answer <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">CallOpenAIApi</span><span class="token punctuation">(</span>UserPrompt<span class="token punctuation">,</span> PromptContext<span class="token punctuation">)</span><span class="token punctuation">;</span>
    args<span class="token punctuation">.</span>Output <span class="token operator">=</span> $<span class="token string">"{answer}"</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>With the previous changes, we can see that after making a selection, it is possible to ask the AI model about the selected text easily:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2025/2025-12/selected-text-used-as-context-to-ask-the-ai-model-questions.gif?sfvrsn=17682031_2" alt="Selected text used as context to ask the AI model questions" /></p><p>Finally, we can carry out a similar approach for when a command is executed, except in this case, we will not use <code>UserPrompt</code> but the command prompt:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">private</span> <span class="token keyword">async</span> Task <span class="token function">OnCommandExecute</span><span class="token punctuation">(</span>InlineAIPromptCommandExecuteEventArgs args<span class="token punctuation">)</span>
<span class="token punctuation">{</span>        
    <span class="token keyword">var</span> answer <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">CallOpenAIApi</span><span class="token punctuation">(</span>args<span class="token punctuation">.</span>Command<span class="token punctuation">.</span>Prompt<span class="token punctuation">,</span> PromptContext<span class="token punctuation">)</span><span class="token punctuation">;</span>
    args<span class="token punctuation">.</span>Output <span class="token operator">=</span> $<span class="token string">"{answer}"</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>The result is that we can quickly select a section of text and execute a command, as seen below:</p><p><img src="https://d585tldpucybw.cloudfront.net/sfimages/default-source/blogs/2025/2025-12/executing-predefined-commands-through-the-ai-model.gif?sfvrsn=118597b7_2" alt="Executing predefined commands through the AI model" /></p><p>And there you have it, with this we have implemented an easy and quick way for users to make queries in a complex article, thanks to the Telerik Blazor Inline AI Prompt component.</p><h2 id="conclusion">Conclusion</h2><p>Throughout this article, we have explored the Telerik Inline AI Prompt component, which enables seamless querying of AI models without interrupting users&rsquo; workflows, helping them become more efficient in their tasks. Definitely a component worth exploring if you plan to create AI-based applications.</p><p>Ready to try it for yourself? Telerik UI for Blazor offers a free 30-day trial!</p><p><a target="_blank" href="https://www.telerik.com/try/ui-for-blazor" class="Btn">Get Started</a></p><img src="https://feeds.telerik.com/link/23050/17251839.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:4b642f4c-8518-4d0d-9074-84bea8239577</id>
    <title type="text">Blazor Basics: Should You Migrate to .NET 10?</title>
    <summary type="text">Not only is .NET 10 the next long-term support version, it also delivers improved startup time, state management, JavaScript interop and NotFound handling. In short, YES! It’s worth updating your Blazor app to .NET 10!</summary>
    <published>2026-01-06T18:16:26Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Claudio Bernasconi </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17248144/blazor-basics-should-you-migrate-net-10"/>
    <content type="text"><![CDATA[<p><span class="featured">Not only is .NET 10 the next long-term support version, it also delivers improved startup time, state management, JavaScript interop and NotFound handling. In short, YES! It&rsquo;s worth updating your Blazor app to .NET 10!</span></p><p>In this article, I want to share <strong>what&rsquo;s new in .NET 10 for Blazor development</strong>. You will learn about new features and their impact on everyday web development with Blazor.</p><p>Besides writing articles for the Blazor Basics series on the Progress Telerik blog, I have two Blazor web applications of different sizes in production for my customers.</p><p>If you are still using .NET 8 because of its <strong>long-term support (LTS)</strong> policy, let me convince you to upgrade your apps to .NET 10. It is, after all, the next LTS version that will be supported by Microsoft for three years.</p><h2 id="improved-startup-time-and-lighter-payloads">Improved Startup Time and Lighter Payloads</h2><p>One of the less developer-focused, but no less critical, updates is that the <code>blazor.web.js</code> file is now <strong>pre-compressed</strong> using the <strong>Brotli/gzip</strong> algorithm and fingerprinting.</p><p>The pre-compression reduces the download size for the whole Blazor <em>engine</em> from around <strong>200 KB</strong> to less than <strong>50 KB</strong> per application.</p><p><strong>Note:</strong> Those numbers are not from artificial testing or benchmarking, but from observing real-world applications.</p><p>This reduction in payload size primarily yields faster startup performance and, therefore, a better user experience.&nbsp;All you have to do to take advantage of it is upgrade your application to use .NET 10.</p><p><strong>Who doesn&rsquo;t like free performance gains for their apps?</strong></p><h2 id="improved-state-management-with-the-persistedstate-attribute-blazor-server">Improved State Management with the PersistedState Attribute (Blazor Server)</h2><p>The <code>PersistentComponentState</code> service allows us to persist state during prerendering. Prerendering is a complex topic explained in the <a target="_blank" href="https://www.telerik.com/blogs/blazor-basics-prerendering-server-components-blazor">Blazor Basics: Prerendering Server Components in Blazor</a> article.</p><p>Before .NET 10, we had to write a lot of code to handle state persistence during prerendering properly. It not only includes many lines of code that bloat the application and become hard to maintain, but it is also an error-prone area.</p><p>I have seen developers implementing slightly wrong or completely wrong code when using the <code>PersistentComponentState</code> service.</p><p>Starting with .NET 10, we can use the <code>PersistentState</code> attribute. It allows for a <strong>declarative</strong> (compared to an imperative) way to declare what data should be persisted during prerendering.</p><p>The following example demonstrates that we can now persist the state of the <code>CustomerList</code> property during prerendering by applying the <code>PersistentState</code> attribute.</p><pre class=" language-csharp"><code class="prism  language-csharp">@code <span class="token punctuation">{</span> 
  <span class="token punctuation">[</span>PersistentState<span class="token punctuation">]</span> 
  <span class="token keyword">public</span> List<span class="token operator">&lt;</span>Customers<span class="token operator">&gt;</span><span class="token operator">?</span> CustomerList <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> 

  <span class="token keyword">protected</span> <span class="token keyword">override</span> <span class="token keyword">async</span> Task <span class="token function">OnInitializedAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span> 
  <span class="token punctuation">{</span> 
    CustomerList <span class="token operator">?</span><span class="token operator">?</span><span class="token operator">=</span> <span class="token keyword">await</span> CustomerService<span class="token punctuation">.</span><span class="token function">GetCustomers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 
  <span class="token punctuation">}</span> 
<span class="token punctuation">}</span>
</code></pre><p>You can explore more information, including detailed example code, in the <a target="_blank" href="https://learn.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-10.0?view=aspnetcore-10.0#declarative-model-for-persisting-state-from-components-and-services">official Microsoft documentation on persisting state</a>.</p><h2 id="new-javascript-interop-functionality">New JavaScript Interop Functionality</h2><p>Starting with .NET 10, we can now create an instance of a JavaScript object and provide arguments to the constructor parameters.</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">var</span> personRef <span class="token operator">=</span> <span class="token keyword">await</span> JSRuntime<span class="token punctuation">.</span><span class="token function">InvokeConstructorAsync</span><span class="token punctuation">(</span><span class="token string">"jsInterop.PersonClass"</span><span class="token punctuation">,</span> <span class="token string">"Claudio"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> name <span class="token operator">=</span> <span class="token keyword">await</span> personRef <span class="token punctuation">.</span><span class="token generic-method function">GetValueAsync<span class="token punctuation">&lt;</span><span class="token keyword">string</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 
<span class="token keyword">var</span> nameLength <span class="token operator">=</span> <span class="token keyword">await</span> personRef <span class="token punctuation">.</span><span class="token generic-method function">InvokeAsync<span class="token punctuation">&lt;</span><span class="token keyword">int</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token string">"getNameLength"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>This example code assumes a JavaScript <code>PersonClass</code> class with a <code>name</code> field and a <code>getNameLength</code> function exists.</p><p>Setting values to a property is also possible using the <code>SetValueAsync</code> method.</p><p>If you don&rsquo;t have to use JavaScript interop, you might not be able to tell how much these new APIs will improve the developer experience.</p><p>However, I previously had to make heavy use of JavaScript interop, and I had to work my way around the limitations. The code will definitely become simpler and shorter using these new APIs.</p><h2 id="consistent-notfound-handling-using-navigationmanager">Consistent NotFound Handling Using NavigationManager</h2><p>The <code>NotFound</code> property of the <code>Router</code> (found in <code>Routes.razor</code>) component allows us to define what component to render when a route doesn&rsquo;t match any registered page components.</p><p>However, until .NET 10, there was no simple way to handle the case where a route matches a page, but the application logic determines that no resource exists at that route.</p><p><strong>Consider the following example:</strong></p><p>Let&rsquo;s say we have a customers page that lists all our customers. The user can click on the name of the customer to load a detail page about the customer containing information such as open invoices and their purchase history.</p><p>Let&rsquo;s say there is a broken link in the application, or the user puts a random <code>id</code> into the browser&rsquo;s address. Blazor will find and render the correct customer details page. However, we will not be able to find the customer in the database.</p><p>Up to .NET 9, we may have handled that case using the following code:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">protected</span> <span class="token keyword">override</span> <span class="token keyword">void</span> <span class="token function">OnInitialized</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  CustomerItem <span class="token operator">=</span> CustomerService<span class="token punctuation">.</span><span class="token function">GetCustomer</span><span class="token punctuation">(</span>CustomerId<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">if</span> <span class="token punctuation">(</span>CustomerItem <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span>
  <span class="token punctuation">{</span>
    NavigationManager<span class="token punctuation">.</span><span class="token function">NavigateTo</span><span class="token punctuation">(</span><span class="token string">"/not-found"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>We have to <strong>manually</strong> redirect to the error page. There are two main flaws with this approach:</p><ol><li>We need to manually reroute to a different page. We have to provide the name of the page or use a predefined constant.</li><li>The HTTP status code is 200. This is mainly an issue for SEO or caching when using Blazor SSR. However, it&rsquo;s still not best practice to provide an HTTP code 200 when it should be 404.</li></ol><p>Starting with .NET 10, there is a new <code>NotFound</code> method on the <code>NavigationManager</code> class.</p><p>We can use the following code:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">protected</span> <span class="token keyword">override</span> <span class="token keyword">void</span> <span class="token function">OnInitialized</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  CustomerItem <span class="token operator">=</span> CustomerService<span class="token punctuation">.</span><span class="token function">GetCustomer</span><span class="token punctuation">(</span>CustomerId<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">if</span> <span class="token punctuation">(</span>CustomerItem <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span>
  <span class="token punctuation">{</span>
    NavigationManager<span class="token punctuation">.</span><span class="token function">NotFound</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>Calling the <code>NotFound</code> method on the <code>NavigationManager</code> fixed both problems described above.</p><p>The user will be redirected to the general <code>NotFound</code> error page (see <code>NotFound.razor</code> in projects generated using the .NET 10 project templates). And it will correctly set <strong>404</strong> as the HTTP Status code for the request.</p><p>The best part is that we can now use this identical method for Static Server-Rendered Pages, Streaming SSR, Blazor Server and Blazor WebAssembly interactivity.</p><p>You can <a target="_blank" href="https://github.com/claudiobernasconi/BlazorNavigationManagerNotFound">access the code of the working example on GitHub</a>.</p><h2 id="conclusion">Conclusion</h2><p>The features and improvements mentioned in this article have the most significant impact on everyday Blazor web development. At least, they have a positive impact on my real-world applications running in my clients&rsquo; businesses.</p><p>With the new <strong>JavaScript interop</strong> methods, I write less and more efficient interop code.</p><p>With the <code>PersistentState</code> attribute, handling state persistence using <strong>component prerendering in Blazor Server</strong> is finally understandable without being an expert Blazor developer.</p><p>And the <code>NotFound</code> method on the <code>NavigationManager</code> provides a consistent, correct experience across all <a target="_blank" href="https://www.telerik.com/blogs/blazor-basics-blazor-render-modes-net-8">Blazor rendering modes</a> by implementing proper behavior for resources that do not exist.</p><p><a target="_blank" href="https://learn.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-10.0">There are obviously many more improvements in .NET 10</a>, such as built-in Blazor metrics for ASP.NET Core, tracing of Blazor Server circuits, Blazor WebAssembly memory profiling support and improved Blazor web application project templates.</p><p>Some of them are not limited to Blazor, but improve the developer and user experience across other parts of the ASP.NET Core web framework or even the whole .NET platform. For example, the <a target="_blank" href="https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-10/">general performance improvements from .NET 9 to .NET 10</a>.</p><p>If you made it this far, I hope I have convinced you to start upgrading your Blazor web application from .NET 9 or even .NET 8 to .NET 10. <strong>It&rsquo;s worth it.</strong></p><hr /><p>If you want to learn more about Blazor development, watch my <a target="_blank" href="https://www.youtube.com/playlist?list=PLwISgxnkpZGL_LhTQCWwp-WCzupv7lcp0">free Blazor Crash Course</a> on YouTube. And stay tuned to the Telerik blog for more <a target="_blank" href="https://www.telerik.com/blogs/tag/blazor-basics">Blazor Basics</a>.</p><img src="https://feeds.telerik.com/link/23050/17248144.gif" height="1" width="1"/>]]></content>
  </entry>
  <entry>
    <id>urn:uuid:7e4ca7c4-6c94-43c4-9c4c-d002818c10a6</id>
    <title type="text">What’s New with APIs in .NET 10: Taking a Look at Real Improvements</title>
    <summary type="text">This post walks through .NET 10 and C# 14 updates from the perspective of an API developer using a real-world example: an order management API with validation, OpenAPI docs and Entity Framework Core.</summary>
    <published>2025-12-31T13:29:02Z</published>
    <updated>2026-04-11T21:15:17Z</updated>
    <author>
      <name>Dave Brock </name>
    </author>
    <link rel="alternate" href="https://feeds.telerik.com/link/23050/17244502/whats-new-apis-net-10-real-improvements"/>
    <content type="text"><![CDATA[<p><span class="featured">This post walks through .NET 10 and C# 14 updates from the perspective of an API developer using a real-world example: an order management API with validation, OpenAPI docs and Entity Framework Core.</span></p><p>It&rsquo;s that time of year: A new version of the .NET platform has shipped. .NET 10 <a target="_blank" href="https://devblogs.microsoft.com/dotnet/announcing-dotnet-10/">landed last month</a> as <a target="_blank" href="https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core">an LTS release</a>, with support through November 2028.</p><p>To complement Jon Hilton&rsquo;s <a target="_blank" href="https://www.telerik.com/blogs/net-10-has-arrived-heres-whats-changed-blazor"><em>.NET 10 Has Arrived&mdash;Here&rsquo;s What Changed for Blazor</em></a> article and Assis Zang&rsquo;s <em><a href="https://www.telerik.com/blogs/whats-new-net-10-aspnet-core" target="_blank">What&rsquo;s New in .NET 10 for ASP.NET Core</a></em>, let&rsquo;s look at .NET 10 improvements through the viewpoint of an API developer.</p><p>Throughout this post, we&rsquo;ll walk through updates using a real-world example: an order management API with validation, OpenAPI docs and Entity Framework Core.</p><p><strong>NOTE</strong>: The examples use Minimal APIs for brevity, but most of these improvements can be used for controller-based APIs as well.</p><h2 id="built-in-validation-for-minimal-apis">Built in Validation for Minimal APIs</h2><p>Before .NET 10, teams building Minimal APIs ended up rolling their own validation. The result? Endpoint code that was more about policing inputs than implementing business logic.</p><p>Here&rsquo;s a simplified example that shows the problem.</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">OrderEndpoints</span>
<span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">MapOrderEndpoints</span><span class="token punctuation">(</span><span class="token keyword">this</span> WebApplication app<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">var</span> <span class="token keyword">group</span> <span class="token operator">=</span> app<span class="token punctuation">.</span><span class="token function">MapGroup</span><span class="token punctuation">(</span><span class="token string">"/api/orders"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">group</span><span class="token punctuation">.</span><span class="token function">MapPost</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span> CreateOrder<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">group</span><span class="token punctuation">.</span><span class="token function">MapGet</span><span class="token punctuation">(</span><span class="token string">"/{id}"</span><span class="token punctuation">,</span> GetOrder<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">async</span> Task<span class="token operator">&lt;</span>IResult<span class="token operator">&gt;</span> <span class="token function">CreateOrder</span><span class="token punctuation">(</span>
        CreateOrderRequest request<span class="token punctuation">,</span>
        OrderDbContext db<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrWhiteSpace</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>CustomerEmail<span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token keyword">return</span> Results<span class="token punctuation">.</span><span class="token function">BadRequest</span><span class="token punctuation">(</span><span class="token string">"Customer email is required"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">if</span> <span class="token punctuation">(</span>request<span class="token punctuation">.</span>Items <span class="token keyword">is</span> <span class="token keyword">null</span> <span class="token operator">||</span> request<span class="token punctuation">.</span>Items<span class="token punctuation">.</span>Count <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span>
            <span class="token keyword">return</span> Results<span class="token punctuation">.</span><span class="token function">BadRequest</span><span class="token punctuation">(</span><span class="token string">"Order must contain at least one item"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token keyword">var</span> item <span class="token keyword">in</span> request<span class="token punctuation">.</span>Items<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>item<span class="token punctuation">.</span>Quantity <span class="token operator">&lt;</span> <span class="token number">1</span><span class="token punctuation">)</span>
                <span class="token keyword">return</span> Results<span class="token punctuation">.</span><span class="token function">BadRequest</span><span class="token punctuation">(</span><span class="token string">"Quantity must be at least 1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>item<span class="token punctuation">.</span>ProductId <span class="token operator">&lt;=</span> <span class="token number">0</span><span class="token punctuation">)</span>
                <span class="token keyword">return</span> Results<span class="token punctuation">.</span><span class="token function">BadRequest</span><span class="token punctuation">(</span><span class="token string">"Invalid product ID"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token keyword">var</span> order <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Order</span>
        <span class="token punctuation">{</span>
            CustomerEmail <span class="token operator">=</span> request<span class="token punctuation">.</span>CustomerEmail<span class="token punctuation">,</span>
            Items <span class="token operator">=</span> request<span class="token punctuation">.</span>Items<span class="token punctuation">.</span><span class="token function">Select</span><span class="token punctuation">(</span>i <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token keyword">new</span> <span class="token class-name">OrderItem</span>
            <span class="token punctuation">{</span>
                ProductId <span class="token operator">=</span> i<span class="token punctuation">.</span>ProductId<span class="token punctuation">,</span>
                Quantity <span class="token operator">=</span> i<span class="token punctuation">.</span>Quantity
            <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ToList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            CreatedAt <span class="token operator">=</span> DateTime<span class="token punctuation">.</span>UtcNow
        <span class="token punctuation">}</span><span class="token punctuation">;</span>

        db<span class="token punctuation">.</span>Orders<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>order<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">await</span> db<span class="token punctuation">.</span><span class="token function">SaveChangesAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">return</span> Results<span class="token punctuation">.</span><span class="token function">Created</span><span class="token punctuation">(</span>$<span class="token string">"/api/orders/{order.Id}"</span><span class="token punctuation">,</span> order<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">async</span> Task<span class="token operator">&lt;</span>IResult<span class="token operator">&gt;</span> <span class="token function">GetOrder</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">,</span> OrderDbContext db<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">var</span> order <span class="token operator">=</span> <span class="token keyword">await</span> db<span class="token punctuation">.</span>Orders<span class="token punctuation">.</span><span class="token function">FindAsync</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> order <span class="token keyword">is</span> <span class="token keyword">null</span> <span class="token operator">?</span> Results<span class="token punctuation">.</span><span class="token function">NotFound</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> Results<span class="token punctuation">.</span><span class="token function">Ok</span><span class="token punctuation">(</span>order<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>There were ways around this: you could use filters, helper methods or third-party validators. Even so, it was frustrating that Minimal APIs didn&rsquo;t have the baked-in validation experience you have with controller-based APIs.</p><p>.NET 10 adds built-in validation support for Minimal APIs. You can enable it with one registration call:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">var</span> builder <span class="token operator">=</span> WebApplication<span class="token punctuation">.</span><span class="token function">CreateBuilder</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>

builder<span class="token punctuation">.</span>Services<span class="token punctuation">.</span><span class="token generic-method function">AddDbContext<span class="token punctuation">&lt;</span>OrderDbContext<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// Enables built-in validation for Minimal APIs</span>
builder<span class="token punctuation">.</span>Services<span class="token punctuation">.</span><span class="token function">AddValidation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">var</span> app <span class="token operator">=</span> builder<span class="token punctuation">.</span><span class="token function">Build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>Once enabled, ASP.NET Core automatically applies <code>DataAnnotations</code> validation to Minimal API parameters. This includes query, header and request body binding.</p><p>You can also disable validation for a specific endpoint using <code>DisableValidation()</code>, which is handy for internal endpoints or partial updates where you intentionally accept incomplete payloads.</p><p>With validation handled by the framework and the attributes added to our models, endpoints can focus on business logic.</p><h3 id="validation-error-responses">Validation Error Responses</h3><p>When validation fails, ASP.NET Core returns a standardized <code>ProblemDetails</code> response with an <code>errors</code> dictionary.</p><p>A typical response looks like this.</p><pre class=" language-json"><code class="prism  language-json"><span class="token punctuation">{</span>
  <span class="token string">"type"</span><span class="token punctuation">:</span> <span class="token string">"https://tools.ietf.org/html/rfc9110#section-15.5.1"</span><span class="token punctuation">,</span>
  <span class="token string">"title"</span><span class="token punctuation">:</span> <span class="token string">"One or more validation errors occurred."</span><span class="token punctuation">,</span>
  <span class="token string">"status"</span><span class="token punctuation">:</span> <span class="token number">400</span><span class="token punctuation">,</span>
  <span class="token string">"errors"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span>
    <span class="token string">"CustomerEmail"</span><span class="token punctuation">:</span> <span class="token punctuation">[</span>
      <span class="token string">"The CustomerEmail field is required."</span>
    <span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token string">"Items[0].Quantity"</span><span class="token punctuation">:</span> <span class="token punctuation">[</span>
      <span class="token string">"Quantity must be between 1 and 1000"</span>
    <span class="token punctuation">]</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><h2 id="openapi-3.1-modernizing-api-documentation">OpenAPI 3.1: Modernizing API Documentation</h2><p>.NET 10&rsquo;s built-in OpenAPI document generation supports OpenAPI 3.1 and <a target="_blank" href="https://json-schema.org/draft/2020-12/release-notes">JSON Schema 2020-12</a>. The default OpenAPI version for generated documents is now 3.1.</p><p>OpenAPI 3.1 aligns better with modern JSON schema expectations and improves how tools interpret your schemas.</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">using</span> Microsoft<span class="token punctuation">.</span>AspNetCore<span class="token punctuation">.</span>OpenApi<span class="token punctuation">;</span>
<span class="token keyword">using</span> Microsoft<span class="token punctuation">.</span>OpenApi<span class="token punctuation">.</span>Models<span class="token punctuation">;</span>

<span class="token keyword">var</span> builder <span class="token operator">=</span> WebApplication<span class="token punctuation">.</span><span class="token function">CreateBuilder</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>

builder<span class="token punctuation">.</span>Services<span class="token punctuation">.</span><span class="token function">AddOpenApi</span><span class="token punctuation">(</span>options <span class="token operator">=</span><span class="token operator">&gt;</span>
<span class="token punctuation">{</span>
    <span class="token comment">// OpenAPI 3.1 is the default, but you can be explicit</span>
    options<span class="token punctuation">.</span>OpenApiVersion <span class="token operator">=</span> Microsoft<span class="token punctuation">.</span>OpenApi<span class="token punctuation">.</span>OpenApiSpecVersion<span class="token punctuation">.</span>OpenApi3_1<span class="token punctuation">;</span>

    options<span class="token punctuation">.</span><span class="token function">AddDocumentTransformer</span><span class="token punctuation">(</span><span class="token punctuation">(</span>document<span class="token punctuation">,</span> context<span class="token punctuation">,</span> cancellationToken<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span>
    <span class="token punctuation">{</span>
        document<span class="token punctuation">.</span>Info <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">OpenApiInfo</span>
        <span class="token punctuation">{</span>
            Title <span class="token operator">=</span> <span class="token string">"Order Management API"</span><span class="token punctuation">,</span>
            Version <span class="token operator">=</span> <span class="token string">"v1"</span><span class="token punctuation">,</span>
            Description <span class="token operator">=</span> <span class="token string">"Enterprise order processing system"</span><span class="token punctuation">,</span>
            Contact <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">OpenApiContact</span>
            <span class="token punctuation">{</span>
                Name <span class="token operator">=</span> <span class="token string">"API Support"</span><span class="token punctuation">,</span>
                Email <span class="token operator">=</span> <span class="token string">"api-support@company.com"</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>

        <span class="token keyword">return</span> Task<span class="token punctuation">.</span>CompletedTask<span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">var</span> app <span class="token operator">=</span> builder<span class="token punctuation">.</span><span class="token function">Build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span>app<span class="token punctuation">.</span>Environment<span class="token punctuation">.</span><span class="token function">IsDevelopment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">// JSON at /openapi/v1.json</span>
    app<span class="token punctuation">.</span><span class="token function">MapOpenApi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">// YAML at /openapi/v1.yaml</span>
    app<span class="token punctuation">.</span><span class="token function">MapOpenApi</span><span class="token punctuation">(</span><span class="token string">"/openapi/{documentName}.yaml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

app<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>Note the YAML route: in .NET 10, you generate YAML by using a route ending in <code>.yaml</code> or <code>.yml</code>, typically with <code>{documentName}</code> in the path.</p><h3 id="schema-improvements-in-practice">Schema Improvements in Practice</h3><p>OpenAPI 3.0 often expressed nullability using <code>nullable: true</code>.</p><pre class=" language-yaml"><code class="prism  language-yaml"><span class="token key atrule">components</span><span class="token punctuation">:</span>
  <span class="token key atrule">schemas</span><span class="token punctuation">:</span>
    <span class="token key atrule">ShippingAddress</span><span class="token punctuation">:</span>
      <span class="token key atrule">type</span><span class="token punctuation">:</span> object
      <span class="token key atrule">nullable</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
      <span class="token key atrule">properties</span><span class="token punctuation">:</span>
        <span class="token key atrule">street</span><span class="token punctuation">:</span>
          <span class="token key atrule">type</span><span class="token punctuation">:</span> string
          <span class="token key atrule">nullable</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
        <span class="token key atrule">city</span><span class="token punctuation">:</span>
          <span class="token key atrule">type</span><span class="token punctuation">:</span> string
</code></pre><p>OpenAPI 3.1 allows us to use union types:</p><pre class=" language-yaml"><code class="prism  language-yaml"><span class="token key atrule">components</span><span class="token punctuation">:</span>
  <span class="token key atrule">schemas</span><span class="token punctuation">:</span>
    <span class="token key atrule">ShippingAddress</span><span class="token punctuation">:</span>
      <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"object"</span><span class="token punctuation">,</span> <span class="token string">"null"</span><span class="token punctuation">]</span>
      <span class="token key atrule">properties</span><span class="token punctuation">:</span>
        <span class="token key atrule">street</span><span class="token punctuation">:</span>
          <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"string"</span><span class="token punctuation">,</span> <span class="token string">"null"</span><span class="token punctuation">]</span>
        <span class="token key atrule">city</span><span class="token punctuation">:</span>
          <span class="token key atrule">type</span><span class="token punctuation">:</span> string
</code></pre><p>This tends to play nicer with tooling that relies heavily on JSON Schema semantics such as OpenAPI Generator and NSwag.</p><h2 id="ef-core-10-named-query-filters">EF Core 10: Named Query Filters</h2><p>Global query filters are <a target="_blank" href="https://www.milanjovanovic.tech/blog/named-query-filters-in-ef-10-multiple-query-filters-per-entity">a staple for multi-tenant apps and soft deletes</a>. The classic problem was granularity: <code>IgnoreQueryFilters()</code> disabled all filters at once.</p><p>EF Core 10 introduces <a target="_blank" href="https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-10.0/whatsnew#named-query-filters">named query filters</a>, so you can selectively disable one filter while keeping another.</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">OrderDbContext</span> <span class="token punctuation">:</span> DbContext
<span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token keyword">readonly</span> <span class="token keyword">int</span> _tenantId<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token function">OrderDbContext</span><span class="token punctuation">(</span>DbContextOptions<span class="token operator">&lt;</span>OrderDbContext<span class="token operator">&gt;</span> options<span class="token punctuation">,</span> ITenantProvider tenant<span class="token punctuation">)</span>
        <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>options<span class="token punctuation">)</span>
        <span class="token operator">=</span><span class="token operator">&gt;</span> _tenantId <span class="token operator">=</span> tenant<span class="token punctuation">.</span>TenantId<span class="token punctuation">;</span>

    <span class="token keyword">public</span> DbSet<span class="token operator">&lt;</span>Order<span class="token operator">&gt;</span> Orders <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token generic-method function">Set<span class="token punctuation">&lt;</span>Order<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">protected</span> <span class="token keyword">override</span> <span class="token keyword">void</span> <span class="token function">OnModelCreating</span><span class="token punctuation">(</span>ModelBuilder modelBuilder<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        modelBuilder<span class="token punctuation">.</span><span class="token generic-method function">Entity<span class="token punctuation">&lt;</span>Order<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">HasQueryFilter</span><span class="token punctuation">(</span><span class="token string">"SoftDelete"</span><span class="token punctuation">,</span> o <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token operator">!</span>o<span class="token punctuation">.</span>IsDeleted<span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">HasQueryFilter</span><span class="token punctuation">(</span><span class="token string">"TenantIsolation"</span><span class="token punctuation">,</span> o <span class="token operator">=</span><span class="token operator">&gt;</span> o<span class="token punctuation">.</span>TenantId <span class="token operator">==</span> _tenantId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>Now an admin endpoint can disable soft delete without disabling tenant isolation:</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">AdminEndpoints</span>
<span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">MapAdminEndpoints</span><span class="token punctuation">(</span><span class="token keyword">this</span> WebApplication app<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">var</span> <span class="token keyword">group</span> <span class="token operator">=</span> app<span class="token punctuation">.</span><span class="token function">MapGroup</span><span class="token punctuation">(</span><span class="token string">"/api/admin"</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">RequireAuthorization</span><span class="token punctuation">(</span><span class="token string">"Admin"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">group</span><span class="token punctuation">.</span><span class="token function">MapGet</span><span class="token punctuation">(</span><span class="token string">"/orders/deleted"</span><span class="token punctuation">,</span> GetDeletedOrders<span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">WithSummary</span><span class="token punctuation">(</span><span class="token string">"Gets deleted orders for the current tenant only"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">async</span> Task<span class="token operator">&lt;</span>IResult<span class="token operator">&gt;</span> <span class="token function">GetDeletedOrders</span><span class="token punctuation">(</span>OrderDbContext db<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">var</span> deletedOrders <span class="token operator">=</span> <span class="token keyword">await</span> db<span class="token punctuation">.</span>Orders
            <span class="token punctuation">.</span><span class="token function">IgnoreQueryFilters</span><span class="token punctuation">(</span><span class="token keyword">new</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">{</span> <span class="token string">"SoftDelete"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> 
            <span class="token punctuation">.</span><span class="token function">Where</span><span class="token punctuation">(</span>o <span class="token operator">=</span><span class="token operator">&gt;</span> o<span class="token punctuation">.</span>IsDeleted<span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">Select</span><span class="token punctuation">(</span>o <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token keyword">new</span> <span class="token punctuation">{</span> o<span class="token punctuation">.</span>Id<span class="token punctuation">,</span> o<span class="token punctuation">.</span>CustomerEmail<span class="token punctuation">,</span> o<span class="token punctuation">.</span>DeletedAt <span class="token punctuation">}</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">ToListAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">return</span> Results<span class="token punctuation">.</span><span class="token function">Ok</span><span class="token punctuation">(</span>deletedOrders<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>This capability is small, but it&rsquo;s exactly the kind of real-world safety improvement that helps prevent cross-tenant data leaks.</p><h2 id="c-14-improvements">C# 14 Improvements</h2><p>.NET 10 ships alongside C# 14. For API developers, a few features immediately reduce boilerplate and improve readability.</p><h3 id="the-field-keyword-eliminate-backing-field-boilerplate">The field Keyword: Eliminate Backing-field Boilerplate</h3><p>C# 14 introduces field-backed properties, where you can reference the compiler-generated backing field directly using the <code>field</code> keyword.</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">public</span> <span class="token keyword">sealed</span> <span class="token keyword">class</span> <span class="token class-name">Order</span>
<span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">string</span> CustomerEmail
    <span class="token punctuation">{</span>
        <span class="token keyword">get</span><span class="token punctuation">;</span>
        <span class="token keyword">set</span>
        <span class="token punctuation">{</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrWhiteSpace</span><span class="token punctuation">(</span><span class="token keyword">value</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">ArgumentException</span><span class="token punctuation">(</span><span class="token string">"Email cannot be empty."</span><span class="token punctuation">,</span> <span class="token function">nameof</span><span class="token punctuation">(</span><span class="token keyword">value</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            field <span class="token operator">=</span> <span class="token keyword">value</span><span class="token punctuation">.</span><span class="token function">Trim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ToLowerInvariant</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><h3 id="null-conditional-assignments">Null-conditional Assignments</h3><p>C# 14 allows null-conditional operators (<code>?.</code> and <code>?[]</code>) on the left-hand side of assignments and compound assignments. The right-hand side is evaluated only when the receiver isn&rsquo;t null. This is great for processing patches.</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">public</span> <span class="token keyword">sealed</span> record <span class="token function">OrderPatchRequest</span><span class="token punctuation">(</span><span class="token keyword">string</span><span class="token operator">?</span> NewStatus<span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token operator">?</span> NewPriority<span class="token punctuation">,</span> <span class="token keyword">string</span><span class="token operator">?</span> NewCity<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">OrderPatchService</span>
<span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">ApplyPatch</span><span class="token punctuation">(</span>Order<span class="token operator">?</span> order<span class="token punctuation">,</span> OrderPatchRequest<span class="token operator">?</span> patch<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>patch <span class="token keyword">is</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span>

        order<span class="token operator">?</span><span class="token punctuation">.</span>Status <span class="token operator">=</span> patch<span class="token punctuation">.</span>NewStatus <span class="token operator">?</span><span class="token operator">?</span> order<span class="token operator">?</span><span class="token punctuation">.</span>Status<span class="token punctuation">;</span>
        order<span class="token operator">?</span><span class="token punctuation">.</span>Priority <span class="token operator">=</span> patch<span class="token punctuation">.</span>NewPriority <span class="token operator">?</span><span class="token operator">?</span> order<span class="token operator">?</span><span class="token punctuation">.</span>Priority<span class="token punctuation">;</span>
        order<span class="token operator">?</span><span class="token punctuation">.</span>Shipping<span class="token operator">?</span><span class="token punctuation">.</span>City <span class="token operator">=</span> patch<span class="token punctuation">.</span>NewCity <span class="token operator">?</span><span class="token operator">?</span> order<span class="token operator">?</span><span class="token punctuation">.</span>Shipping<span class="token operator">?</span><span class="token punctuation">.</span>City<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p><strong>Note:</strong> Increment/decrement operators (<code>++</code>, <code>--</code>) aren&rsquo;t allowed with null-conditional assignments. Compound assignments like <code>+=</code> are supported.</p><p>For more details on this feature, check out the post <a target="_blank" href="https://www.telerik.com/blogs/write-cleaner-code-csharp-14-null-conditional-assignment-operator"><em>Write Cleaner Code with C# 14&rsquo;s Null-Conditional Assignment Operator</em></a>.</p><h3 id="extension-members-properties-static-members-and-operators">Extension Members: Properties, Static Members and Operators</h3><p>C# 14&rsquo;s headline feature is extension members, which add extension properties, static extension members and even operators using the new <code>extension</code> block syntax.</p><p>Don&rsquo;t you just <em>love</em> the syntax?</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">OrderExtensions</span>
<span class="token punctuation">{</span>
    <span class="token function">extension</span><span class="token punctuation">(</span>Order source<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">public</span> <span class="token keyword">decimal</span> TotalValue <span class="token operator">=</span><span class="token operator">&gt;</span>
            source<span class="token punctuation">.</span>Items<span class="token punctuation">.</span><span class="token function">Sum</span><span class="token punctuation">(</span>i <span class="token operator">=</span><span class="token operator">&gt;</span> i<span class="token punctuation">.</span>Quantity <span class="token operator">*</span> i<span class="token punctuation">.</span>UnitPrice<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">public</span> <span class="token keyword">bool</span> IsHighValue <span class="token operator">=</span><span class="token operator">&gt;</span> source<span class="token punctuation">.</span>TotalValue <span class="token operator">&gt;</span> 1000m<span class="token punctuation">;</span>

        <span class="token keyword">public</span> <span class="token keyword">string</span> Summary <span class="token operator">=</span><span class="token operator">&gt;</span>
            $<span class="token string">"Order #{source.Id}: {source.Items.Count} items, ${source.TotalValue:F2} total"</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token function">extension</span><span class="token punctuation">(</span>Order<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">public</span> <span class="token keyword">static</span> Order <span class="token function">CreateEmpty</span><span class="token punctuation">(</span><span class="token keyword">int</span> tenantId<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token keyword">new</span> <span class="token class-name">Order</span>
        <span class="token punctuation">{</span>
            TenantId <span class="token operator">=</span> tenantId<span class="token punctuation">,</span>
            CreatedAt <span class="token operator">=</span> DateTime<span class="token punctuation">.</span>UtcNow<span class="token punctuation">,</span>
            Items <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">List</span><span class="token operator">&lt;</span>OrderItem<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            Status <span class="token operator">=</span> <span class="token string">"Draft"</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>For more details on extension members, check out <a target="_blank" href="https://www.telerik.com/blogs/extension-properties-csharp-14-game-changing-feature-cleaner-code"><em>Extension Properties: C# 14&rsquo;s Game-Changing Feature for Cleaner Code</em></a>. (I don&rsquo;t get paid by the click, I swear.)</p><h2 id="server-sent-events-simplifying-real-time-updates">Server-Sent Events: Simplifying Real-Time Updates</h2><p>ASP.NET Core in .NET 10 adds a built-in <code>ServerSentEvents</code> result for Minimal APIs, so you can stream updates over a single HTTP connection without manually formatting frames.</p><pre class=" language-csharp"><code class="prism  language-csharp"><span class="token keyword">using</span> System<span class="token punctuation">.</span>Runtime<span class="token punctuation">.</span>CompilerServices<span class="token punctuation">;</span>
<span class="token keyword">using</span> Microsoft<span class="token punctuation">.</span>AspNetCore<span class="token punctuation">.</span>Http<span class="token punctuation">.</span>HttpResults<span class="token punctuation">;</span>

<span class="token keyword">public</span> record <span class="token function">OrderStatusUpdate</span><span class="token punctuation">(</span><span class="token keyword">int</span> OrderId<span class="token punctuation">,</span> <span class="token keyword">string</span> Status<span class="token punctuation">,</span> <span class="token keyword">string</span> Message<span class="token punctuation">,</span> DateTime Timestamp<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">OrderStreamingEndpoints</span>
<span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">MapStreamingEndpoints</span><span class="token punctuation">(</span><span class="token keyword">this</span> WebApplication app<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        app<span class="token punctuation">.</span><span class="token function">MapGet</span><span class="token punctuation">(</span><span class="token string">"/api/orders/{id:int}/status-stream"</span><span class="token punctuation">,</span> StreamOrderStatus<span class="token punctuation">)</span>
           <span class="token punctuation">.</span><span class="token function">WithSummary</span><span class="token punctuation">(</span><span class="token string">"Stream real-time order status updates"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">static</span> ServerSentEventsResult<span class="token operator">&lt;</span>OrderStatusUpdate<span class="token operator">&gt;</span> <span class="token function">StreamOrderStatus</span><span class="token punctuation">(</span>
        <span class="token keyword">int</span> id<span class="token punctuation">,</span>
        OrderDbContext db<span class="token punctuation">,</span>
        CancellationToken ct<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">async</span> IAsyncEnumerable<span class="token operator">&lt;</span>OrderStatusUpdate<span class="token operator">&gt;</span> <span class="token function">GetUpdates</span><span class="token punctuation">(</span>
            <span class="token punctuation">[</span>EnumeratorCancellation<span class="token punctuation">]</span> CancellationToken cancellationToken<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token keyword">string</span><span class="token operator">?</span> last <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>

            <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span>cancellationToken<span class="token punctuation">.</span>IsCancellationRequested<span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                <span class="token keyword">var</span> order <span class="token operator">=</span> <span class="token keyword">await</span> db<span class="token punctuation">.</span>Orders<span class="token punctuation">.</span><span class="token function">AsNoTracking</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                    <span class="token punctuation">.</span><span class="token function">FirstOrDefaultAsync</span><span class="token punctuation">(</span>o <span class="token operator">=</span><span class="token operator">&gt;</span> o<span class="token punctuation">.</span>Id <span class="token operator">==</span> id<span class="token punctuation">,</span> cancellationToken<span class="token punctuation">)</span><span class="token punctuation">;</span>

                <span class="token keyword">if</span> <span class="token punctuation">(</span>order <span class="token keyword">is</span> <span class="token keyword">null</span><span class="token punctuation">)</span>
                <span class="token punctuation">{</span>
                    <span class="token keyword">yield</span> <span class="token keyword">return</span> <span class="token keyword">new</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> <span class="token string">"ERROR"</span><span class="token punctuation">,</span> <span class="token string">"Order not found"</span><span class="token punctuation">,</span> DateTime<span class="token punctuation">.</span>UtcNow<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">yield</span> <span class="token keyword">break</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>

                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span>order<span class="token punctuation">.</span>Status<span class="token punctuation">,</span> last<span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>Ordinal<span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token punctuation">{</span>
                    <span class="token keyword">yield</span> <span class="token keyword">return</span> <span class="token keyword">new</span><span class="token punctuation">(</span>order<span class="token punctuation">.</span>Id<span class="token punctuation">,</span> order<span class="token punctuation">.</span>Status<span class="token punctuation">,</span> $<span class="token string">"Order is now {order.Status}"</span><span class="token punctuation">,</span> DateTime<span class="token punctuation">.</span>UtcNow<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    last <span class="token operator">=</span> order<span class="token punctuation">.</span>Status<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>

                <span class="token keyword">if</span> <span class="token punctuation">(</span>order<span class="token punctuation">.</span>Status <span class="token keyword">is</span> <span class="token string">"Delivered"</span> or <span class="token string">"Cancelled"</span><span class="token punctuation">)</span>
                    <span class="token keyword">yield</span> <span class="token keyword">break</span><span class="token punctuation">;</span>

                <span class="token keyword">await</span> Task<span class="token punctuation">.</span><span class="token function">Delay</span><span class="token punctuation">(</span>TimeSpan<span class="token punctuation">.</span><span class="token function">FromSeconds</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">,</span> cancellationToken<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>

        <span class="token keyword">return</span> TypedResults<span class="token punctuation">.</span><span class="token function">ServerSentEvents</span><span class="token punctuation">(</span><span class="token function">GetUpdates</span><span class="token punctuation">(</span>ct<span class="token punctuation">)</span><span class="token punctuation">,</span> eventType<span class="token punctuation">:</span> <span class="token string">"order-status"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>Client-side consumption is quite simple, too:</p><pre class=" language-javascript"><code class="prism  language-javascript"><span class="token operator">&lt;</span>script<span class="token operator">&gt;</span>
  <span class="token keyword">function</span> <span class="token function">trackOrderStatus</span><span class="token punctuation">(</span>orderId<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> es <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EventSource</span><span class="token punctuation">(</span><span class="token template-string"><span class="token string">`/api/orders/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>orderId<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/status-stream`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    es<span class="token punctuation">.</span><span class="token function-variable function">onmessage</span> <span class="token operator">=</span> <span class="token punctuation">(</span>event<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> update <span class="token operator">=</span> JSON<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>update<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>update<span class="token punctuation">.</span>status <span class="token operator">===</span> <span class="token string">"Delivered"</span> <span class="token operator">||</span> update<span class="token punctuation">.</span>status <span class="token operator">===</span> <span class="token string">"Cancelled"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        es<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>

    es<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token string">"SSE connection error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> es<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
</code></pre><h2 id="should-you-upgrade-to-.net-10">Should You Upgrade to .NET 10?</h2><p>.NET 10 is an LTS release. If you&rsquo;re starting a new project, it&rsquo;s a no-brainer.</p><p>If you&rsquo;re upgrading from .NET 8 or .NET 9, a few things to keep in mind:</p><ul><li><strong>Minimal API validation</strong>: If you&rsquo;ve been hand-rolling validation, .NET 10&rsquo;s <code>AddValidation</code> support can remove a surprising amount of custom code.</li><li><strong>OpenAPI</strong>: Built-in OpenAPI generation defaults to 3.1 and supports YAML endpoints via <code>.yaml</code>/<code>.yml</code> routes.</li><li><strong>EF Core</strong>: Named query filters are a real safety upgrade for multi-tenant apps, and JSON column support continues to improve (including bulk update support).</li><li><strong>C# 14</strong>: You can adopt new features incrementally. Even if you ignore extension members entirely, <code>field</code> and null-conditional assignment will show up in your codebase quickly.</li></ul><p>The upgrade path is generally smooth: change the target in your <code>.csproj</code>, run tests, fix warnings and ship.</p><h2 id="wrapping-up">Wrapping Up</h2><p>.NET 10 delivers meaningful improvements for API developers through thoughtful enhancements rather than revolutionary changes. The combination of built-in Minimal API validation, OpenAPI 3.1 and C# 14 quality-of-life features add up to a more productive and safer development experience.</p><p>Happy coding!</p><h2 id="references">References</h2><h3 id="platform-updates">Platform updates</h3><ul><li><a target="_blank" href="https://devblogs.microsoft.com/dotnet/announcing-dotnet-10/">Announcing .NET 10</a> (Microsoft)</li><li><a target="_blank" href="https://dotnet.microsoft.com/en-us/platform/support/policy">.NET Support Policy</a> (Microsoft)</li><li><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/overview">What&rsquo;s new in .NET 10</a> (Microsoft Learn)</li></ul><h3 id="asp.net-coreapi-updates">ASP.NET Core/API Updates</h3><ul><li><a target="_blank" href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis?view=aspnetcore-10.0#validation-support-in-minimal-apis">Minimal APIs quick reference &ndash; validation support</a> (Microsoft Learn)</li><li><a target="_blank" href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/openapi/aspnetcore-openapi?view=aspnetcore-10.0&amp;tabs=visual-studio%2Cvisual-studio-code">Generate OpenAPI documents</a> (Microsoft Learn)</li><li><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.typedresults.serversentevents?view=aspnetcore-10.0">TypedResults.ServerSentEvents API docs</a> (Microsoft Learn)</li><li><a target="_blank" href="https://timdeschryver.dev/blog/aspnet-10-validating-incoming-models-in-minimal-apis">ASP.NET 10: Validating incoming models in Minimal APIs</a> (Tim Deschryver)</li><li><a target="_blank" href="https://blog.safia.rocks/2025/11/10/aspnetcore-ten/">And just like that .NET 10 ships tomorrow</a> (Safia Abdalla)</li></ul><h3 id="language-updates">Language Updates</h3><ul><li><a target="_blank" href="https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-10.0/whatsnew">What&rsquo;s new in EF Core 10</a> (Microsoft Learn)</li><li><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14">What&rsquo;s new in C# 14</a> (Microsoft Learn)</li><li><a target="_blank" href="https://devblogs.microsoft.com/dotnet/introducing-csharp-14/">Introducing C# 14</a> (Microsoft .NET Blog)</li><li><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/extension-members">Extension members tutorial</a> (Microsoft Learn)</li></ul><img src="https://feeds.telerik.com/link/23050/17244502.gif" height="1" width="1"/>]]></content>
  </entry>
</feed>
