<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Lucy Muturi</title>
    <description>The latest articles on Forem by Lucy Muturi (@lucy_muturi).</description>
    <link>https://forem.com/lucy_muturi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1819420%2F87984bdb-83b5-40f8-8f70-9afbaec9a433.png</url>
      <title>Forem: Lucy Muturi</title>
      <link>https://forem.com/lucy_muturi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/lucy_muturi"/>
    <language>en</language>
    <item>
      <title>Angular Spreadsheet Freezing on Large Excel Imports? Here’s the Fix</title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Fri, 17 Apr 2026 12:10:31 +0000</pubDate>
      <link>https://forem.com/syncfusion/angular-spreadsheet-freezing-on-large-excel-imports-heres-the-fix-2904</link>
      <guid>https://forem.com/syncfusion/angular-spreadsheet-freezing-on-large-excel-imports-heres-the-fix-2904</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Large Excel imports in Angular Spreadsheet freeze the UI because synchronous XLSX parsing (styles, formats, objects) blocks the main thread. Optimize imports by disabling style/format parsing, enforcing server-side cell and file size thresholds, and using openFromJson with selective deserialization for predictable performance and lower memory usage.&lt;/p&gt;

&lt;p&gt;Have you ever uploaded an Excel file and watched your web app freeze instantly? It happens more often when users try to import Excel files in Angular. A large workbook can easily slow down the browser, trigger memory spikes, or get stuck while reading the file, making the entire page feel unresponsive.&lt;/p&gt;

&lt;p&gt;Most Angular apps freeze during large Excel imports because the browser tries to parse every cell, style, formula, and object on the main thread. This leads to long pauses, high memory usage, and unpredictable “page unresponsive” errors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.syncfusion.com/spreadsheet-editor-sdk/angular-spreadsheet-editor" rel="noopener noreferrer"&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt; Angular Spreadsheet Editor&lt;/a&gt; avoids these issues by loading only what’s necessary, enforcing file size and data limits, and allowing large workbooks to open quickly via lightweight JSON loading rather than full XLSX parsing.&lt;/p&gt;

&lt;p&gt;In this blog, you’ll learn three specific techniques to fix this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Skip heavy formatting using &lt;a href="https://help.syncfusion.com/cr/document-processing/Syncfusion.EJ2.Spreadsheet.WorkbookParseOptions.html#Syncfusion_EJ2_Spreadsheet_WorkbookParseOptions_IgnoreStyle" rel="noopener noreferrer"&gt;IgnoreStyle &lt;/a&gt;and &lt;a href="https://help.syncfusion.com/cr/document-processing/Syncfusion.EJ2.Spreadsheet.WorkbookParseOptions.html#Syncfusion_EJ2_Spreadsheet_WorkbookParseOptions_IgnoreFormat" rel="noopener noreferrer"&gt;IgnoreFormat&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Prevent server overload using &lt;a href="https://help.syncfusion.com/cr/document-processing/Syncfusion.EJ2.Spreadsheet.ThresholdLimit.html#Syncfusion_EJ2_Spreadsheet_ThresholdLimit_MaximumDataLimit" rel="noopener noreferrer"&gt;MaximumDataLimit &lt;/a&gt;and &lt;a href="https://help.syncfusion.com/cr/document-processing/Syncfusion.EJ2.Spreadsheet.ThresholdLimit.html#Syncfusion_EJ2_Spreadsheet_ThresholdLimit_MaximumFileSize" rel="noopener noreferrer"&gt;MaximumFileSize&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Load large workbooks faster using &lt;a href="https://ej2.syncfusion.com/angular/documentation/api/spreadsheet/index-default#openfromjson" rel="noopener noreferrer"&gt;openFromJson&lt;/a&gt; with selective deserialization.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive deeper into these techniques that make large Excel imports fast and reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why large Excel imports silently break web apps
&lt;/h2&gt;

&lt;p&gt;Large Excel files don’t just “take longer.” They often trigger a chain reaction that feels like a crash:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The page freezes&lt;/strong&gt; because parsing blocks the UI thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory jumps&lt;/strong&gt;  due to styles, formats, images, and workbook metadata.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Imports time out&lt;/strong&gt; on slower machines or remote environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Users get no actionable error&lt;/strong&gt;, just a stuck screen or killed tab.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is especially common in enterprise scenarios where “normal” spreadsheets contain hundreds of thousands of cells plus formatting rules, validations, and embedded objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Syncfusion Angular Spreadsheet eliminates large file import failures
&lt;/h2&gt;

&lt;p&gt;Many apps fail because they load everything at once. &lt;a href="https://www.syncfusion.com/spreadsheet-editor-sdk/angular-spreadsheet-editor" rel="noopener noreferrer"&gt;Syncfusion Angular Spreadsheet Editor&lt;/a&gt; is designed to avoid that pattern by letting you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load only what you need (data vs. styling/features)&lt;/li&gt;
&lt;li&gt;Enforce thresholds before a file overwhelms the system&lt;/li&gt;
&lt;li&gt;Open workbooks from lightweight JSON for faster startup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FInventory-data-with-formulas-and-conditional-formatting-in-Angular-Spreadsheet-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FInventory-data-with-formulas-and-conditional-formatting-in-Angular-Spreadsheet-1.png" alt="Angular Spreadsheet with Styles and Formatting" width="779" height="343"&gt;&lt;/a&gt;&lt;br&gt;Angular Spreadsheet with Styles and Formatting
  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Curious to see the Angular Spreadsheet in action?&lt;/strong&gt; Explore the live &lt;a href="https://document.syncfusion.com/demos/spreadsheet-editor/angular/#/tailwind3/spreadsheet/default" rel="noopener noreferrer"&gt;demo&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parsing options: Load only what you need
&lt;/h3&gt;

&lt;p&gt;Most Excel imports fail not because of data volume alone, but because of &lt;strong&gt;formatting overhead&lt;/strong&gt;. Styles, number formats, and empty-cell metadata dramatically increase parsing cost, even when your app only needs raw values.&lt;/p&gt;

&lt;p&gt;Syncfusion solves this with &lt;a href="https://help.syncfusion.com/cr/document-processing/Syncfusion.EJ2.Spreadsheet.WorkbookParseOptions.html" rel="noopener noreferrer"&gt;WorkbookParseOptions&lt;/a&gt;. By enabling &lt;a href="https://help.syncfusion.com/cr/document-processing/Syncfusion.EJ2.Spreadsheet.WorkbookParseOptions.html#Syncfusion_EJ2_Spreadsheet_WorkbookParseOptions_IgnoreStyle" rel="noopener noreferrer"&gt;IgnoreStyle&lt;/a&gt; and &lt;a href="https://help.syncfusion.com/cr/document-processing/Syncfusion.EJ2.Spreadsheet.WorkbookParseOptions.html#Syncfusion_EJ2_Spreadsheet_WorkbookParseOptions_IgnoreFormat" rel="noopener noreferrer"&gt;IgnoreFormat&lt;/a&gt; properties on the server, the spreadsheet loads only raw data, skipping the formatting overhead entirely.&lt;/p&gt;

&lt;p&gt;Here is a server-side example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IActionResult&lt;/span&gt; &lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IFormCollection&lt;/span&gt; &lt;span class="n"&gt;openRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;OpenRequest&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;OpenRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="c1"&gt;// Enable parsing options to skip styles and formats for faster loading&lt;/span&gt;
    &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseOptions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WorkbookParseOptions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="n"&gt;IgnoreStyle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;IgnoreFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt; 
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="c1"&gt;// Process and return the parsed workbook data&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Workbook&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By disabling style and format parsing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only raw cell values are processed&lt;/li&gt;
&lt;li&gt;JSON payload size is reduced&lt;/li&gt;
&lt;li&gt;Memory usage drops significantly&lt;/li&gt;
&lt;li&gt;Import time improves immediately&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; These options are ideal when styles and number formats aren’t important for your use case, and the goal is to load the Excel data as quickly as possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you gain&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster file loading&lt;/li&gt;
&lt;li&gt;Lower memory usage&lt;/li&gt;
&lt;li&gt;Smaller JSON payloads sent to the client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is ideal for “data pipeline” imports where formatting is irrelevant (finance exports, HR records, inventory loads).&lt;/p&gt;

&lt;h3&gt;
  
  
  Threshold limits: Stop the file before it crashes the app
&lt;/h3&gt;

&lt;p&gt;Large Excel files don’t just overload the browser; they can spike server memory too. Without a safety check, a single oversized upload can silently degrade your entire application’s performance.&lt;/p&gt;

&lt;p&gt;Syncfusion’s threshold limits give you a clear control point. You can define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://help.syncfusion.com/cr/document-processing/Syncfusion.EJ2.Spreadsheet.ThresholdLimit.html#Syncfusion_EJ2_Spreadsheet_ThresholdLimit_MaximumDataLimit" rel="noopener noreferrer"&gt;MaximumDataLimit&lt;/a&gt;: The maximum number of cells allowed.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://help.syncfusion.com/cr/document-processing/Syncfusion.EJ2.Spreadsheet.ThresholdLimit.html#Syncfusion_EJ2_Spreadsheet_ThresholdLimit_MaximumFileSize" rel="noopener noreferrer"&gt;MaximumFileSize&lt;/a&gt;: The maximum file size in bytes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What happens when a limit is exceeded&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An alert message appears: &lt;strong&gt;&lt;code&gt;The file is large&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Cancel&lt;/code&gt;&lt;/strong&gt; stops the import cleanly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;OK&lt;/code&gt;&lt;/strong&gt; continues (only if your app logic permits it)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This single check prevents crashes, timeouts, and memory overloads caused by unexpectedly large uploads, and gives users clarity rather than confusion.&lt;/p&gt;

&lt;p&gt;You can configure the thresholds API on the server side using the following code example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IActionResult&lt;/span&gt; &lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IFormCollection&lt;/span&gt; &lt;span class="n"&gt;openRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;OpenRequest&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;OpenRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openRequest&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Guid"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="c1"&gt;// Set maximum allowed number of cells&lt;/span&gt;
    &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ThresholdLimit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaximumDataLimit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 1,000,000 cells&lt;/span&gt;

    &lt;span class="c1"&gt;// Set maximum allowed file size in bytes (e.g., 5MB)&lt;/span&gt;
    &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ThresholdLimit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaximumFileSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;openbook&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Workbook&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;openbook&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code example enforces a safety gate before parsing becomes expensive, protecting both the user experience and backend stability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FFile-size-warning-in-Angular-Spreadsheet.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FFile-size-warning-in-Angular-Spreadsheet.png" alt="File size warning in Angular Spreadsheet" width="800" height="344"&gt;&lt;/a&gt;&lt;br&gt;File size warning in Angular Spreadsheet
  &lt;/p&gt;

&lt;h3&gt;
  
  
  JSON serialization: Parse once, open instantly
&lt;/h3&gt;

&lt;p&gt;Parsing a full &lt;strong&gt;&lt;code&gt;XLSX&lt;/code&gt;&lt;/strong&gt; file on every file open is expensive. If the workbook includes charts, images, conditional formatting, or complex styles, that overhead adds up fast.&lt;/p&gt;

&lt;p&gt;Syncfusion Angular Spreadsheet solves this with &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/angular/performance-best-practices#configure-json-serialization-options-during-open" rel="noopener noreferrer"&gt;JSON serialization options&lt;/a&gt;. These let you exclude specific features, such as styles, formats, charts, images, wrap, and more, from the Workbook JSON object when opening it via the &lt;a href="https://ej2.syncfusion.com/angular/documentation/api/spreadsheet/index-default#openfromjson" rel="noopener noreferrer"&gt;openFromJson&lt;/a&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why JSON-based loading is faster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;strong&gt;&lt;code&gt;openFromJson&lt;/code&gt;&lt;/strong&gt;, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid repeated XLSX parsing&lt;/li&gt;
&lt;li&gt;Exclude features your app doesn’t need&lt;/li&gt;
&lt;li&gt;Reduce JSON size and processing time&lt;/li&gt;
&lt;li&gt;Improve load speed for large or complex workbooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Syncfusion also supports &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/angular/open-save#configure-json-deserialization-options" rel="noopener noreferrer"&gt;selective deserialization&lt;/a&gt;. You can choose exactly which parts of the JSON to ignore during loading. Previously, &lt;strong&gt;&lt;code&gt;openFromJson&lt;/code&gt;&lt;/strong&gt; always loaded every element: styles, formulas, conditional formatting, charts, images, validations, and Notes. Now you control that explicitly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Client-side example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Load workbook JSON — ignore styles for faster rendering of the spreadsheet&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openFromJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fileJson&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;ignoreStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you fine-grained control over the loading process, exactly what you need when you import large Excel files in Angular apps with complex structures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to know more details about these techniques?&lt;/strong&gt; Explore the full Angular Spreadsheet &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/angular/overview" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Syncfusion Angular Spreadsheet for large file imports
&lt;/h2&gt;

&lt;p&gt;Here’s how to integrate the Syncfusion Spreadsheet into your Angular app from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Install Angular CLI
&lt;/h3&gt;

&lt;p&gt;You can use &lt;a href="https://github.com/angular/angular-cli" rel="noopener noreferrer"&gt;Angular CLI&lt;/a&gt; to set up your Angular applications. To install Angular CLI, use the following command:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bash&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Create a new Angular application
&lt;/h3&gt;

&lt;p&gt;You can create a new Angular application using the following Angular CLI command:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bash&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng new my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Choose your preferred stylesheet format (&lt;strong&gt;&lt;code&gt;CSS/SCSS&lt;/code&gt;&lt;/strong&gt;) and &lt;strong&gt;&lt;code&gt;SSR&lt;/code&gt;&lt;/strong&gt; options when prompted.&lt;/p&gt;

&lt;p&gt;For more details, refer to the blog post at &lt;a href="https://www.syncfusion.com/blogs/post/angular-spreadsheet-freezing-large-excel-import" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>angularspreadsheet</category>
      <category>excelimport</category>
      <category>excellikespreadsheet</category>
    </item>
    <item>
      <title>.NET MAUI State Management: From ViewModels to App Stores</title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Thu, 16 Apr 2026 13:46:15 +0000</pubDate>
      <link>https://forem.com/syncfusion/net-maui-state-management-from-viewmodels-to-app-stores-4al9</link>
      <guid>https://forem.com/syncfusion/net-maui-state-management-from-viewmodels-to-app-stores-4al9</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Start with MVVM and data binding for page-level state, apply Visual State Manager for visual-only changes, and rely on DI-backed app-wide stores for shared state. For highly interactive or complex flows, MVU or reducer-style unidirectional updates offer better predictability.&lt;/p&gt;

&lt;p&gt;State is the backbone of every .NET MAUI application. It determines what users see, how the UI reacts to interactions, and how consistently data flows across screens. Whether it’s the text inside an Entry, the enabled state of a button, or the user session shared across pages, effective state management ensures your UI remains predictable, testable, and easy to maintain.&lt;/p&gt;

&lt;p&gt;.NET MAUI does not enforce a single state management solution. Instead, it provides flexible building blocks that allow you to choose the right approach based on your app’s complexity. This article walks through the most practical and production-ready ways to manage state in .NET MAUI, from simple &lt;strong&gt;ViewModel&lt;/strong&gt; state to shared app-wide stores, and helps you decide when to use each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why state management in MAUI matters
&lt;/h2&gt;

&lt;p&gt;In real apps, state stops being “just a couple of properties” fast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication affects navigation, headers, API calls, and cached data.&lt;/li&gt;
&lt;li&gt;Offline support introduces queues and retry logic.&lt;/li&gt;
&lt;li&gt;Multiple pages need the same data (profile, cart, preferences).&lt;/li&gt;
&lt;li&gt;Background sync and push notifications mutate state while the user is elsewhere.&lt;/li&gt;
&lt;li&gt;Multi-window scenarios need a shared but safe global state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If state changes can happen anywhere, debugging becomes guesswork. The goal is not a perfect architecture; it’s predictable updates and a UI that stays consistent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recommended state management approaches in .NET MAUI
&lt;/h2&gt;

&lt;p&gt;Most real-world MAUI apps rely on a combination of the following patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MVVM with data binding&lt;/strong&gt; for page-level and feature-level state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MVU-style updates&lt;/strong&gt; for predictable, unidirectional state transitions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual State Manager (VSM)&lt;/strong&gt; for purely visual UI changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Injection (DI)&lt;/strong&gt; for shared and app-wide state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rather than treating these as competing patterns, think of them as complementary tools. The key is applying each one where it fits best.&lt;/p&gt;

&lt;h2&gt;
  
  
  MVVM + INotifyPropertyChanged: The foundation
&lt;/h2&gt;

&lt;p&gt;MVVM (Model-View-ViewModel) is the most widely used pattern in .NET MAUI and forms the foundation of state management for most applications.&lt;/p&gt;

&lt;p&gt;In MVVM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;View&lt;/strong&gt; defines the UI using XAML.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;ViewModel&lt;/strong&gt; holds the state and exposes it through bindable properties.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Model&lt;/strong&gt; represents your domain or business data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The View never directly manipulates state. Instead, it binds to ViewModel properties. When the ViewModel changes, the UI updates automatically through data binding.&lt;/p&gt;

&lt;p&gt;Here’s the example MVVM implementation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ViewModel.cs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ViewModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;INotifyPropertyChanged&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;set&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="nf"&gt;OnPropertyChanged&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;event&lt;/span&gt; &lt;span class="n"&gt;PropertyChangedEventHandler&lt;/span&gt; &lt;span class="n"&gt;PropertyChanged&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnPropertyChanged&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;CallerMemberName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;propertyName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;PropertyChanged&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PropertyChangedEventArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;MainPage.xaml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Label&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"{Binding Name}"&lt;/span&gt; &lt;span class="na"&gt;FontSize=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;MainPage.xaml.cs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainPage&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ContentPage&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;MainPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;InitializeComponent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;BindingContext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ViewModel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Maui"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;When to use:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forms, lists, and CRUD screens&lt;/li&gt;
&lt;li&gt;Input validation and command-based interactions&lt;/li&gt;
&lt;li&gt;Navigation flows and page-level logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MVVM is ideal when you want strong separation of concerns, easy unit testing, and straightforward data binding.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FMVVM-architecture-flow-in-.NET-MAUI.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FMVVM-architecture-flow-in-.NET-MAUI.jpg" alt="MVVM architecture flow in .NET MAUI" width="800" height="518"&gt;&lt;/a&gt;&lt;br&gt;MVVM architecture flow in .NET MAUI
  &lt;/p&gt;

&lt;h2&gt;
  
  
  MVU (Model-View-Update): Predictable state flow
&lt;/h2&gt;

&lt;p&gt;MVU introduces a functional, unidirectional approach to state management. Instead of mutating properties across different objects, MVU treats state as an immutable model that changes only through explicit updates.&lt;/p&gt;

&lt;p&gt;The flow looks like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model → View → Message → Update → Model&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model&lt;/strong&gt; represents the entire state snapshot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;View&lt;/strong&gt; renders UI based solely on the model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update&lt;/strong&gt; receives user actions or events messages and returns a new model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;AppModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Increment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;AppModel&lt;/span&gt; &lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppModel&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Msg&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Increment&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because all state changes occur in a single Update function, MVU delivers predictable behavior and prevents unintended state mutations. It works best for UIs with complex, interdependent interactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Highly interactive screens&lt;/li&gt;
&lt;li&gt;Complex workflows with many dependent UI updates&lt;/li&gt;
&lt;li&gt;Scenarios where unidirectional data flow is preferred&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MVU is less common than MVVM in MAUI, but it shines in advanced use cases and pairs well with frameworks like &lt;strong&gt;&lt;code&gt;Comet&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;MauiReactor&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FMVU-state-flow-in-.NET-MAUI.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FMVU-state-flow-in-.NET-MAUI.jpg" alt="MVU architecture flow in .NET MAUI" width="780" height="432"&gt;&lt;/a&gt;&lt;br&gt;MVU architecture flow in .NET MAUI
  &lt;/p&gt;

&lt;h2&gt;
  
  
  Visual State Manager (VSM): Declarative UI states
&lt;/h2&gt;

&lt;p&gt;Visual State Manager (VSM) is designed specifically for visual changes, not business logic. It allows you to define &lt;strong&gt;named visual states&lt;/strong&gt;, such as &lt;strong&gt;&lt;code&gt;Normal&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;Pressed&lt;/code&gt;&lt;/strong&gt;, or &lt;strong&gt;&lt;code&gt;Selected&lt;/code&gt;&lt;/strong&gt;, and let VSM handle the transitions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The View (XAML)&lt;/strong&gt; declares &lt;strong&gt;&lt;code&gt;VisualStateGroups&lt;/code&gt;&lt;/strong&gt; and individual &lt;strong&gt;&lt;code&gt;VisualStates&lt;/code&gt;&lt;/strong&gt;, each containing the appearance rules for that state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State changes&lt;/strong&gt; are triggered through bindings, behaviors, or code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of manually toggling properties across controls, you switch visual states and let VSM handle the transitions. This keeps your UI logic organized, consistent, and easy to maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ContentView&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;BoxView&lt;/span&gt; &lt;span class="na"&gt;x:Name=&lt;/span&gt;&lt;span class="s"&gt;"box"&lt;/span&gt;
             &lt;span class="na"&gt;WidthRequest=&lt;/span&gt;&lt;span class="s"&gt;"120"&lt;/span&gt;
             &lt;span class="na"&gt;HeightRequest=&lt;/span&gt;&lt;span class="s"&gt;"120"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;VisualStateManager.VisualStateGroups&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;VisualStateGroup&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"SelectionStates"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;VisualState&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"Normal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;VisualState.Setters&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class="na"&gt;TargetName=&lt;/span&gt;&lt;span class="s"&gt;"box"&lt;/span&gt;
                            &lt;span class="na"&gt;Property=&lt;/span&gt;&lt;span class="s"&gt;"BackgroundColor"&lt;/span&gt;
                            &lt;span class="na"&gt;Value=&lt;/span&gt;&lt;span class="s"&gt;"LightGray"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/VisualState.Setters&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/VisualState&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;VisualState&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"Selected"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;VisualState.Setters&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class="na"&gt;TargetName=&lt;/span&gt;&lt;span class="s"&gt;"box"&lt;/span&gt;
                            &lt;span class="na"&gt;Property=&lt;/span&gt;&lt;span class="s"&gt;"BackgroundColor"&lt;/span&gt;
                            &lt;span class="na"&gt;Value=&lt;/span&gt;&lt;span class="s"&gt;"LightBlue"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/VisualState.Setters&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/VisualState&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/VisualStateGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/VisualStateManager.VisualStateGroups&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ContentView&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual feedback such as selection, focus, or disabled states.&lt;/li&gt;
&lt;li&gt;Simple animations or appearance changes.&lt;/li&gt;
&lt;li&gt;Keeping UI logic declarative and XAML-focused.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid placing business logic inside visual state transitions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FVisual-State-Manager-flow-in-.NET-MAUI.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FVisual-State-Manager-flow-in-.NET-MAUI.jpg" alt="Visual State Manager flow in .NET MAUI" width="780" height="505"&gt;&lt;/a&gt;&lt;br&gt;Visual State Manager flow in .NET MAUI
  &lt;/p&gt;

&lt;p&gt;For more details, refer to the blog post at &lt;a href="https://www.syncfusion.com/blogs/post/managing-state-in-dotnet-maui" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>netmaui</category>
      <category>dependencyinjection</category>
      <category>maui</category>
      <category>mvvm</category>
    </item>
    <item>
      <title>.NET MAUI ListView vs CollectionView: How Syncfusion ListView Performs Better</title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Thu, 16 Apr 2026 12:16:44 +0000</pubDate>
      <link>https://forem.com/syncfusion/net-maui-listview-vs-collectionview-how-syncfusion-listview-performs-better-4fj9</link>
      <guid>https://forem.com/syncfusion/net-maui-listview-vs-collectionview-how-syncfusion-listview-performs-better-4fj9</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Many .NET MAUI lists falter under real-world demands. This comparison reveals how Syncfusion .NET MAUI ListView confidently manages grouping, gestures, infinite scroll, and large data, delivering smoother scrolling, fewer allocations, and less glue code than CollectionView.&lt;/p&gt;

&lt;h2&gt;
  
  
  When CollectionView hits its limits, here’s the ListView built for real apps
&lt;/h2&gt;

&lt;p&gt;If you’ve built more than a demo app with .NET MAUI, you’ve probably hit this point:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“The list worked great—until we added more features.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/collectionview/?view=net-maui-10.0" rel="noopener noreferrer"&gt;.NET MAUI CollectionView&lt;/a&gt; is a solid starting point, but it starts to show strain as an app grows.&lt;/p&gt;

&lt;p&gt;Add grouped data, sticky headers, swipe actions, drag‑and‑drop, or infinite scrolling, and CollectionView often turns into a web of event handlers, state management, and performance trade‑offs. The result is familiar: more code to maintain, tougher debugging, and a list of experiences that feel sluggish on real devices.&lt;/p&gt;

&lt;p&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt; &lt;a href="https://www.syncfusion.com/maui-controls/maui-listview" rel="noopener noreferrer"&gt;.NET MAUI ListView&lt;/a&gt; takes a different approach.&lt;/p&gt;

&lt;p&gt;Instead of making you piece together common list behaviors, it delivers them out of the box using built‑in properties, MVVM‑friendly commands, and a virtualization engine designed for large datasets. The payoff is immediate: cleaner code, smoother scrolling, and significantly lower memory usage.&lt;/p&gt;

&lt;p&gt;This post compares both controls using the same real‑world scenario and shows where Syncfusion .NET MAUI ListView saves time, code, and memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Syncfusion .NET MAUI ListView outshines Collection View
&lt;/h2&gt;

&lt;p&gt;When comparing these two controls, the Syncfusion &lt;a href="https://help.syncfusion.com/maui/listview/getting-started" rel="noopener noreferrer"&gt;.NET MAUI ListView&lt;/a&gt; stands out with built‑in features that reduce extra code and deliver smoother performance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Grouping with sticky headers:&lt;/strong&gt; Pins the current group header at the top while scrolling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swipe actions:&lt;/strong&gt; Reveals quick actions by swiping left or right on an item.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drag-and-drop reorder:&lt;/strong&gt; Users can reorder items by dragging them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incremental loading:&lt;/strong&gt; Loads the page on demand for faster, lighter lists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layout choices:&lt;/strong&gt; Switches between list and grid presentations to fit the content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Item sizing and virtualization:&lt;/strong&gt; Uses fixed or measured row heights to keep scrolling smooth.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Syncfusion .NET MAUI ListView vs .NET MAUI CollectionView: Real feature comparison
&lt;/h2&gt;

&lt;p&gt;To keep this comparison honest, we are going to test both controls using the &lt;strong&gt;same MVVM book list&lt;/strong&gt;, no shortcuts, no artificial demos. Each section answers the kinds of questions developers actually run into when building production apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How much effort does sticky grouping really take?&lt;/li&gt;
&lt;li&gt;How quickly does swipe support get messy?&lt;/li&gt;
&lt;li&gt;What breaks when you add drag‑and‑drop reordering?&lt;/li&gt;
&lt;li&gt;And what happens to memory usage as the list grows?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Along the way, you’ll see where Syncfusion ListView handles these scenarios with built‑in properties and templates, and where Collection View requires extra event wiring, state tracking, and custom logic.&lt;/p&gt;

&lt;p&gt;Instead of theory or feature checklists, this walkthrough shows real code, real UI behavior, and real performance numbers, so you can decide which control fits your feature needs and performance goals based on facts rather than assumptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Grouping with sticky headers
&lt;/h3&gt;

&lt;p&gt;To see the difference clearly, let’s compare how each control handles this feature:&lt;/p&gt;

&lt;h4&gt;
  
  
  a) Syncfusion .NET MAUI ListView
&lt;/h4&gt;

&lt;p&gt;Sticky headers are a built-in feature in Syncfusion .NET MAUI ListView. As you scroll, the current group title stays pinned at the top, so users always know where they are. A single setting enables it, and grouping by the first letter feels effortless.&lt;/p&gt;

&lt;p&gt;Here’s the code you need:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;listView:SfListView&lt;/span&gt; &lt;span class="na"&gt;x:Name=&lt;/span&gt;&lt;span class="s"&gt;"listView"&lt;/span&gt;
                      &lt;span class="na"&gt;ItemsSource=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BookInfo}"&lt;/span&gt;
                      &lt;span class="na"&gt;IsStickyGroupHeader=&lt;/span&gt;&lt;span class="s"&gt;"True"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;listView:SfListView.GroupHeaderTemplate&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DataTemplate&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;Grid&lt;/span&gt; &lt;span class="na"&gt;BackgroundColor=&lt;/span&gt;&lt;span class="s"&gt;"#F2F2F2"&lt;/span&gt; &lt;span class="na"&gt;Padding=&lt;/span&gt;&lt;span class="s"&gt;"8,4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;Label&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"{Binding Key}"&lt;/span&gt; &lt;span class="na"&gt;VerticalTextAlignment=&lt;/span&gt;&lt;span class="s"&gt;"Center"&lt;/span&gt; &lt;span class="na"&gt;FontAttributes=&lt;/span&gt;&lt;span class="s"&gt;"Bold"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/Grid&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/DataTemplate&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/listView:SfListView.GroupHeaderTemplate&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/listView:SfListView&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Group items by the first character of BookName (uppercase).&lt;/span&gt;
&lt;span class="n"&gt;listView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GroupDescriptors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;GroupDescriptor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;PropertyName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"BookName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;KeySelector&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;obj1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj1&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;BookInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BookName&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  b) .NET MAUI CollectionView
&lt;/h4&gt;

&lt;p&gt;You need to manage sticky headers manually. On every scroll, you recalculate which group is visible and update the header. It works but requires extra housekeeping.&lt;/p&gt;

&lt;p&gt;Refer to the following code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Grid&lt;/span&gt; &lt;span class="na"&gt;RowDefinitions=&lt;/span&gt;&lt;span class="s"&gt;"Auto,*"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Border&lt;/span&gt; &lt;span class="na"&gt;BackgroundColor=&lt;/span&gt;&lt;span class="s"&gt;"#F2F2F2"&lt;/span&gt; &lt;span class="na"&gt;Padding=&lt;/span&gt;&lt;span class="s"&gt;"8,4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Label&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"{Binding CurrentGroupName}"&lt;/span&gt; &lt;span class="na"&gt;FontAttributes=&lt;/span&gt;&lt;span class="s"&gt;"Bold"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Border&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;CollectionView&lt;/span&gt; &lt;span class="na"&gt;x:Name=&lt;/span&gt;&lt;span class="s"&gt;"List"&lt;/span&gt;
                    &lt;span class="na"&gt;Grid.Row=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
                    &lt;span class="na"&gt;ItemsSource=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BookGroups}"&lt;/span&gt;
                    &lt;span class="na"&gt;IsGrouped=&lt;/span&gt;&lt;span class="s"&gt;"True"&lt;/span&gt;
                    &lt;span class="na"&gt;SelectionMode=&lt;/span&gt;&lt;span class="s"&gt;"Multiple"&lt;/span&gt;
                    &lt;span class="na"&gt;ItemSizingStrategy=&lt;/span&gt;&lt;span class="s"&gt;"MeasureFirstItem"&lt;/span&gt;
                    &lt;span class="na"&gt;Scrolled=&lt;/span&gt;&lt;span class="s"&gt;"OnCollectionViewScrolled"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;CollectionView.GroupHeaderTemplate&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;DataTemplate&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;Grid&lt;/span&gt; &lt;span class="na"&gt;BackgroundColor=&lt;/span&gt;&lt;span class="s"&gt;"#f2f2f2"&lt;/span&gt; &lt;span class="na"&gt;Padding=&lt;/span&gt;&lt;span class="s"&gt;"12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;Label&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"{Binding Name}"&lt;/span&gt; &lt;span class="na"&gt;FontAttributes=&lt;/span&gt;&lt;span class="s"&gt;"Bold"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/Grid&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/DataTemplate&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/CollectionView.GroupHeaderTemplate&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/CollectionView&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Grid&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Loaded&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;OnLoaded&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnLoaded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;UpdateCurrentGroupHeader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnCollectionViewScrolled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ItemsViewScrolledEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;UpdateCurrentGroupHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstVisibleItemIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;UpdateCurrentGroupHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;firstVisibleIndex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Vm&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;Vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BookGroups&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;Vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BookGroups&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;firstVisibleIndex&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;firstVisibleIndex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Map to group by flattening groups until we cover firstVisibleIndex&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BookGroups&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;groupCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;groupCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentGroupName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;groupCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Fallback&lt;/span&gt;
    &lt;span class="n"&gt;Vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentGroupName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BookGroups&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Swipe actions
&lt;/h3&gt;

&lt;p&gt;Both controls support swipe gestures, but the way they implement and simplify quick actions differs significantly:&lt;/p&gt;

&lt;h4&gt;
  
  
  a) Syncfusion .NET MAUI ListView
&lt;/h4&gt;

&lt;p&gt;Swipe gestures reveal sleek, ready-to-use actions like &lt;strong&gt;Favorite&lt;/strong&gt; and &lt;strong&gt;Delete&lt;/strong&gt;. Templates keep the UI consistent, and commands bind directly to your ViewModel. The experience feels native across platforms.&lt;/p&gt;

&lt;p&gt;Refer to the following code example.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;listView:SfListView&lt;/span&gt; &lt;span class="na"&gt;x:Name=&lt;/span&gt;&lt;span class="s"&gt;"listView"&lt;/span&gt;
                      &lt;span class="na"&gt;ItemsSource=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BookInfo}"&lt;/span&gt;
                      &lt;span class="na"&gt;AllowSwiping=&lt;/span&gt;&lt;span class="s"&gt;"True"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;listView:SfListView.StartSwipeTemplate&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DataTemplate&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;Grid&lt;/span&gt; &lt;span class="na"&gt;BackgroundColor=&lt;/span&gt;&lt;span class="s"&gt;"#E8F5E9"&lt;/span&gt; &lt;span class="na"&gt;Padding=&lt;/span&gt;&lt;span class="s"&gt;"12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"Favourite"&lt;/span&gt;
                        &lt;span class="na"&gt;FontSize=&lt;/span&gt;&lt;span class="s"&gt;"12"&lt;/span&gt;
                        &lt;span class="na"&gt;Padding=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt;
                        &lt;span class="na"&gt;TextColor=&lt;/span&gt;&lt;span class="s"&gt;"White"&lt;/span&gt;
                        &lt;span class="na"&gt;BackgroundColor=&lt;/span&gt;&lt;span class="s"&gt;"#2E7032"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/Grid&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/DataTemplate&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/listView:SfListView.StartSwipeTemplate&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;listView:SfListView.EndSwipeTemplate&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DataTemplate&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;Grid&lt;/span&gt; &lt;span class="na"&gt;BackgroundColor=&lt;/span&gt;&lt;span class="s"&gt;"#FFEBEE"&lt;/span&gt; &lt;span class="na"&gt;Padding=&lt;/span&gt;&lt;span class="s"&gt;"12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"Delete"&lt;/span&gt;
                        &lt;span class="na"&gt;TextColor=&lt;/span&gt;&lt;span class="s"&gt;"White"&lt;/span&gt;
                        &lt;span class="na"&gt;BackgroundColor=&lt;/span&gt;&lt;span class="s"&gt;"#C62828"&lt;/span&gt;
                        &lt;span class="na"&gt;Command=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BindingContext.DeleteCommand, Source={x:Reference listView}}"&lt;/span&gt;
                        &lt;span class="na"&gt;CommandParameter=&lt;/span&gt;&lt;span class="s"&gt;"{Binding .}"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/Grid&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/DataTemplate&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/listView:SfListView.EndSwipeTemplate&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/listView:SfListView&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  b) .NET MAUI CollectionView
&lt;/h4&gt;

&lt;p&gt;You wrap each item in a Swipe View and define left/right actions yourself. Flexible, but repetitive, more template code for the same result.&lt;/p&gt;

&lt;p&gt;Here’s how to implement this feature:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;CollectionView&lt;/span&gt; &lt;span class="na"&gt;ItemsSource=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BookInfo}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;CollectionView.ItemTemplate&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;DataTemplate&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;SwipeView&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;SwipeView.LeftItems&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;SwipeItems&lt;/span&gt; &lt;span class="na"&gt;Mode=&lt;/span&gt;&lt;span class="s"&gt;"Reveal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;SwipeItem&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"Fav"&lt;/span&gt; &lt;span class="na"&gt;BackgroundColor=&lt;/span&gt;&lt;span class="s"&gt;"#FFE08A"&lt;/span&gt;
                       &lt;span class="na"&gt;Command=&lt;/span&gt;&lt;span class="s"&gt;"{Binding FavoriteCommand}"&lt;/span&gt; &lt;span class="na"&gt;CommandParameter=&lt;/span&gt;&lt;span class="s"&gt;"{Binding .}"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/SwipeItems&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/SwipeView.LeftItems&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;SwipeView.RightItems&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;SwipeItems&lt;/span&gt; &lt;span class="na"&gt;Mode=&lt;/span&gt;&lt;span class="s"&gt;"Reveal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;SwipeItem&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"Delete"&lt;/span&gt; &lt;span class="na"&gt;BackgroundColor=&lt;/span&gt;&lt;span class="s"&gt;"#FFCDD2"&lt;/span&gt;
                       &lt;span class="na"&gt;Command=&lt;/span&gt;&lt;span class="s"&gt;"{Binding DeleteCommand}"&lt;/span&gt; &lt;span class="na"&gt;CommandParameter=&lt;/span&gt;&lt;span class="s"&gt;"{Binding .}"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/SwipeItems&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/SwipeView.RightItems&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Grid&lt;/span&gt; &lt;span class="na"&gt;Padding=&lt;/span&gt;&lt;span class="s"&gt;"12,8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;Label&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BookName}"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&amp;lt;/Grid&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/SwipeView&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/DataTemplate&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/CollectionView.ItemTemplate&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/CollectionView&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Drag-and-drop reordering
&lt;/h3&gt;

&lt;p&gt;This feature shows a clear difference in how each control handles item movement and user interaction:&lt;/p&gt;

&lt;h4&gt;
  
  
  a) Syncfusion .NET MAUI ListView
&lt;/h4&gt;

&lt;p&gt;Reordering is built in. You can press, drag, and release; items move exactly where expected without juggling gestures or indexes, as shown in the code below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;listView:SfListView&lt;/span&gt; &lt;span class="na"&gt;x:Name=&lt;/span&gt;&lt;span class="s"&gt;"listView"&lt;/span&gt;
                      &lt;span class="na"&gt;ItemsSource=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BookInfo}"&lt;/span&gt;
                      &lt;span class="na"&gt;DragStartMode=&lt;/span&gt;&lt;span class="s"&gt;"OnHold"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  b) .NET MAUI CollectionView
&lt;/h4&gt;

&lt;p&gt;You wire up drag/drop events, manage indices, and refresh grouping after reordering. Powerful, but more moving parts.&lt;/p&gt;

&lt;p&gt;Here’s how you can do it in code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;CollectionView&lt;/span&gt; &lt;span class="na"&gt;x:Name=&lt;/span&gt;&lt;span class="s"&gt;"List"&lt;/span&gt;
                &lt;span class="na"&gt;Grid.Row=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
                &lt;span class="na"&gt;ItemsSource=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BookGroups}"&lt;/span&gt;
                &lt;span class="na"&gt;IsGrouped=&lt;/span&gt;&lt;span class="s"&gt;"True"&lt;/span&gt;
                &lt;span class="na"&gt;SelectionMode=&lt;/span&gt;&lt;span class="s"&gt;"Multiple"&lt;/span&gt;
                &lt;span class="na"&gt;ItemSizingStrategy=&lt;/span&gt;&lt;span class="s"&gt;"MeasureFirstItem"&lt;/span&gt;
                &lt;span class="na"&gt;Scrolled=&lt;/span&gt;&lt;span class="s"&gt;"OnCollectionViewScrolled"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;CollectionView.ItemTemplate&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DataTemplate&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;SwipeView&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;Grid&lt;/span&gt; &lt;span class="na"&gt;Padding=&lt;/span&gt;&lt;span class="s"&gt;"12"&lt;/span&gt; &lt;span class="na"&gt;RowDefinitions=&lt;/span&gt;&lt;span class="s"&gt;"Auto,Auto"&lt;/span&gt; &lt;span class="na"&gt;ColumnDefinitions=&lt;/span&gt;&lt;span class="s"&gt;"Auto,*"&lt;/span&gt; &lt;span class="na"&gt;HeightRequest=&lt;/span&gt;&lt;span class="s"&gt;"70"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;Grid.GestureRecognizers&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;DropGestureRecognizer&lt;/span&gt; &lt;span class="na"&gt;AllowDrop=&lt;/span&gt;&lt;span class="s"&gt;"True"&lt;/span&gt; &lt;span class="na"&gt;DragOver=&lt;/span&gt;&lt;span class="s"&gt;"OnDragOver"&lt;/span&gt; &lt;span class="na"&gt;Drop=&lt;/span&gt;&lt;span class="s"&gt;"OnDrop"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/Grid.GestureRecognizers&amp;gt;&lt;/span&gt;

                    &lt;span class="c"&gt;&amp;lt;!-- Drag handle icon --&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;Label&lt;/span&gt; &lt;span class="na"&gt;Grid.RowSpan=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt; &lt;span class="na"&gt;Grid.Column=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;VerticalOptions=&lt;/span&gt;&lt;span class="s"&gt;"Center"&lt;/span&gt; &lt;span class="na"&gt;Margin=&lt;/span&gt;&lt;span class="s"&gt;"0,0,8,0"&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"≡≡"&lt;/span&gt; &lt;span class="na"&gt;FontSize=&lt;/span&gt;&lt;span class="s"&gt;"18"&lt;/span&gt; &lt;span class="na"&gt;Opacity=&lt;/span&gt;&lt;span class="s"&gt;"0.6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;Label.GestureRecognizers&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;DragGestureRecognizer&lt;/span&gt; &lt;span class="na"&gt;CanDrag=&lt;/span&gt;&lt;span class="s"&gt;"True"&lt;/span&gt; &lt;span class="na"&gt;DragStarting=&lt;/span&gt;&lt;span class="s"&gt;"OnDragStarting"&lt;/span&gt; &lt;span class="na"&gt;DropCompleted=&lt;/span&gt;&lt;span class="s"&gt;"OnDropCompleted"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/Label.GestureRecognizers&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/Label&amp;gt;&lt;/span&gt;

                    &lt;span class="nt"&gt;&amp;lt;Label&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BookName}"&lt;/span&gt; &lt;span class="na"&gt;Grid.Row=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;Grid.Column=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;FontAttributes=&lt;/span&gt;&lt;span class="s"&gt;"Bold"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;Label&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BookDescription}"&lt;/span&gt; &lt;span class="na"&gt;Grid.Row=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;Grid.Column=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;Opacity=&lt;/span&gt;&lt;span class="s"&gt;"0.7"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/Grid&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/SwipeView&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/DataTemplate&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/CollectionView.ItemTemplate&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/CollectionView&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnDragStarting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DragStartingEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Element&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BindingContext&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;BookInfo&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"item"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnDrop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DropEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Vm&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TryGetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"item"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="n"&gt;BookInfo&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Element&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BindingContext&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;BookInfo&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;ReferenceEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BookInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sourceIndex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IndexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;targetIndex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IndexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sourceIndex&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;targetIndex&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Normalize target index when removing earlier item affects index&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sourceIndex&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;targetIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;targetIndex&lt;/span&gt;&lt;span class="p"&gt;--;&lt;/span&gt;

            &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RemoveAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sourceIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targetIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="c1"&gt;// Update stable order indices and rebuild grouping to reflect new order in the UI&lt;/span&gt;
            &lt;span class="n"&gt;Vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReindexOrders&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;Vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RefreshGroups&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Incremental loading
&lt;/h3&gt;

&lt;p&gt;Handling large datasets highlights how each control approaches infinite scrolling and data fetch efficiency:&lt;/p&gt;

&lt;h4&gt;
  
  
  a) Syncfusion .NET MAUI ListView
&lt;/h4&gt;

&lt;p&gt;Infinite scrolling is simple. The control fetches more items as you near the end, with a built-in busy indicator. A single command controls when and how much to load.&lt;/p&gt;

&lt;p&gt;Refer to the following code examples for feature implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;listView:SfListView&lt;/span&gt; &lt;span class="na"&gt;x:Name=&lt;/span&gt;&lt;span class="s"&gt;"listView"&lt;/span&gt;
                      &lt;span class="na"&gt;ItemsSource=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BookInfo}"&lt;/span&gt;
                      &lt;span class="na"&gt;LoadMoreOption=&lt;/span&gt;&lt;span class="s"&gt;"Manual"&lt;/span&gt;
                      &lt;span class="na"&gt;LoadMorePosition=&lt;/span&gt;&lt;span class="s"&gt;"End"&lt;/span&gt;
                      &lt;span class="na"&gt;LoadMoreCommand=&lt;/span&gt;&lt;span class="s"&gt;"{Binding LoadMoreItemsCommand}"&lt;/span&gt;
                      &lt;span class="na"&gt;LoadMoreCommandParameter=&lt;/span&gt;&lt;span class="s"&gt;"{Binding Source={x:Reference listView}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ICommand&lt;/span&gt; &lt;span class="n"&gt;LoadMoreItemsCommand&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;LoadMoreItemsCommand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;LoadMoreItems&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CanLoadMoreItems&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CanLoadMore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BookInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;totalItems&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CanLoadMoreItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CanLoadMore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;IsLoading&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;LoadMoreItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="nf"&gt;CanLoadMore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;IsLoading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;listView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsLazyLoading&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;listView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsLazyLoading&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;AddBooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PageSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;currentIndex&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;PageSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  b) .NET MAUI CollectionView
&lt;/h4&gt;

&lt;p&gt;You implement a “ &lt;strong&gt;Load More&lt;/strong&gt; ” footer and spinner, track remaining items, and manage progress state. Clear and explicit, but heavier on logic.&lt;/p&gt;

&lt;p&gt;Here’s the code you need for quick implementation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;CollectionView&lt;/span&gt; &lt;span class="na"&gt;x:Name=&lt;/span&gt;&lt;span class="s"&gt;"List"&lt;/span&gt;
                 &lt;span class="na"&gt;ItemsSource=&lt;/span&gt;&lt;span class="s"&gt;"{Binding BookGroups}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Manual Load More footer to mirror List View's LoadMoreOption=Manual at End --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;CollectionView.Footer&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Grid&lt;/span&gt; &lt;span class="na"&gt;Padding=&lt;/span&gt;&lt;span class="s"&gt;"12"&lt;/span&gt; &lt;span class="na"&gt;BackgroundColor=&lt;/span&gt;&lt;span class="s"&gt;"Transparent"&lt;/span&gt; &lt;span class="na"&gt;HorizontalOptions=&lt;/span&gt;&lt;span class="s"&gt;"Center"&lt;/span&gt; &lt;span class="na"&gt;RowDefinitions=&lt;/span&gt;&lt;span class="s"&gt;"Auto,Auto"&lt;/span&gt; &lt;span class="na"&gt;ColumnDefinitions=&lt;/span&gt;&lt;span class="s"&gt;"Auto,Auto"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt; &lt;span class="na"&gt;Text=&lt;/span&gt;&lt;span class="s"&gt;"Load More"&lt;/span&gt;
                    &lt;span class="na"&gt;Grid.Row=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;Grid.ColumnSpan=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;
                    &lt;span class="na"&gt;HorizontalOptions=&lt;/span&gt;&lt;span class="s"&gt;"Center"&lt;/span&gt;
                    &lt;span class="na"&gt;IsEnabled=&lt;/span&gt;&lt;span class="s"&gt;"{Binding HasMoreItems}"&lt;/span&gt;
                    &lt;span class="na"&gt;Command=&lt;/span&gt;&lt;span class="s"&gt;"{Binding LoadMoreItemsCommand}"&lt;/span&gt;
                    &lt;span class="na"&gt;CommandParameter=&lt;/span&gt;&lt;span class="s"&gt;"{Binding Source={x:Reference List}}"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;ActivityIndicator&lt;/span&gt; &lt;span class="na"&gt;Grid.Row=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;Grid.ColumnSpan=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;
                               &lt;span class="na"&gt;IsVisible=&lt;/span&gt;&lt;span class="s"&gt;"{Binding IsLoading}"&lt;/span&gt;
                               &lt;span class="na"&gt;IsRunning=&lt;/span&gt;&lt;span class="s"&gt;"{Binding IsLoading}"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/Grid&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/CollectionView.Footer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/CollectionView&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ICommand&lt;/span&gt; &lt;span class="n"&gt;LoadMoreItemsCommand&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;LoadMoreItemsCommand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;LoadMoreItems&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CanLoadMoreItems&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CanLoadMore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BookInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;totalItems&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CanLoadMoreItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CanLoadMore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;IsLoading&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;LoadMoreItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="nf"&gt;CanLoadMore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;IsLoading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// CollectionView path uses the footer ActivityIndicator bound to IsLoading&lt;/span&gt;
        &lt;span class="n"&gt;IsLoading&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;IsLoading&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;AddBooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PageSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;currentIndex&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;PageSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;RebuildGroups&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details, refer to the blog post at &lt;a href="https://www.syncfusion.com/blogs/post/dotnet-maui-listview-vs-collectionview" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>netmaui</category>
      <category>crossplatform</category>
      <category>desktop</category>
      <category>maui</category>
    </item>
    <item>
      <title>Spec-Driven Development with Markdown for AI Workflows </title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Thu, 02 Apr 2026 07:23:10 +0000</pubDate>
      <link>https://forem.com/syncfusion/spec-driven-development-with-markdown-for-ai-workflows-39c4</link>
      <guid>https://forem.com/syncfusion/spec-driven-development-with-markdown-for-ai-workflows-39c4</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Spec-driven development uses Markdown specifications and Code Studio prompt files as a single source of truth, letting AI reliably generate, test, review, and deploy code while preserving context. This blog shows practical prompt files and workflows, plus project structure and best practices for building a real-time project.&lt;/p&gt;

&lt;p&gt;AI revolutionizes software development but loses context between chats, forgets earlier architectural decisions, and produces contradictory implementations unless you keep re-explaining the same requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spec-driven development&lt;/strong&gt; treats Markdown specifications as your single source of truth. Rather than repeating requirements in AI conversations, you maintain a single living document that captures what your application does, how it behaves, and why.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.syncfusion.com/code-studio/" rel="noopener noreferrer"&gt;Syncfusion&lt;/a&gt;&lt;a href="https://www.syncfusion.com/document-sdk/net-word-library" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;sup&gt;®&lt;/sup&gt;&lt;/strong&gt;&lt;/a&gt;&lt;a href="https://www.syncfusion.com/code-studio/" rel="noopener noreferrer"&gt;Code Studio&lt;/a&gt; makes this even easier with a &lt;strong&gt;&lt;code&gt;prompt.md&lt;/code&gt;&lt;/strong&gt; files (and &lt;a href="https://help.syncfusion.com/code-studio/reference/configure-properties/custom-agents" rel="noopener noreferrer"&gt;Custom Agents&lt;/a&gt;), workflow files that tell your AI assistant exactly what to do at each development stage. This enables seamless specification-to-code compilation, code reviews, testing, and deployment workflows.&lt;/p&gt;

&lt;p&gt;This blog post will guide you through implementing a practical spec-to-code workflow using &lt;strong&gt;&lt;code&gt;prompt.md&lt;/code&gt;&lt;/strong&gt; templates while building a real-world analytics dashboard example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI-assisted development breaks down
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The core problem: AI context loss
&lt;/h3&gt;

&lt;p&gt;When working with traditional AI‑assisted development, the AI often generates code in isolation without retaining or referencing the broader project context.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Example&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You ask for a feature (e.g., authentication).&lt;/li&gt;
&lt;li&gt;The AI generates code in isolation.&lt;/li&gt;
&lt;li&gt;Later, you ask for changes, and the AI forgets earlier constraints (tenancy, RBAC, security rules, naming conventions).&lt;/li&gt;
&lt;li&gt;You repeat requirements and still get drift.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What is spec-driven development?
&lt;/h2&gt;

&lt;p&gt;Spec-driven development is a methodology where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The specification is the source code. Your Markdown files describe the complete application design (behavior, APIs, constraints, and acceptance criteria) in plain English mixed with structured data. AI generates implementation; Code Studio’s Custom Agents compile your specification into working code.&lt;/li&gt;
&lt;li&gt;Every AI task references the same spec. You reduce contradictions and rework.&lt;/li&gt;
&lt;li&gt;Documentation stays aligned. The spec evolves alongside the code rather than becoming stale.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;User:&lt;/strong&gt; Build me a user authentication module.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;AI:&lt;/strong&gt; &lt;em&gt;Generates authentication code&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Spec‐driven development ensures the AI always has access to the relevant specifications. This means the generated code is not only functional but also aligned with architectural requirements, security standards, and organizational workflows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# User Authentication Module Specification&lt;/span&gt;
&lt;span class="c"&gt;## Overview&lt;/span&gt;
Multi-tenant SaaS application requiring OAuth 2.0 with role-based access control &lt;span class="o"&gt;(&lt;/span&gt;RBAC&lt;span class="o"&gt;)&lt;/span&gt; 
across 10,000+ organizations.
&lt;span class="c"&gt;## RBAC Structure&lt;/span&gt;
- Organization Admin: Full access to org settings
- Team Lead: Manage team members and reports
- Member: Read-only access to team data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This format makes requirements explicit, so code generation and reviews can consistently validate against it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How spec-driven development with Markdown works in Code Studio
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What are prompt.md files?
&lt;/h3&gt;

&lt;p&gt;Prompt files are workflow specifications written in Markdown that tell Code Studio’s AI what to do at each stage of development. They are the primary tool for automating your development process.&lt;/p&gt;

&lt;p&gt;Key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repeatable instructions&lt;/strong&gt;: Store prompts and reusable specifications to ensure consistent execution across projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task automation&lt;/strong&gt;: Automate critical stages such as compilation, testing, code review, and deployment for faster delivery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool access&lt;/strong&gt;: Provide AI with direct access to file operations, terminal commands, and web search for comprehensive workflow support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable workflows&lt;/strong&gt;: Share and apply prompt files across teams and projects to standardize development practices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version control&lt;/strong&gt;: Manage and track prompt files in Git alongside source code for full history and collaboration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prompt.md file format (template)
&lt;/h3&gt;

&lt;p&gt;All prompt files follow this structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;---&lt;/span&gt;
name: prompt file name 
mode: agent
description: Brief description of what this prompt does
&lt;span class="nt"&gt;---&lt;/span&gt;

&lt;span class="c"&gt;# Main Task Title&lt;/span&gt;
Step-by-step instructions &lt;span class="k"&gt;for &lt;/span&gt;the AI.
- Use bullet points &lt;span class="k"&gt;for &lt;/span&gt;clarity
- Include specific file paths
- Reference specifications
- Define expected outputs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure is simple, but it’s the key to making AI output consistent and reviewable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spec-driven development with Markdown: Project setup (dashboard example)
&lt;/h2&gt;

&lt;p&gt;Creating a complete dashboard project with the help of &lt;strong&gt;&lt;code&gt;prompt.md&lt;/code&gt;&lt;/strong&gt; files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recommended project structure
&lt;/h3&gt;

&lt;p&gt;analytics-dashboard/&lt;br&gt;&lt;br&gt;
├──. codestudio/&lt;br&gt;&lt;br&gt;
│ └── prompts/&lt;br&gt;&lt;br&gt;
│ ├── compile.prompt.md&lt;br&gt;&lt;br&gt;
│ ├── lint.prompt.md&lt;br&gt;&lt;br&gt;
│ └── test.prompt.md&lt;br&gt;&lt;br&gt;
├── src/&lt;br&gt;&lt;br&gt;
│ ├── components/&lt;br&gt;&lt;br&gt;
│ │ ├── Dashboard.tsx&lt;br&gt;&lt;br&gt;
│ │ ├── Chart.tsx&lt;br&gt;&lt;br&gt;
│ │ └── Widget.tsx&lt;br&gt;&lt;br&gt;
│ └── types/&lt;br&gt;&lt;br&gt;
│ └── dashboard. types.ts&lt;br&gt;&lt;br&gt;
├── tests/&lt;br&gt;&lt;br&gt;
│ ├── dashboard.test.ts&lt;br&gt;&lt;br&gt;
│ └── api.test.ts&lt;br&gt;&lt;br&gt;
├── package. json&lt;br&gt;&lt;br&gt;
└── tsconfig. json&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Keep prompts in &lt;strong&gt;&lt;code&gt;.codestudio/prompts/&lt;/code&gt;&lt;/strong&gt; so they’re easy to find, review, and run consistently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create your prompt files
&lt;/h3&gt;

&lt;p&gt;To create Custom Prompts in Code Studio, follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Chat Window.&lt;/li&gt;
&lt;li&gt;Select Prompt Files.&lt;/li&gt;
&lt;li&gt;Click + New Prompt File and choose the location based on your preference.&lt;/li&gt;
&lt;li&gt;Type prompt file name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more insights, see our &lt;a href="https://help.syncfusion.com/code-studio/reference/configure-properties/custom-prompt" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; on configuring custom prompts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FCreating-Custom-Prompt-Files-in-Code-Studio.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F04%2FCreating-Custom-Prompt-Files-in-Code-Studio.gif" alt="Creating Custom Prompt Files in Code Studio" width="1920" height="1020"&gt;&lt;/a&gt;&lt;br&gt;Creating Custom Prompt Files in Code Studio
  &lt;/p&gt;

&lt;p&gt;Create the &lt;strong&gt;&lt;code&gt;.codestudio/prompts/&lt;/code&gt;&lt;/strong&gt; folder and create these files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;compile.prompt.md&lt;/code&gt;&lt;/strong&gt;: Compile spec to code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;dashboard.prompt.md&lt;/code&gt;&lt;/strong&gt;: The dashboard specification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;review.prompt.md&lt;/code&gt;&lt;/strong&gt;: Code review against spec.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;security.prompt.md&lt;/code&gt;&lt;/strong&gt;: Security audit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;test.prompt.md&lt;/code&gt;&lt;/strong&gt;: Test generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;lint-spec.prompt.md&lt;/code&gt;&lt;/strong&gt;: Spec linting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can find all these sample prompt files in this &lt;a href="https://github.com/syncfusion/code-studio-library/tree/master/prompts/sample-dashboard/" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more details, refer to the blog post at &lt;a href="https://www.syncfusion.com/blogs/post/ai-agents-vs-chatbots-key-differences" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codestudio</category>
      <category>aiassistant</category>
      <category>aichatbots</category>
      <category>aicodingtools</category>
    </item>
    <item>
      <title>AI Code Review in Code Studio: Instant Pre‑Commit Feedback that Cuts PR Churn</title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Tue, 17 Mar 2026 15:12:28 +0000</pubDate>
      <link>https://forem.com/syncfusion/ai-code-review-in-code-studio-instant-pre-commit-feedback-that-cuts-pr-churn-4g1h</link>
      <guid>https://forem.com/syncfusion/ai-code-review-in-code-studio-instant-pre-commit-feedback-that-cuts-pr-churn-4g1h</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; AI code review in Code Studio gives developers instant, in‑editor feedback &lt;em&gt;before&lt;/em&gt; opening a PR. Use #changes to analyze uncommitted diffs, run Custom Review Agents to enforce your team’s rules, and apply Inline Review suggestions directly in files. The result: fewer review cycles, more consistent standards, and cleaner pull requests.&lt;/p&gt;

&lt;p&gt;You just finished implementing a complex feature that spans 15 files across your codebase. The code works well, and all tests pass. You open a PR and wait. Review queues grow, context fades, and you switch tasks. The slow part isn’t writing code anymore. It’s getting solid review feedback fast.&lt;/p&gt;

&lt;p&gt;Sound familiar? You’re not alone.&lt;/p&gt;

&lt;p&gt;Code reviews are essential, but the traditional process often wastes valuable time. What if there were a better way, one that gives you instant, intelligent feedback without sacrificing code quality?&lt;/p&gt;

&lt;p&gt;That’s exactly what &lt;a href="https://www.syncfusion.com/code-studio/" rel="noopener noreferrer"&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt; Code Studio&lt;/a&gt; delivers. This guide will show you the practical ways to get instant, intelligent code reviews in Code Studio. You’ll learn how to review your code changes in seconds before committing, and create AI reviewers that remember and enforce your team’s specific coding standards.&lt;/p&gt;

&lt;p&gt;Code Studio brings all of this together, making the entire code review process faster, more consistent, and less frustrating.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a code review?
&lt;/h2&gt;

&lt;p&gt;At its core, a code review is a systematic examination of source code intended to find bugs, improve code quality, and share knowledge among team members. It’s a critical practice in modern software development in which one or more developers review code written by a peer before it’s merged into the main codebase.&lt;/p&gt;

&lt;p&gt;Here’s the typical manual flow many teams still rely on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developer writes code and creates a pull request (PR).&lt;/li&gt;
&lt;li&gt;Reviewer(s) are assigned (manually or automatically).&lt;/li&gt;
&lt;li&gt;Reviewers examine the changes line by line.&lt;/li&gt;
&lt;li&gt;They leave comments and suggestions directly on the diff.&lt;/li&gt;
&lt;li&gt;The author addresses feedback and pushes new commits.&lt;/li&gt;
&lt;li&gt;The review cycle repeats until approval.&lt;/li&gt;
&lt;li&gt;The final code is merged into the main branch.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why do we need code reviews?
&lt;/h2&gt;

&lt;p&gt;Every developer (junior or senior) benefits from consistent, thoughtful reviews. They help teams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Catch bugs early&lt;/strong&gt;: Bugs fixed during review take minutes. Bugs found in production cost time, money, and trust.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improve code quality&lt;/strong&gt;: Reviews promote best practices and maintain consistency. Code that makes sense today may confuse you or your teammates months later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Share knowledge:&lt;/strong&gt; Reviews spread context and patterns across the team. Junior developers learn faster, and experienced developers gain new perspectives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhance security:&lt;/strong&gt; Many security vulnerabilities are preventable with proper review.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduce technical debt:&lt;/strong&gt; Regular review prevents shortcuts from piling up into large refactoring projects later.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The hidden costs of traditional code reviews
&lt;/h2&gt;

&lt;p&gt;Before we dive into solutions, let’s examine the real pain points that plague modern development teams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The waiting game:&lt;/strong&gt; Manual reviews slow teams down. Senior developers get overloaded. Juniors wait for feedback. Work stalls, and release cycles stretch out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inconsistent standards:&lt;/strong&gt; Different reviewers catch different things. What one approves, another flags. Without consistent rules, technical debt grows quietly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation debt:&lt;/strong&gt; Most developers intend to update the documentation later, but later rarely comes. Missing documentation makes debugging and onboarding harder.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Enter Code Studio: Your AI-powered development partner
&lt;/h2&gt;

&lt;p&gt;Syncfusion Code Studio helps reduce these bottlenecks by bringing AI into your development workflow. It supports instant code reviews, team-specific review rules, and context-aware suggestions, all without replacing human judgment. To learn more about Code Studio, visit our &lt;a href="https://www.syncfusion.com/blogs/post/syncfusion-code-studio-2-next-gen-ai-ide" rel="noopener noreferrer"&gt;blog&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get instant code reviews in Code Studio
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What you need&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install and configure Code Studio using our installation &lt;a href="https://help.syncfusion.com/code-studio/getting-started/install-and-configuration" rel="noopener noreferrer"&gt;guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Install &lt;a href="https://git-scm.com/install/?utm_source=copilot.com" rel="noopener noreferrer"&gt;Git&lt;/a&gt; on your system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code Studio offers multiple ways to review your code. Choose the best way that fits you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instant Git diff review with ‘#changes’ tool
&lt;/h3&gt;

&lt;p&gt;Right before committing, you’ve changed several files, fixed a bug, added a feature, and refactored code. Then comes the doubt: Did I miss anything? Scanning the diff takes time, and you can still miss issues. Imagine if you could ask someone to review it all instantly.&lt;/p&gt;

&lt;p&gt;That’s exactly what &lt;strong&gt;&lt;code&gt;#changes&lt;/code&gt;&lt;/strong&gt; do in the Code Studio chat. Type &lt;strong&gt;&lt;code&gt;#changes&lt;/code&gt;&lt;/strong&gt; in the chat to analyze all uncommitted, staged, or unstaged changes, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code you added or modified.&lt;/li&gt;
&lt;li&gt;Code you deleted.&lt;/li&gt;
&lt;li&gt;Files you renamed or deleted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’ll get a concise summary, risk flags, and a suggested commit message. This keeps feedback where it belongs: &lt;strong&gt;before&lt;/strong&gt; the PR. For example, if you ask, “ &lt;strong&gt;What did I change?&lt;/strong&gt; “, it summarizes all modifications.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step-by-step guide to use #changes tool:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open your Git project&lt;/strong&gt;
To use the &lt;strong&gt;&lt;code&gt;#changes&lt;/code&gt;&lt;/strong&gt; tool, your project needs to be connected to Git.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Check whether your project folder contains a &lt;strong&gt;&lt;code&gt;.git&lt;/code&gt;&lt;/strong&gt; directory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open your project folder in your system’s file manager or Finder.&lt;/li&gt;
&lt;li&gt;Look for a &lt;strong&gt;&lt;code&gt;.git&lt;/code&gt;&lt;/strong&gt; folder in the project root.&lt;/li&gt;
&lt;li&gt;If it exists, Git is already initialized.&lt;/li&gt;
&lt;li&gt;Now open the same folder in &lt;strong&gt;Code Studio&lt;/strong&gt; (&lt;strong&gt;&lt;code&gt;File → Open Folder&lt;/code&gt;&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your project does NOT have Git initialized yet, follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open your project in Code Studio (&lt;strong&gt;&lt;code&gt;File → Open Folder&lt;/code&gt;&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Open the Terminal (
&lt;strong&gt;&lt;code&gt;Ctrl+&lt;/code&gt; (Windows`&lt;/strong&gt;) or &lt;strong&gt;&lt;code&gt;^+&lt;/code&gt; (macOS))`&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Type &lt;strong&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/strong&gt; and press Enter.&lt;/li&gt;
&lt;li&gt;That’s it — your project is now connected to Git.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you see an error while running the &lt;strong&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/strong&gt; command, reinstall Git and make sure to select the “Add Git to PATH” option during installation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Make your changes:&lt;/strong&gt; Edit your code as usual. Any staged or unstaged edits will be included when you run &lt;strong&gt;&lt;code&gt;#changes&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open chat panel:&lt;/strong&gt; Press &lt;strong&gt;&lt;code&gt;Ctrl+Shift+I&lt;/code&gt;&lt;/strong&gt; (Windows) or &lt;strong&gt;&lt;code&gt;cmd+Shift+I&lt;/code&gt;&lt;/strong&gt; (macOS) to open the chat view.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type &lt;code&gt;#&lt;/code&gt; in the chat:&lt;/strong&gt; A dropdown menu appears showing available options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select #changes:&lt;/strong&gt; Choose &lt;strong&gt;&lt;code&gt;#changes&lt;/code&gt;&lt;/strong&gt; from the dropdown to attach your Git diff as context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add your request:&lt;/strong&gt; Type your question or instructions you want the AI to analyze.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Submit:&lt;/strong&gt; The AI analyzes your Git diff and provides detailed feedback.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Example prompt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#changes Analyze my uncommitted changes and answer the following:
Questions to Address:
1. What are the main changes I made? Summarize the modifications by file and purpose.
2. What is the overall impact of these changes on the codebase?
3. Are there any obvious bugs, logic errors, or edge cases I might have missed?
4. Are there any files I modified that might need corresponding test updates?
5. Could any of these changes potentially break existing functionality?
6. What would be a clear, descriptive commit message for these changes?

Output Format:
- Start with a summary of what changed (2-3 sentences)
- Answer each question with specific file references 
- Highlight any concerns that need immediate attention
- Provide a recommended commit message at the end
Be conversational but thorough. Flag anything that looks suspicious or needs clarification.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCode-Review-using-changes-tool.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCode-Review-using-changes-tool.gif" alt="Code Review using #changes tool" width="720" height="679"&gt;&lt;/a&gt;&lt;br&gt;Code Review using #changes tool
  &lt;/p&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/ai-agents-vs-chatbots-key-differences" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codestudio</category>
      <category>aiagents</category>
      <category>aichatbots</category>
      <category>aicodeeditor</category>
    </item>
    <item>
      <title>AI Chatbots vs AI Agents: What Developers Should Build in 2026 </title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Thu, 12 Mar 2026 13:26:46 +0000</pubDate>
      <link>https://forem.com/syncfusion/ai-chatbots-vs-ai-agents-what-developers-should-build-in-2026-3md</link>
      <guid>https://forem.com/syncfusion/ai-chatbots-vs-ai-agents-what-developers-should-build-in-2026-3md</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; AI chatbots focus on conversational interfaces, while AI agents extend LLM capabilities with planning, tool usage, and autonomous task execution. Although both rely on similar AI models, their architectures and application patterns differ significantly. This guide compares chatbots and agents and helps developers decide which approach fits modern applications in 2026.&lt;/p&gt;

&lt;p&gt;Conversational interfaces are now standard in modern applications. Whether you’re building support tools, productivity apps, or internal systems, users expect natural language interaction.&lt;/p&gt;

&lt;p&gt;Early chatbots relied on rule-based logic and predefined flows. As NLP improved, chatbots became more flexible and could understand intent and generate natural responses.&lt;/p&gt;

&lt;p&gt;LLMs advanced this further, enabling chatbots capable of rich, contextual interaction. They also enabled something more powerful: &lt;strong&gt;AI agents&lt;/strong&gt;, which don’t just respond, but &lt;strong&gt;reason and act&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While both use LLMs, their architecture and purpose differ. This article explains those differences so you can choose the right approach for your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are AI Chatbots?
&lt;/h2&gt;

&lt;p&gt;An AI chatbot is software designed to simulate human conversation through natural language. Modern Chatbots use natural language processing (NLP) and large language models (LLMs) to understand queries and generate relevant responses.&lt;/p&gt;

&lt;p&gt;Unlike older rule-based predecessors, today’s AI chatbots:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand user intent from natural language (not just keywords).&lt;/li&gt;
&lt;li&gt;Maintain context across conversations.&lt;/li&gt;
&lt;li&gt;Generate dynamic, contextual responses.&lt;/li&gt;
&lt;li&gt;Pull data from backend systems when needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key characteristic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Chatbots are reactive. They respond to user messages but do not independently initiate complex actions or workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core architecture
&lt;/h3&gt;

&lt;p&gt;Most AI chatbot systems are built around these components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Natural Language Understanding (NLU)&lt;/strong&gt;
Processes user input to determine intent and extract entities.
Example: “What’s the status of my order?” → Order-status intent + order ID extraction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dialogue management&lt;/strong&gt;
Controls conversation flow and determines the next appropriate response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response generation&lt;/strong&gt;
Creates responses using templates, structured logic, or LLMs (increasingly common).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend integrations&lt;/strong&gt;
Accesses databases or APIs to retrieve information, such as order status.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example workflow
&lt;/h3&gt;

&lt;p&gt;User: “ &lt;strong&gt;Can you help me reset my password?&lt;/strong&gt; “:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;NLP layer interprets intent (&lt;strong&gt;&lt;code&gt;password_reset_request&lt;/code&gt;&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Dialogue manager determines the appropriate response path.&lt;/li&gt;
&lt;li&gt;System checks if additional info is needed (&lt;strong&gt;&lt;code&gt;email&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;username&lt;/code&gt;&lt;/strong&gt; ).&lt;/li&gt;
&lt;li&gt;Chatbot generates a response.&lt;/li&gt;
&lt;li&gt;If the user provides details, a backend API may be triggered.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The chatbot responds to user input, it does not proactively inspect account health or take independent action.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are AI Agents?
&lt;/h2&gt;

&lt;p&gt;An AI agent autonomously performs tasks, makes decisions, and interacts with external systems to achieve specific goals. They extend beyond conversation. They integrate with tools, execute actions, and operate with independence.&lt;/p&gt;

&lt;p&gt;Unlike chatbots that wait for prompts, AI agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plan multi-step tasks.&lt;/li&gt;
&lt;li&gt;Decide which tools or APIs to use.&lt;/li&gt;
&lt;li&gt;Execute actions across different systems.&lt;/li&gt;
&lt;li&gt;Remember previous interactions and outcomes.&lt;/li&gt;
&lt;li&gt;Adjust strategies based on results and feedback.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This enables agents to perform tasks requiring reasoning, planning, and iterative execution, not just respond to questions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Autonomous decision making&lt;/strong&gt;
Agents determine the steps required to complete a task without human instructions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Planning and reasoning&lt;/strong&gt;
LLMs help agents break down complex problems into actionable subtasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool usage&lt;/strong&gt;
Agents interact with APIs, databases, search engines, code interpreters, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory systems&lt;/strong&gt;
Agents store information beyond single conversations across tasks and sessions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution loops&lt;/strong&gt;
Agents continuously evaluate their progress and adjust actions until the task is completed. If one approach doesn’t work, they try another.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example scenario
&lt;/h3&gt;

&lt;p&gt;User: “&lt;strong&gt;Research the latest trends in AI developer tools and create a summary report.&lt;/strong&gt;”&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Plan the task:&lt;/strong&gt; Break it into subtasks, search for sources, identify trends, extract insights, compile a report.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execute searches:&lt;/strong&gt; Use web search tools to find recent articles, GitHub repos, and discussions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analyze the results:&lt;/strong&gt; Read through sources and extract key trends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synthesize findings:&lt;/strong&gt; Identify patterns and important developments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate the report:&lt;/strong&gt; Compile everything into a structured summary document.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deliver results:&lt;/strong&gt; Present the completed report to you.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This involves planning, tool usage, information synthesis, and content creation, far beyond chatbot capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Thank you for reading! AI chatbots and AI agents offer two distinct approaches to building intelligent systems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chatbots&lt;/strong&gt; support conversational UI and guided assistance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agents&lt;/strong&gt; enable autonomous, multi-step workflow execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Developers should choose based on the problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use chatbots for conversation.&lt;/li&gt;
&lt;li&gt;Use agents for automation and complex workflows.&lt;/li&gt;
&lt;li&gt;Use hybrid architectures when both are needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As AI evolves, the most effective applications will blend both approaches, delivering natural interaction and autonomous action.&lt;/p&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/ai-agents-vs-chatbots-key-differences" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aiagents</category>
      <category>aichatbots</category>
      <category>aitools</category>
    </item>
    <item>
      <title>How to Add Mentions and Slash Commands to a React Rich Text Editor</title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Wed, 11 Mar 2026 14:47:58 +0000</pubDate>
      <link>https://forem.com/syncfusion/how-to-add-mentions-and-slash-commands-to-a-react-rich-text-editor-jk8</link>
      <guid>https://forem.com/syncfusion/how-to-add-mentions-and-slash-commands-to-a-react-rich-text-editor-jk8</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Discover how Smart Suggestions (Slash Menu) and Mentions enhance the React Rich Text Editor’s workflow. The blog explains how slash-triggered commands improve formatting flow, how structured &lt;strong&gt;&lt;code&gt;@&lt;/code&gt;&lt;/strong&gt; tagging strengthens accuracy, and how these features together support smoother content creation, stronger collaboration, and a more intuitive editing experience in modern applications.&lt;/p&gt;

&lt;p&gt;Are you building a modern application that demands powerful, collaborative content tools? In today’s fast-paced digital landscape, content creation must be intuitive and efficient to meet workflow demands. The &lt;a href="https://www.syncfusion.com/react-components/react-rich-text-editor" rel="noopener noreferrer"&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt; Rich Text Editor&lt;/a&gt; makes content simple and efficient. Its &lt;strong&gt;Smart Suggestions&lt;/strong&gt; and &lt;strong&gt;Mentions&lt;/strong&gt; features improve formatting and collaboration, making it a great fit for blogs, forums, and messaging apps.&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll explore how Smart Suggestions and Mentions work, their key benefits, and share sample code to help you implement them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Smart Suggestions and Mentions matter
&lt;/h2&gt;

&lt;p&gt;Modern users expect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast actions without hunting through toolbars.&lt;/li&gt;
&lt;li&gt;Structured formatting with minimal effort.&lt;/li&gt;
&lt;li&gt;Accurate tagging inside collaborative environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Smart Suggestions and Mentions help achieve all of this by providing context-aware menus right where users type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Smart Suggestions (Slash Menu) in React Rich Text Editor
&lt;/h2&gt;

&lt;p&gt;Smart Suggestions, also known as the &lt;strong&gt;Slash Menu&lt;/strong&gt;, allow users to type &lt;strong&gt;&lt;code&gt;/&lt;/code&gt;&lt;/strong&gt; in the editor to open a quick command popup for actions such as applying headings, creating lists, or inserting media. This removes friction from formatting and makes content creation feel natural, especially for blogging and note-taking.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Smart Suggestions work
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trigger&lt;/strong&gt;: Type &lt;strong&gt;&lt;code&gt;/&lt;/code&gt;&lt;/strong&gt; inside the editor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Options&lt;/strong&gt;: A customizable list of commands (e.g., Paragraph, Headings, lists, media insertion, and more).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customization&lt;/strong&gt;: Configure via the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/rich-text-editor#slashmenusettings" rel="noopener noreferrer"&gt;slashMenuSettings&lt;/a&gt; class:

&lt;ul&gt;
&lt;li&gt;Enabling/disabling the feature.&lt;/li&gt;
&lt;li&gt;Define custom items using the items property.&lt;/li&gt;
&lt;li&gt;Handle custom actions with the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/rich-text-editor#slashmenuitemselect" rel="noopener noreferrer"&gt;slashMenuItemSelect&lt;/a&gt; event.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Enabling Smart Suggestions in React Rich Text Editor
&lt;/h3&gt;

&lt;p&gt;Here’s a quick example showing how to enable and customize the Slash Menu using Syncfusion’s React Rich Text Editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
   * Initialize Rich Text Editor from React element
   */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;HtmlEditor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;QuickToolbar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;RichTextEditorComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Toolbar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;EmojiPicker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;PasteCleanup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SlashMenu&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@syncfusion/ej2-react-richtexteditor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;editorObj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meetingNotes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;
        &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Meeting Notes&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
        &amp;lt;table class="e-rte-table" style="width: 100%; min-width: 0px; height: 150px;"&amp;gt;
            &amp;lt;tbody&amp;gt;
                &amp;lt;tr style="height: 20%;"&amp;gt;
                    &amp;lt;td style="width: 50%;"&amp;gt;&amp;lt;strong&amp;gt;Attendees&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;
                    &amp;lt;td style="width: 50%;" class=""&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/td&amp;gt;
                &amp;lt;/tr&amp;gt;
                &amp;lt;tr style="height: 20%;"&amp;gt;
                    &amp;lt;td style="width: 50%;"&amp;gt;&amp;lt;strong&amp;gt;Date &amp;amp; Time&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;
                    &amp;lt;td style="width: 50%;"&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/td&amp;gt;
                &amp;lt;/tr&amp;gt;
                &amp;lt;tr style="height: 20%;"&amp;gt;
                    &amp;lt;td style="width: 50%;"&amp;gt;&amp;lt;strong&amp;gt;Agenda&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;
                    &amp;lt;td style="width: 50%;"&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/td&amp;gt;
                &amp;lt;/tr&amp;gt;
                &amp;lt;tr style="height: 20%;"&amp;gt;
                    &amp;lt;td style="width: 50%;"&amp;gt;&amp;lt;strong&amp;gt;Discussed Items&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;
                    &amp;lt;td style="width: 50%;"&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/td&amp;gt; 
                &amp;lt;/tr&amp;gt;
                &amp;lt;tr style="height: 20%;"&amp;gt;
                    &amp;lt;td style="width: 50%;"&amp;gt;&amp;lt;strong&amp;gt;Action Items&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;
                    &amp;lt;td style="width: 50%;"&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/td&amp;gt;
                &amp;lt;/tr&amp;gt;
            &amp;lt;/tbody&amp;gt;
        &amp;lt;/table&amp;gt;
    &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toolbarSettings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Italic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Underline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StrikeThrough&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FontName&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FontSize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FontColor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BackgroundColor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Formats&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alignments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Blockquote&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NumberFormatList&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BulletFormatList&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CreateLink&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CreateTable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EmojiPicker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SourceCode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Undo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Redo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="c1"&gt;// Define custom Slash Menu items &lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;slashMenuSettings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Paragraph&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Heading 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Heading 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Heading 3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Heading 4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OrderedList&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UnorderedList&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Blockquote&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Table&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Emojipicker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Meeting notes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Insert a meeting note template.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;iconCss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;e-icons e-description&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Custom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MeetingNotes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// Handle custom Slash Menu item selection &lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onSlashMenuItemSelect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MeetingNotes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Insert custom meeting note &lt;/span&gt;
            &lt;span class="nx"&gt;editorObj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executeCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;insertHTML&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;meetingNotes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;RichTextEditorComponent&lt;/span&gt;
            &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;editorObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
            &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Type '/' and choose format&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;toolbarSettings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;toolbarSettings&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;slashMenuSettings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;slashMenuSettings&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;slashMenuItemSelect&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSlashMenuItemSelect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Inject&lt;/span&gt;
                &lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;
                    &lt;span class="nx"&gt;HtmlEditor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nx"&gt;SlashMenu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nx"&gt;Toolbar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nx"&gt;QuickToolbar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nx"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nx"&gt;PasteCleanup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nx"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nx"&gt;EmojiPicker&lt;/span&gt;
                &lt;span class="p"&gt;]}&lt;/span&gt;
            &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/RichTextEditorComponent&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Code explanation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://ej2.syncfusion.com/react/documentation/api/rich-text-editor/#slashmenusettings" rel="noopener noreferrer"&gt;&lt;strong&gt;slashMenuSettings&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;&lt;code&gt;enable: true&lt;/code&gt;&lt;/strong&gt; property activates the Slash Menu and injects the &lt;strong&gt;&lt;code&gt;SlashMenu&lt;/code&gt;&lt;/strong&gt; service into the editor.&lt;/li&gt;
&lt;li&gt;The items array defines the available commands, including default options like Paragraph and Heading 1, as well as custom items (e.g., &lt;strong&gt;&lt;code&gt;MeetingNotes&lt;/code&gt;&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://ej2.syncfusion.com/react/documentation/api/rich-text-editor/#slashmenuitemselect" rel="noopener noreferrer"&gt;&lt;strong&gt;slashMenuItemSelect&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;This event handler runs when a user selects an item from the Slash Menu.&lt;/li&gt;
&lt;li&gt;In the above code example, we check if the selected command is &lt;strong&gt;&lt;code&gt;MeetingNotes&lt;/code&gt;&lt;/strong&gt; and use &lt;a href="https://ej2.syncfusion.com/react/documentation/api/rich-text-editor/#executecommand" rel="noopener noreferrer"&gt;executeCommand&lt;/a&gt; method to insert a predefined HTML snippet.&lt;/li&gt;
&lt;li&gt;Developers can extend this logic to handle other custom actions, such as inserting templates, signatures, or dynamic content.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;For example, a content creator can type &lt;strong&gt;&lt;code&gt;/&lt;/code&gt;&lt;/strong&gt; select Heading 1 to format a title, or choose &lt;strong&gt;&lt;code&gt;MeetingNotes&lt;/code&gt;&lt;/strong&gt; to insert a predefined note, streamlining their workflow as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FMention-suggestions-are-displayed-after-typing-%40.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FMention-suggestions-are-displayed-after-typing-%40.gif" alt="Smart Suggestions menu displayed after typing “/” in the Rich Text Editor" width="1821" height="632"&gt;&lt;/a&gt;&lt;br&gt;Smart Suggestions menu displayed after typing “/” in the Rich Text Editor
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of Smart Suggestions
&lt;/h3&gt;

&lt;p&gt;Here are the key features that make this feature efficient.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Faster formatting&lt;/strong&gt;: Skip toolbars and format inline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contextual workflow&lt;/strong&gt;: Suggestions appear exactly where users type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizability&lt;/strong&gt;: Tailor the Slash Menu to include app-specific commands, like inserting signatures or templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ready to level up your editor? Explore the Smart Suggestions &lt;a href="https://ej2.syncfusion.com/react/demos/#/tailwind3/rich-text-editor/smart-suggestion" rel="noopener noreferrer"&gt;demo&lt;/a&gt; and &lt;a href="https://ej2.syncfusion.com/react/documentation/rich-text-editor/smart-editing/slash-menu" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; to start implementing and customizing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Mentions in React Rich Text Editor
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.syncfusion.com/react-components/react-mention" rel="noopener noreferrer"&gt;Mentions&lt;/a&gt; feature allows users to tag people, groups, or entities by typing &lt;strong&gt;&lt;code&gt;@&lt;/code&gt;&lt;/strong&gt;, triggering a suggestion list populated from a data source. This is perfect for collaborative applications like messaging apps, comment sections, or project management tools, ensuring accurate and efficient tagging.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Mentions work
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trigger&lt;/strong&gt;: Type &lt;strong&gt;&lt;code&gt;@&lt;/code&gt;&lt;/strong&gt; followed by a character to display the suggestion list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Source&lt;/strong&gt;: A list of objects (e.g., employee records with names, emails, and profile images).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customization&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;itemTemplate&lt;/strong&gt; to style the suggestion list.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;displayTemplate&lt;/strong&gt; to format tagged values.&lt;/li&gt;
&lt;li&gt;Properties like &lt;strong&gt;suggestionCount&lt;/strong&gt;, &lt;strong&gt;popupWidth&lt;/strong&gt;, and &lt;strong&gt;allowSpaces&lt;/strong&gt; provide further control.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Integrating Mentions in React Rich Text Editor
&lt;/h3&gt;

&lt;p&gt;Below is a React example showing how to integrate and customize the Mentions feature using Syncfusion’s React Rich Text Editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
   * Initialize Rich Text Editor from React element
   */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;HtmlEditor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;QuickToolbar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;RichTextEditorComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Toolbar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;EmojiPicker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;PasteCleanup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SlashMenu&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@syncfusion/ej2-react-richtexteditor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MentionComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@syncfusion/ej2-react-dropdowns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Sample data for Mentions &lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mentionData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Selma Rose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;EmailId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;selma@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Maria Smith&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;EmailId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;maria@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;EmailId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;john@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fieldsData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toolbarSettings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Italic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Underline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StrikeThrough&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FontName&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FontSize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FontColor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BackgroundColor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Formats&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alignments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Blockquote&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NumberFormatList&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BulletFormatList&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CreateLink&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CreateTable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EmojiPicker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SourceCode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Undo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Redo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;RichTextEditorComponent&lt;/span&gt;
                &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mentionRTE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;toolbarSettings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;toolbarSettings&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Type @ to tag a name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;toolbarSettings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;toolbarSettings&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Inject&lt;/span&gt;
                    &lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;
                        &lt;span class="nx"&gt;HtmlEditor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nx"&gt;Toolbar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nx"&gt;QuickToolbar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nx"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nx"&gt;PasteCleanup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nx"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nx"&gt;EmojiPicker&lt;/span&gt;
                    &lt;span class="p"&gt;]}&lt;/span&gt;
                &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/RichTextEditorComponent&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MentionComponent&lt;/span&gt;
                &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#mentionRTE_rte-edit-view&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mentionData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fieldsData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;suggestionCount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;popupWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;250px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;itemTemplate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;span&amp;gt;${Name} - ${EmailId}&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Code explanation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;mentionData&lt;/strong&gt;: A sample dataset containing objects with &lt;strong&gt;&lt;code&gt;Name&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;EmailId&lt;/code&gt;&lt;/strong&gt; fields for populating the suggestion list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fieldsData&lt;/strong&gt;: Specifies which field (Name) should be displayed in the suggestion list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MentionComponent&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The target property binds the Mentions feature to the Rich Text Editor’s editable area (e.g., &lt;strong&gt;&lt;code&gt;#mentionRTE_rte-edit-view&lt;/code&gt;&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt; &lt;a href="https://ej2.syncfusion.com/react/documentation/api/mention/#datasource" rel="noopener noreferrer"&gt;dataSource&lt;/a&gt; and fields properties link the component to the dataset.&lt;/li&gt;
&lt;li&gt; &lt;a href="https://ej2.syncfusion.com/react/documentation/api/mention/#suggestioncount" rel="noopener noreferrer"&gt;suggestionCount&lt;/a&gt; limits the number of suggestions displayed.&lt;/li&gt;
&lt;li&gt; &lt;a href="https://ej2.syncfusion.com/react/documentation/api/mention/#popupwidth" rel="noopener noreferrer"&gt;popupWidth&lt;/a&gt; sets the width of the suggestion list.&lt;/li&gt;
&lt;li&gt; &lt;a href="https://ej2.syncfusion.com/react/documentation/api/mention/#itemtemplate" rel="noopener noreferrer"&gt;itemTemplate&lt;/a&gt; customizes the suggestion list to show both name and email.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: In a team messaging app, typing &lt;strong&gt;&lt;code&gt;@Maria&lt;/code&gt;&lt;/strong&gt; displays a suggestion list with &lt;strong&gt;&lt;code&gt;Maria Smith - maria@example.com&lt;/code&gt;&lt;/strong&gt;, ensuring accurate tagging.&lt;/p&gt;

&lt;p&gt;Refer to the following image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FMention-suggestions-are-displayed-after-typing-%40-1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FMention-suggestions-are-displayed-after-typing-%40-1.gif" alt="Mention suggestions are displayed after typing “@”" width="1821" height="616"&gt;&lt;/a&gt;&lt;br&gt;Mention suggestions are displayed after typing “@”
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of Mentions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration&lt;/strong&gt;: Simplifies tagging team members, improving communication in collaborative tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accuracy&lt;/strong&gt;: Selecting from a predefined list reduces typing errors and ensures correct tagging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced UI&lt;/strong&gt;: Customizable suggestion lists with images or status indicators improve the visual experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Explore the Mentions &lt;a href="https://ej2.syncfusion.com/react/demos/#/tailwind3/rich-text-editor/mention-integration" rel="noopener noreferrer"&gt;demo&lt;/a&gt; and &lt;a href="https://ej2.syncfusion.com/react/documentation/rich-text-editor/smart-editing/mentions" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for detailed steps on implementing and customizing this feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-world applications
&lt;/h2&gt;

&lt;p&gt;The combination of &lt;strong&gt;Smart Suggestions&lt;/strong&gt; and &lt;strong&gt;Mentions&lt;/strong&gt; makes the Rich Text Editor ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blogging platforms&lt;/strong&gt;: Use Smart Suggestions to format posts quickly and Mentions to tag contributors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration tools&lt;/strong&gt;: Tag team members in comments or notes for seamless communication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support ticket systems&lt;/strong&gt;: Assign tasks with Mentions and insert predefined responses with Smart Suggestions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. What is the difference between Smart Suggestions (Slash Menu) and Mentions?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Smart Suggestions are triggered by typing &lt;code&gt;/&lt;/code&gt; and help with formatting actions like adding headings, lists, or inserting templates. Mentions are triggered by typing &lt;code&gt;@&lt;/code&gt; and are used to tag people, entities, or items from a data source within the editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Can I create my own custom Smart Suggestion (Slash Menu) commands?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes. You can fully customize the Slash Menu by adding your own items with text, icons, descriptions, and actions. Using the &lt;strong&gt;&lt;code&gt;slashMenuSettings.items&lt;/code&gt;&lt;/strong&gt; property and handling the &lt;strong&gt;&lt;code&gt;slashMenuItemSelect&lt;/code&gt;&lt;/strong&gt; event, you can insert templates, dynamic HTML, signatures, or any custom content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Does the Mentions feature work with dynamic data from APIs?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Absolutely. Mentions can use any data source, static arrays, remote data, REST APIs, or databases. Bind the &lt;strong&gt;&lt;code&gt;dataSource&lt;/code&gt;&lt;/strong&gt; of the &lt;strong&gt;&lt;code&gt;MentionComponent&lt;/code&gt;&lt;/strong&gt; to your dynamic data and map fields like text, value, or email using the fields property.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Can I customize how Mention items appear in the suggestion list?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes. Mentions support multiple presentation options: Custom &lt;code&gt;itemTemplate&lt;/code&gt; for list appearance and Custom &lt;code&gt;displayTemplate&lt;/code&gt; for how selected mentions appear inside the editor&lt;br&gt;&lt;br&gt;
You can include profile images, roles, email IDs, statuses, or any custom UI element.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Thanks for reading! The &lt;strong&gt;Smart Suggestions&lt;/strong&gt; and &lt;strong&gt;Mentions&lt;/strong&gt; features in &lt;a href="https://www.syncfusion.com/react-components/react-rich-text-editor" rel="noopener noreferrer"&gt;Syncfusion Rich Text Editor&lt;/a&gt; transform content creation by making it faster, more intuitive, and collaborative.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smart Suggestions&lt;/strong&gt; reduce clicks with quick formatting commands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mentions&lt;/strong&gt; ensure accurate, structured tagging in collaborative environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both features are highly customizable, flexible, and ready for real-world applications.&lt;br&gt;&lt;br&gt;
Try them out to elevate your content creation experience today!&lt;/p&gt;

&lt;p&gt;If you’re a Syncfusion user, you can download the setup from the &lt;a href="https://www.syncfusion.com/sales/pricing" rel="noopener noreferrer"&gt;license and downloads&lt;/a&gt; page. Otherwise, you can download a free &lt;a href="https://www.syncfusion.com/downloads/" rel="noopener noreferrer"&gt;30-day trial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also contact us through our &lt;a href="https://www.syncfusion.com/forums" rel="noopener noreferrer"&gt;support forum&lt;/a&gt;, &lt;a href="https://support.syncfusion.com/" rel="noopener noreferrer"&gt;support portal&lt;/a&gt;, or &lt;a href="https://www.syncfusion.com/feedback" rel="noopener noreferrer"&gt;feedback portal&lt;/a&gt; for queries. We are always happy to assist you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Blogs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/react-rich-text-editor-xss-prevention" rel="noopener noreferrer"&gt;How to Prevent XSS Attacks in React Rich Text Editor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/merge-fields-in-react-rich-text-editor" rel="noopener noreferrer"&gt;How to Use Merge Fields in React Rich Text Editor for Dynamic Content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/emojis-in-react-rich-text-editor" rel="noopener noreferrer"&gt;Introducing Emoji Icons Support in the React Rich Text Editor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/integrate-react-image-editor-into-rich-text-editor" rel="noopener noreferrer"&gt;Easily Integrate the React Image Editor into the Rich Text Editor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/react-rich-text-editor-mentions" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>autocomplete</category>
      <category>mentions</category>
      <category>richtexteditor</category>
    </item>
    <item>
      <title>Prevent Connector Overlap in React Diagrams with Smart Line Routing</title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Tue, 10 Mar 2026 12:31:05 +0000</pubDate>
      <link>https://forem.com/syncfusion/prevent-connector-overlap-in-react-diagrams-with-smart-line-routing-4p27</link>
      <guid>https://forem.com/syncfusion/prevent-connector-overlap-in-react-diagrams-with-smart-line-routing-4p27</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Connector lines overlapping all over your diagram? This guide shows how to clean them up using Syncfusion React Diagram’s AvoidLineOverlapping with LineRouting. Learn how to keep connectors smart, readable, and neatly routed, complete with a copy-ready example you can plug into workflow, flowchart, or circuit-style diagrams.&lt;/p&gt;

&lt;p&gt;Readable diagrams are essential when working on workflow designers, circuit editors, process maps, or architecture visualizations. Without clarity, even the best UI becomes frustrating to use. As the number of connections grows, connectors often stack on the same route, creating visual noise.&lt;/p&gt;

&lt;p&gt;This guide shows how to prevent overlapping connector lines in React diagrams using the  &lt;a href="https://ej2.syncfusion.com/react/documentation/diagram/connectors#avoid-line-overlapping" rel="noopener noreferrer"&gt;AvoidLineOverlapping&lt;/a&gt; API in &lt;a href="https://www.syncfusion.com/react-components/react-diagram" rel="noopener noreferrer"&gt;Syncfusion&lt;sup&gt;® &lt;/sup&gt;React Diagram&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is line overlapping (and why it hurts UX)?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Line overlapping&lt;/strong&gt;  happens when multiple connectors take the same (or nearly the same) route between nodes. When lines sit directly on top of each other, users can’t tell which connector goes where.&lt;/p&gt;

&lt;p&gt;You’ll see this often in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repetitive data flows (many nodes sharing the same upstream/downstream path).&lt;/li&gt;
&lt;li&gt;Multi-bit circuit diagrams (parallel signals).&lt;/li&gt;
&lt;li&gt;Dense process maps.&lt;/li&gt;
&lt;li&gt;Diagrams with lots of “fan-in / fan-out” connections.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Syncfusion avoids connector overlap
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;AvoidLineOverlapping&lt;/code&gt;&lt;/strong&gt; reduces clutter by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detecting when orthogonal connector segments overlap.&lt;/li&gt;
&lt;li&gt;Applying small  &lt;strong&gt;offsets/detours&lt;/strong&gt;  so each connector gets a distinct visible path.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It typically re-runs when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You add new connectors.&lt;/li&gt;
&lt;li&gt;You move nodes.&lt;/li&gt;
&lt;li&gt;Multiple connectors share the same corridor.&lt;/li&gt;
&lt;li&gt;Layout updates occur.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Cleaner diagrams with less manual connector nudging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you start:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; and &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;NPM&lt;/a&gt; packages.&lt;/li&gt;
&lt;li&gt;Install Syncfusion &lt;a href="https://www.npmjs.com/package/@syncfusion/ej2-react-diagrams" rel="noopener noreferrer"&gt;React Diagram Library&lt;/a&gt; (@syncfusion/ej2-react-diagrams).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; New to Syncfusion React Diagram? Start with the official getting-started &lt;a href="https://ej2.syncfusion.com/react/documentation/diagram/getting-started" rel="noopener noreferrer"&gt;guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration checklist (required)
&lt;/h2&gt;

&lt;p&gt;Before implementing the Avoid Line Overlapping feature, ensure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Enable routing in diagram constraints&lt;/strong&gt;
You need routing enabled via constraints ( &lt;strong&gt;&lt;code&gt;LineRouting&lt;/code&gt;&lt;/strong&gt; ), as shown in the code snippet below:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;DiagramConstraints&lt;/span&gt; &lt;span class="n"&gt;diagramConstraints&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DiagramConstraints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;DiagramConstraints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LineRouting&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use orthogonal connectors&lt;/strong&gt;
&lt;strong&gt;&lt;code&gt;AvoidLineOverlapping&lt;/code&gt;&lt;/strong&gt; is designed for &lt;strong&gt;orthogonal&lt;/strong&gt; routing. Ensure your connectors are set to use orthogonal paths.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to prevent connector overlap in React Diagram
&lt;/h2&gt;

&lt;p&gt;Add &lt;a href="https://ej2.syncfusion.com/react/documentation/api/diagram/diagramconstraints" rel="noopener noreferrer"&gt;DiagramConstraints.AvoidLineOverlapping&lt;/a&gt; to your &lt;a href="https://ej2.syncfusion.com/react/documentation/api/diagram/index-default" rel="noopener noreferrer"&gt;DiagramComponent&lt;/a&gt; and inject the required services. This configuration ensures that your diagrams automatically manage connector paths to prevent overlapping without manual intervention.&lt;/p&gt;

&lt;p&gt;Here’s how you can do it in code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;AvoidLineOverlapping&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ConnectorModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;DiagramComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;DiagramConstraints&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LineRouting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;NodeModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;PointPortModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;PortVisibility&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ShapeAnnotationModel&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@syncfusion/ej2-react-diagrams&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DiagramComponent&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;diagram&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                  &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;diagramRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                  &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                  &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;580&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                  &lt;span class="nx"&gt;constraints&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;DiagramConstraints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;DiagramConstraints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LineRouting&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;DiagramConstraints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AvoidLineOverlapping&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                  &lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                  &lt;span class="nx"&gt;connectors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;connectors&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Inject&lt;/span&gt; &lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="nx"&gt;LineRouting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AvoidLineOverlapping&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Snapping&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Inject&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/DiagramComponent&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;DiagramConstraints.LineRouting&lt;/code&gt;&lt;/strong&gt; turns on routing logic for connectors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;DiagramConstraints.AvoidLineOverlapping&lt;/code&gt;&lt;/strong&gt; offsets connectors when overlaps are detected.&lt;/li&gt;
&lt;li&gt;Inject registers the runtime services needed for routing and overlap avoidance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Complete example: custom nodes, ports, and orthogonal connectors
&lt;/h2&gt;

&lt;p&gt;The code example below shows a practical setup where ports and orthogonal connectors are defined explicitly, common in circuit-style or workflow-style diagrams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;AvoidLineOverlapping&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ConnectorModel&lt;/span&gt;
    &lt;span class="nx"&gt;DiagramComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;DiagramConstraints&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;LineRouting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;NodeModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PointPortModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;PortVisibility&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Snapping&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@syncfusion/ej2-react-diagrams&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createPort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;offsetX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;offsetY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;PointPortModel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;offsetX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;offsetY&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="na"&gt;visibility&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PortVisibility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Visible&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;AvoidOverlapDiagram&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NodeModel&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;offsetX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;offsetY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Node A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
            &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="nf"&gt;createPort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A_out1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="nf"&gt;createPort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A_out2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.65&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;offsetX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;offsetY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Node B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
            &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="nf"&gt;createPort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B_in1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="nf"&gt;createPort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B_in2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.65&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connectors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ConnectorModel&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;c1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;sourceID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;sourcePortID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A_out1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;targetID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;targetPortID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B_in1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Orthogonal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;c2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;sourceID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;sourcePortID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A_out2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;targetID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;targetPortID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B_in2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Orthogonal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DiagramComponent&lt;/span&gt;
            &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;diagram&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;700px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;580px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;connectors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;connectors&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;constraints&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;DiagramConstraints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="nx"&gt;DiagramConstraints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LineRouting&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="nx"&gt;DiagramConstraints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AvoidLineOverlapping&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Inject&lt;/span&gt; &lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="nx"&gt;LineRouting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AvoidLineOverlapping&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Snapping&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/DiagramComponent&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What to notice:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Both connectors would naturally try to share a similar route between Node A and Node B.&lt;/li&gt;
&lt;li&gt;With &lt;strong&gt;&lt;code&gt;AvoidLineOverlapping&lt;/code&gt;&lt;/strong&gt;, the component offsets them so both paths remain visible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why this feature matters (practical wins)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Better readability:&lt;/strong&gt; Users can trace each connection without guessing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less manual cleanup:&lt;/strong&gt; Connectors adjust when nodes move, or new links appear.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scales to dense diagrams:&lt;/strong&gt; Helpful for fan-in/fan-out patterns and multi-connector corridors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPreventing-connector-overlap-in-React-Diagram.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPreventing-connector-overlap-in-React-Diagram.gif" alt="Preventing connector overlap in React Diagram" width="800" height="480"&gt;&lt;/a&gt;&lt;br&gt;Preventing connector overlap in React Diagram
  &lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub reference
&lt;/h2&gt;

&lt;p&gt;For a complete working sample, refer to the &lt;a href="https://github.com/syncfusion/ej2-react-samples/blob/master/src/diagram/avoid-connector-overlap-functional.tsx" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; demo to avoid line overlapping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Does AvoidLineOverlapping work with all connector types?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; No. &lt;strong&gt;&lt;code&gt;AvoidLineOverlapping&lt;/code&gt;&lt;/strong&gt; is designed specifically for &lt;strong&gt;Orthogonal&lt;/strong&gt; connectors. If your connectors use &lt;strong&gt;Straight&lt;/strong&gt; or &lt;strong&gt;Bezier&lt;/strong&gt; routing, the overlap‑avoidance logic will not apply.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Will enabling AvoidLineOverlapping affect diagram performance?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; In large diagrams with many connectors, enabling &lt;strong&gt;&lt;code&gt;AvoidLineOverlapping&lt;/code&gt;&lt;/strong&gt; may introduce &lt;strong&gt;slight routing overhead&lt;/strong&gt; because the algorithm recalculates and offsets connectors dynamically. However, in typical workflow and process diagram scenarios, the performance impact is minimal and optimized to run efficiently with LineRouting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Do connectors automatically re-adjust when nodes move?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes. When a node is moved, resized, or new connectors are added, the &lt;strong&gt;&lt;code&gt;AvoidLineOverlapping&lt;/code&gt; logic re-runs&lt;/strong&gt;. This ensures connectors continuously avoid overlapping without requiring manual adjustments from the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Thank you for reading! To prevent connector &lt;a href="https://ej2.syncfusion.com/react/documentation/diagram/connectors#avoid-line-overlapping" rel="noopener noreferrer"&gt;overlapping&lt;/a&gt; in &lt;a href="https://www.syncfusion.com/react-components/react-diagram" rel="noopener noreferrer"&gt;React Diagram&lt;/a&gt;, enable  &lt;strong&gt;LineRouting&lt;/strong&gt;, use  &lt;strong&gt;orthogonal connectors&lt;/strong&gt;, and turn on  &lt;strong&gt;AvoidLineOverlapping&lt;/strong&gt;. You’ll get cleaner visuals with far less manual connector work, especially as your diagrams scale in complexity.&lt;/p&gt;

&lt;p&gt;For deeper configuration options, see the official  &lt;strong&gt;Syncfusion React Diagram&lt;/strong&gt; &lt;a href="https://ej2.syncfusion.com/react/documentation/diagram/getting-started" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you’re a Syncfusion user, you can download the setup from the &lt;a href="https://www.syncfusion.com/sales/pricing" rel="noopener noreferrer"&gt;license and downloads&lt;/a&gt; page. Otherwise, you can download a free &lt;a href="https://www.syncfusion.com/downloads/" rel="noopener noreferrer"&gt;30-day trial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also contact us through our &lt;a href="https://www.syncfusion.com/forums" rel="noopener noreferrer"&gt;support forum&lt;/a&gt;, &lt;a href="https://support.syncfusion.com/" rel="noopener noreferrer"&gt;support portal&lt;/a&gt;, or &lt;a href="https://www.syncfusion.com/feedback" rel="noopener noreferrer"&gt;feedback portal&lt;/a&gt; for queries. We are always happy to assist you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Blogs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/react-text-to-flowchart-converter" rel="noopener noreferrer"&gt;Build AI-Powered Text-to-Flowchart Converter Using OpenAI and React Diagram Library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/uml-activity-diagram-in-react-diagram" rel="noopener noreferrer"&gt;Easily Create UML Activity Diagrams with React Diagram Library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/ai-assisted-mind-map-in-react-diagram" rel="noopener noreferrer"&gt;Create AI-Assisted Mind Maps Using OpenAI and React Diagram Library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/create-uml-class-diagrams-in-react" rel="noopener noreferrer"&gt;Build Interactive UML Class Diagrams in React&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/prevent-connector-overlap-react-diagram" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>datavisualization</category>
      <category>diagram</category>
      <category>diagramconnectorover</category>
    </item>
    <item>
      <title>AI-Powered DOCX Editor in React: Writing Assistance, Document Summaries &amp; Contextual Q&amp;A</title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Tue, 10 Mar 2026 11:46:39 +0000</pubDate>
      <link>https://forem.com/syncfusion/ai-powered-docx-editor-in-react-writing-assistance-document-summaries-contextual-qa-3a0a</link>
      <guid>https://forem.com/syncfusion/ai-powered-docx-editor-in-react-writing-assistance-document-summaries-contextual-qa-3a0a</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Learn to bring AI directly into the Syncfusion React DOCX Editor, so users can generate content, clean up their writing, summarize long documents, and ask natural questions without ever leaving the editor. We’ll also see how to plug in your own AI service (thanks to BYOK flexibility) while keeping full control of our data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why modern document editing needs more than just typing
&lt;/h2&gt;

&lt;p&gt;Modern document creation has moved far beyond basic typing and formatting. Today’s users expect their editor to actually help them to generate content, improve clarity, translate text, summarize long sections, and let them interact with their documents more intelligently. Jumping between multiple apps to handle these tasks disrupts focus and slows down productivity.&lt;/p&gt;

&lt;p&gt;To make this experience feel seamless, the Syncfusion&lt;sup&gt;®&lt;/sup&gt; &lt;a href="https://www.syncfusion.com/docx-editor-sdk/react-docx-editor" rel="noopener noreferrer"&gt;React DOCX Editor&lt;/a&gt; offers APIs that let developers embed powerful AI capabilities directly into the editing workflow, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI-powered content generation,&lt;/li&gt;
&lt;li&gt;Refinement,&lt;/li&gt;
&lt;li&gt;Summarization,&lt;/li&gt;
&lt;li&gt;Translation,&lt;/li&gt;
&lt;li&gt;Context-aware Q&amp;amp;A&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI results are inserted straight into the document through the editor, so the output blends naturally with existing content and formatting. The AI interaction interface, prompts, summarization, translation, rewriting panels, and more are built at the application level, giving you full control over the experience.&lt;/p&gt;

&lt;p&gt;Let’s see why integrating AI into the Syncfusion &lt;strong&gt;React DOCX Editor&lt;/strong&gt; is valuable, the intelligent capabilities you can add, and how these enhancements make modern document workflows smoother and far more efficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why integrating AI into a DOCX Editor is a game-changer
&lt;/h2&gt;

&lt;p&gt;Integrating AI into a  &lt;strong&gt;DOCX editor&lt;/strong&gt; workflow is all about saving time, reducing manual effort, and improving the overall writing and editing experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Generate document content faster&lt;/strong&gt; using short prompts, no external tools or app switching required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improve writing quality instantly&lt;/strong&gt; with AI-assisted rewriting, grammar correction, and tone adjustment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Summarize long documents with AI&lt;/strong&gt; or ask natural language questions to extract key insights without reading everything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stay in your workflow;&lt;/strong&gt; all AI-assisted results are delivered directly into the document through the editor, keeping the experience seamless and uninterrupted.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Building an AI‑powered React DOCX Editor
&lt;/h2&gt;

&lt;p&gt;Let’s follow these steps to integrate AI services in &lt;a href="https://help.syncfusion.com/document-processing/word/word-processor/react/overview" rel="noopener noreferrer"&gt;Syncfusion React DOCX Editor&lt;/a&gt; SDK:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Set up the React project
&lt;/h3&gt;

&lt;p&gt;Start by creating a &lt;a href="https://help.syncfusion.com/document-processing/word/word-processor/react/getting-started#setup-for-local-development" rel="noopener noreferrer"&gt;React project&lt;/a&gt; and installing the required dependencies using the following commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BASH&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create vite@latest ai-docx-editor &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--template&lt;/span&gt; react
&lt;span class="nb"&gt;cd &lt;/span&gt;ai-docx-editor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, install the Syncfusion React DOCX Editor and the required AI libraries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BASH&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @syncfusion/ej2-react-documenteditor &lt;span class="nt"&gt;--save&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;openai &lt;span class="nt"&gt;--save&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Configuring the AI service
&lt;/h3&gt;

&lt;p&gt;Set up the AI service by specifying the required resource name, providing the API key for authentication, and selecting the AI model you wish to use.&lt;/p&gt;

&lt;p&gt;The following code initializes the AI service and defines a utility function to handle requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;generateText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createGoogleGenerativeAI&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@ai-sdk/google&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createAzure&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@ai-sdk/azure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createOpenAI&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@ai-sdk/openai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// For Google Gemini AI&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;google&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createGoogleGenerativeAI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://generativelanguage.googleapis.com/v1beta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;API_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// For Azure OpenAI&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;azure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createAzure&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;resourceName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RESOURCE_NAME&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;API_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// For Groq&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;groq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createOpenAI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.groq.com/openai/v1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;API_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;aiModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;azure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MODEL_NAME&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Update the model here&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getAzureChatAIRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;generateText&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;aiModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;topP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;topP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;maxOutputTokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxTokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;frequencyPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frequencyPenalty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;presencePenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;presencePenalty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;stopSequences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stopSequences&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error occurred:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Configure the Syncfusion React DOCX Editor for visualization
&lt;/h3&gt;

&lt;p&gt;The Syncfusion React DOCX Editor allows users to create, edit, view, and print Word documents in web applications. It runs entirely on the client side, resulting in faster, smoother editing.&lt;/p&gt;

&lt;p&gt;Inside the &lt;strong&gt;&lt;code&gt;App.jsx&lt;/code&gt;&lt;/strong&gt; file, import, and configure the Syncfusion React DOCX Editor component. This component acts as the main workspace for document editing in your app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;DocumentEditorContainerComponent&lt;/span&gt;
                    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"document-editor"&lt;/span&gt;
                    &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;{container}&lt;/span&gt;
                    &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"100%"&lt;/span&gt;
                    &lt;span class="na"&gt;serviceUrl=&lt;/span&gt;&lt;span class="s"&gt;{SERVICE_URL}&lt;/span&gt;
                    &lt;span class="na"&gt;enableToolbar=&lt;/span&gt;&lt;span class="s"&gt;{true}&lt;/span&gt;
                    &lt;span class="na"&gt;toolbarMode=&lt;/span&gt;&lt;span class="s"&gt;'Ribbon'&lt;/span&gt;
                    &lt;span class="na"&gt;enableSpellCheck=&lt;/span&gt;&lt;span class="s"&gt;{true}&lt;/span&gt;
                    &lt;span class="na"&gt;created=&lt;/span&gt;&lt;span class="s"&gt;{onContainerCreated}/&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Create AI assistant buttons
&lt;/h3&gt;

&lt;p&gt;Let’s create two buttons for the AI-assisted services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first button will be placed inside the content area. It will help users generate new content and refine existing content using AI.&lt;/li&gt;
&lt;li&gt;The second button will appear in the bottom-right corner of the Syncfusion React DOCX Editor. Users will use it to access AI-powered summarization and Q&amp;amp;A features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;FabComponent&lt;/span&gt;
  &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;{assistFabRef}&lt;/span&gt;
  &lt;span class="na"&gt;cssClass=&lt;/span&gt;&lt;span class="s"&gt;"ai-assist-btn"&lt;/span&gt;
  &lt;span class="na"&gt;iconCss=&lt;/span&gt;&lt;span class="s"&gt;"e-icons e-ai-assist-btn"&lt;/span&gt;
  &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;{isSmartEditor&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="err"&gt;"Refine&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;content"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;"Generate&lt;/span&gt; &lt;span class="err"&gt;new&lt;/span&gt; &lt;span class="err"&gt;content"}&lt;/span&gt;
  &lt;span class="na"&gt;visible=&lt;/span&gt;&lt;span class="s"&gt;{fabAssistVisible}&lt;/span&gt;
  &lt;span class="na"&gt;onMouseDown=&lt;/span&gt;&lt;span class="s"&gt;{(e)&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; {
    e.preventDefault();
    e.stopPropagation();
  }}
  onClick={openAssistMenu}
  style={{
    position: "absolute",
    left: `${assistBtn.left}px`,
    top: `${assistBtn.top}px`,
    width: `${assistBtn.width}px`,
    height: `${assistBtn.height}px`,
  }}/&amp;gt;

&lt;span class="nt"&gt;&amp;lt;FabComponent&lt;/span&gt;
  &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;{chatFabRef}&lt;/span&gt;
  &lt;span class="na"&gt;cssClass=&lt;/span&gt;&lt;span class="s"&gt;"ai-chat-btn"&lt;/span&gt;
  &lt;span class="na"&gt;iconCss=&lt;/span&gt;&lt;span class="s"&gt;"e-icons e-ai-chat-btn"&lt;/span&gt;
  &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Summarization and Q&amp;amp;A"&lt;/span&gt;
  &lt;span class="na"&gt;visible=&lt;/span&gt;&lt;span class="s"&gt;{fabChatVisible}&lt;/span&gt;
  &lt;span class="na"&gt;created=&lt;/span&gt;&lt;span class="s"&gt;{onChatFabCreated}&lt;/span&gt;
  &lt;span class="na"&gt;onClick=&lt;/span&gt;&lt;span class="s"&gt;{openChat}/&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refer to the following image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCreating-AI-assisted-buttons-for-document-processing.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCreating-AI-assisted-buttons-for-document-processing.png" alt="Creating AI-assisted buttons for document processing" width="800" height="484"&gt;&lt;/a&gt;&lt;br&gt;Creating AI-assisted buttons for document processing
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: AI-powered content generation using React Document Editor
&lt;/h3&gt;

&lt;p&gt;To generate content using AI, we’ll create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A dialog with a textbox for the user to enter input,&lt;/li&gt;
&lt;li&gt;A settings icon to set the tone, length, and format of the result to be generated, and&lt;/li&gt;
&lt;li&gt;A send icon to submit the input to the AI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once content is generated, the user can enter a short instruction to expand or refine it, and the system will generate an updated result as needed. Also, we’ll implement the &lt;strong&gt;“Keep it”&lt;/strong&gt;, &lt;strong&gt;“Regenerate”&lt;/strong&gt;, and &lt;strong&gt;“Discard”&lt;/strong&gt; buttons in the same dialog footer to seamlessly manage the generated content.&lt;/p&gt;

&lt;p&gt;See the code example for generating content using AI in the DOCX Editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;DialogComponent&lt;/span&gt;
  &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;{genDialogRef}&lt;/span&gt;
  &lt;span class="na"&gt;visible=&lt;/span&gt;&lt;span class="s"&gt;{genVisible}&lt;/span&gt;
  &lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;"#ai-assist"&lt;/span&gt;
  &lt;span class="na"&gt;header=&lt;/span&gt;&lt;span class="s"&gt;{isContentGenerated&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="err"&gt;"Generate&lt;/span&gt; &lt;span class="err"&gt;content"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;undefined}&lt;/span&gt;
  &lt;span class="na"&gt;footerTemplate=&lt;/span&gt;&lt;span class="s"&gt;{isContentGenerated&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="err"&gt;generateFooterTemplate&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;undefined}&lt;/span&gt;
  &lt;span class="na"&gt;position=&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt; &lt;span class="err"&gt;X:&lt;/span&gt; &lt;span class="err"&gt;dialogPos.x,&lt;/span&gt; &lt;span class="err"&gt;Y:&lt;/span&gt; &lt;span class="err"&gt;dialogPos.y&lt;/span&gt; &lt;span class="err"&gt;}}&lt;/span&gt;
  &lt;span class="na"&gt;showCloseIcon=&lt;/span&gt;&lt;span class="s"&gt;{false}&lt;/span&gt;
  &lt;span class="na"&gt;isModal=&lt;/span&gt;&lt;span class="s"&gt;{false}&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"45%"&lt;/span&gt;
  &lt;span class="na"&gt;beforeOpen=&lt;/span&gt;&lt;span class="s"&gt;{generateContentOpen}&lt;/span&gt;
  &lt;span class="na"&gt;cssClass=&lt;/span&gt;&lt;span class="s"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;isContentGenerated&lt;/span&gt;
      &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="err"&gt;"ai-rewrite-dialog&lt;/span&gt; &lt;span class="err"&gt;ai-assist-dialog"&lt;/span&gt;
      &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;"ai-generate-dialog&lt;/span&gt; &lt;span class="err"&gt;ai-assist-dialog"&lt;/span&gt;
  &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"ai-dialog-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"ai-generate-content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"e-de-parent gc-row ai-gc-row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"ai-input-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;TextBoxComponent&lt;/span&gt;
            &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;{textboxRef}&lt;/span&gt;
            &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"e-de-editableDiv"&lt;/span&gt;
            &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Type a prompt"&lt;/span&gt;
            &lt;span class="na"&gt;cssClass=&lt;/span&gt;&lt;span class="s"&gt;"ai-input-box"&lt;/span&gt;
            &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;{userPrompt}&lt;/span&gt;
            &lt;span class="na"&gt;input=&lt;/span&gt;&lt;span class="s"&gt;{textboxValueChange}&lt;/span&gt;
            &lt;span class="na"&gt;created=&lt;/span&gt;&lt;span class="s"&gt;{TextBoxCreated}&lt;/span&gt;
            &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
            &lt;span class="na"&gt;onFocus=&lt;/span&gt;&lt;span class="s"&gt;{floatFocus}&lt;/span&gt;
            &lt;span class="na"&gt;onBlur=&lt;/span&gt;&lt;span class="s"&gt;{floatBlur}&lt;/span&gt;
            &lt;span class="na"&gt;onKeyDown=&lt;/span&gt;&lt;span class="s"&gt;{(e)&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; {
              if (e.key === "Enter" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; userPrompt?.trim()) {
                e.preventDefault();
                onSend();
              }
            }}/&amp;gt;

        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DropDownButtonComponent&lt;/span&gt;
          &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;{gearRef}&lt;/span&gt;
          &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"ai-assist-settings-btn"&lt;/span&gt;
          &lt;span class="na"&gt;iconCss=&lt;/span&gt;&lt;span class="s"&gt;"e-icons e-settings"&lt;/span&gt;
          &lt;span class="na"&gt;cssClass=&lt;/span&gt;&lt;span class="s"&gt;"e-caret-hide settings-btn"&lt;/span&gt;
          &lt;span class="na"&gt;beforeOpen=&lt;/span&gt;&lt;span class="s"&gt;{(args)&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; {
            args.cancel = true;
            openGearMenu();
          }}/&amp;gt;

      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/DialogComponent&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See the outputs in the following images.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCustomizing-the-settings-for-content-generation.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCustomizing-the-settings-for-content-generation.png" alt="Customizing the settings for content generation" width="800" height="365"&gt;&lt;/a&gt;&lt;br&gt;Customizing the settings for content generation
  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FAI-powered-content-generation-in-Syncfusion-React-DOCX-Editor.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FAI-powered-content-generation-in-Syncfusion-React-DOCX-Editor.png" alt="AI-powered content generation in Syncfusion React DOCX Editor" width="800" height="380"&gt;&lt;/a&gt;&lt;br&gt;AI-powered content generation in Syncfusion React DOCX Editor
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: AI-powered content refinement: Rewrite, fix grammar, and translate
&lt;/h3&gt;

&lt;p&gt;Let’s design the context menu to display the AI writing refinement options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rewriting&lt;/strong&gt;: to rephrase existing content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grammar:&lt;/strong&gt; To automatically detect and fix grammar issues, and the&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Translation:&lt;/strong&gt; To convert selected text into other languages for multilingual document editing and cross‑team collaboration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the user selects any of these options, a dialog opens to handle the chosen AI refinement task. In the dialog, we’ll show the selected existing content in the top pane and the AI‑generated result in the bottom pane for a clear comparison.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Rewrite&lt;/strong&gt; option includes a &lt;strong&gt;Settings&lt;/strong&gt; icon within the dialog to configure the tone, length, and format of the rewritten output.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Grammar Fix&lt;/strong&gt; option displays a list of grammar issues so that the user can choose which corrections should be applied in the dialog. We’ll also include the &lt;strong&gt;Replace&lt;/strong&gt; and &lt;strong&gt;Cancel&lt;/strong&gt; buttons in the dialog footer to either apply the AI‑refined content to the document or cancel the action.&lt;/p&gt;

&lt;p&gt;For both the &lt;strong&gt;Rewrite&lt;/strong&gt; and &lt;strong&gt;Grammar Fix&lt;/strong&gt; dialogs, a &lt;strong&gt;Regenerate&lt;/strong&gt; button is available so users can generate improved results after adjusting tone, length, format, or selected grammar corrections.&lt;/p&gt;

&lt;p&gt;Refer to the code example for implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// To show the refinement option&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ContextMenuComponent&lt;/span&gt;
  &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cmAssistRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;cssClass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ai-smart-menu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;menuItems&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onMenuSelect&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// For the refinement option’s dialog&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DialogComponent&lt;/span&gt;
  &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;smartDialogRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;visible&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;smartVisible&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ai-assist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;smartHeaderTemplate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;footerTemplate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;smartFooterTemplate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;showCloseIcon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;isModal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;70%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setSmartVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
  &lt;span class="nx"&gt;cssClass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-smart-editor-dialog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ai-dialog-body&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SplitterComponent&lt;/span&gt;
      &lt;span class="nx"&gt;orientation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Vertical&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="nx"&gt;separatorSize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`ai-splitter e-vertical-smart &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
        &lt;span class="nx"&gt;popupType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;AiTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Rephrase&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-smart-rephrase&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;popupType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;AiTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Translate&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-smart-translate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-smart-grammar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PanesDirective&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PaneDirective&lt;/span&gt;
          &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;50%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pane-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pane-content-header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;translate-label&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;popupType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;AiTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Translate&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Translate from:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;From:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/label&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
                &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pane-text-area&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;inHtml&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PaneDirective&lt;/span&gt;
          &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;50%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pane-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pane-content-header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;translate-label&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;popupType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;AiTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Translate&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Translate to:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;To:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/label&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;popupType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;AiTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Translate&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ComboBoxComponent&lt;/span&gt;
                    &lt;span class="nx"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;TranslateList&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;translateTo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;changeLanguage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;160px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Translate to&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;popupHeight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;220px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;showClearButton&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="p"&gt;)}&lt;/span&gt;

                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;popupType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;AiTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Grammar&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MultiSelectComponent&lt;/span&gt;
                    &lt;span class="nx"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;GrammarOptions&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
                    &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;checks&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setChecks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[])}&lt;/span&gt;
                    &lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CheckBox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;showSelectAll&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;showDropDownIcon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;allowFiltering&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e.g. Spelling Errors&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;180px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;popupHeight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;260px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Inject&lt;/span&gt; &lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="nx"&gt;CheckBoxSelection&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/MultiSelectComponent&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="p"&gt;)}&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
                &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-de-editableDiv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pane-text-area&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;outHtml&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/PanesDirective&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SplitterComponent&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;spinner-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;spinner-target&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/DialogComponent&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refer to the following images for visual clarity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FContext-menu-displaying-the-refinement-options.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FContext-menu-displaying-the-refinement-options.png" alt="Context menu displaying the refinement options" width="800" height="380"&gt;&lt;/a&gt;&lt;br&gt;Context menu displaying the refinement options
  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FAI-powered-content-refinement-in-Syncfusion-React-DOCX-Editor.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FAI-powered-content-refinement-in-Syncfusion-React-DOCX-Editor.png" alt="AI-powered content refinement in Syncfusion React DOCX Editor" width="800" height="380"&gt;&lt;/a&gt;&lt;br&gt;AI-powered content refinement in Syncfusion React DOCX Editor
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: AI- powered document summarization and intelligent Q&amp;amp;A
&lt;/h3&gt;

&lt;p&gt;Let’s implement the code for AI-powered content summarization and contextual Q&amp;amp;A.&lt;/p&gt;

&lt;p&gt;Here, when the user clicks the &lt;strong&gt;Summarization&lt;/strong&gt; button, a chat panel will open with a default prompt, &lt;strong&gt;“Summarize this document,”&lt;/strong&gt; to help generate a concise summary of lengthy content and highlight the main ideas.&lt;/p&gt;

&lt;p&gt;Also, we’ll include a textbox for the user to enter a general &lt;strong&gt;intelligent question&lt;/strong&gt; or a question related to the document’s content, along with a &lt;strong&gt;send&lt;/strong&gt; button to submit the request to the AI service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AIAssistViewComponent&lt;/span&gt;
  &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;assistInstance&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;cssClass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-aiassist-chat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;promptPlaceholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Type a question&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;promptSuggestions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;aiSuggestions&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;promptIconCss&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-icons e-aiassist-chat-icon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;responseIconCss&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-aiassist-chat-icon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;chatPanelCreated&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;toolbarSettings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;iconCss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-icons e-close&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Right&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;tooltipText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Close&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="nx"&gt;bannerTemplate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ai-assist-banner&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-icons e-aiassist-page-icon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-aiassist-page-header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;How&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;I&lt;/span&gt; &lt;span class="nx"&gt;help&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)}&lt;/span&gt;
  &lt;span class="nx"&gt;promptRequest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Summarize this document&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;documentContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getDocumentText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Prepare the prompt for summarization&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You are a helpful assistant. Your task is to analyze the provided text and generate short summary. Always respond in proper HTML format, but do not include &amp;lt;html&amp;gt;, &amp;lt;head&amp;gt;, or &amp;lt;body&amp;gt; tags.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;documentContent&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;summaryHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getAzureChatAIRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;summaryHtml&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;p&amp;gt;No summary available.&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;assistInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPromptResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;suggestionsRaw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getAzureChatAIRequest&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You are a helpful assistant. Your task is to analyze the provided text and generate 3 short diverse questions and each question should not exceed 10 words&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;documentContent&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;suggestionsRaw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;suggestionsRaw&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;\.\s&lt;/span&gt;&lt;span class="sr"&gt;*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;setAiSuggestions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;// Prepare the prompt for Q&amp;amp;A&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You are a helpful assistant. Use the provided context to answer the user question. Always respond in proper HTML format, but do not include &amp;lt;html&amp;gt;, &amp;lt;head&amp;gt;, or &amp;lt;body&amp;gt; tags. Context:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;answerHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getAzureChatAIRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answerHtml&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;p&amp;gt;No answer.&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;assistInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPromptResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;p class="aiassist-error"&amp;gt;AI error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="nx"&gt;responseToolbarSettings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;iconCss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-icons e-copy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;tooltip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;copy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;iconCss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-btn-icon e-de-ctnr-new&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;tooltip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;insert&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;itemClicked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;dataIndex&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataIndex&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;assistInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;prompts&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;assistInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;prompts&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;resHtml&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resHtml&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;plainText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;tooltip&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tip&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;copy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clipboard&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ClipboardItem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blobHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;resHtml&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blobText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

          &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clipboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ClipboardItem&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blobHtml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blobText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}),&lt;/span&gt;
          &lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clipboard&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;writeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tip&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;insert&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;editor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;documentEditor&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ViewsDirective&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ViewDirective&lt;/span&gt;
      &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AI Assistant&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="nx"&gt;iconCss&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e-icons e-aiassist-chat-header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ViewsDirective&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/AIAssistViewComponent&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FAI-powered-content-summarization-in-Syncfusion-DOCX-Editor.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FAI-powered-content-summarization-in-Syncfusion-DOCX-Editor.png" alt="AI-powered content summarization in Syncfusion DOCX Editor" width="800" height="382"&gt;&lt;/a&gt;&lt;br&gt;AI-powered content summarization in Syncfusion DOCX Editor
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8: Integrating AI for results
&lt;/h3&gt;

&lt;p&gt;Here’s the code to prepare the prompt from the user’s input according to the chosen AI service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Develop your prompt based on the chosen AI option here`&lt;/span&gt; 
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Handle the user input here&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, implement the code to send the request to AI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getAzureChatAIRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s insert the AI‑generated content into the content area for the AI content generation option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;insertContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canceledRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;closeStopDialog&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;setInHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;setOutHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;editorRef&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;documentEditor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;ed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focusIn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;caretEndBefore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getOffsets&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;caretEndBefore&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;selectOffsets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;caretEndBefore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;caretEndBefore&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;plain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;htmlToPlain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canceledRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nx"&gt;ed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plain&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;ed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;endAfter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getOffsets&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;caretEndBefore&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="nx"&gt;endAfter&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="nx"&gt;endAfter&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;caretEndBefore&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;selectOffsets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;caretEndBefore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;endAfter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setDraftRange&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;caretEndBefore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;endAfter&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setDraftRange&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Insert failed: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;setUserPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, replace the selected text with the AI result for AI writing refinement options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;replaceSelectionWithPlainText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="se"&gt;[^&lt;/span&gt;&lt;span class="sr"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&amp;gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;editor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;editorRef&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;documentEditor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;insertText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Replace failed: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, copy the result from the chat panel or insert it into the DOCX Editor for Summarization and Q&amp;amp;A options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tip&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;copy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clipboard&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ClipboardItem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blobHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;resHtml&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blobText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clipboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ClipboardItem&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blobHtml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blobText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clipboard&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;writeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tip&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;insert&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;editor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;documentEditor&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Bring Your Own Key (BYOK): Use your own AI model
&lt;/h2&gt;

&lt;p&gt;The Syncfusion DOCX Editor uses a &lt;strong&gt;Bring Your Own Key (BYOK)&lt;/strong&gt; model for AI integration. Developers can connect their own AI service, such as  &lt;strong&gt;OpenAI, Azure OpenAI, or any custom LLM,&lt;/strong&gt;  with no lock-in to a specific provider.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can use your  &lt;strong&gt;own AI service API key&lt;/strong&gt;. Syncfusion does not provide or manage AI credentials.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can also choose the &lt;strong&gt;AI model&lt;/strong&gt; that best fits our use case, such as GPT-4, Claude, Gemini, or others.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You retain  &lt;strong&gt;complete flexibility&lt;/strong&gt;  to switch AI providers at any time without changing the editor integration.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Data privacy and security in AI-assisted DOCX editing
&lt;/h2&gt;

&lt;p&gt;AI support in the DOCX Editor is designed with privacy and control at the core.&lt;br&gt;&lt;br&gt;
All AI communication happens through your app, ensuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Syncfusion never accesses or stores&lt;/strong&gt;  your prompts, AI responses, or document content.&lt;/li&gt;
&lt;li&gt;All data remains  &lt;strong&gt;fully within your own environment&lt;/strong&gt; , suitable for  &lt;strong&gt;GDPR-compliant&lt;/strong&gt;  and  &lt;strong&gt;enterprise document workflows.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You retain  &lt;strong&gt;complete control over how AI requests are routed and processed&lt;/strong&gt;, with no third-party data exposure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup keeps your documents secure and gives you complete control, making it safe to use AI even in sensitive or regulated scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started: Syncfusion React DOCX Editor with AI Integration
&lt;/h2&gt;

&lt;p&gt;Refer to our &lt;a href="https://github.com/SyncfusionExamples/ai-powered-react-docx-editor-sample" rel="noopener noreferrer"&gt;GitHub example&lt;/a&gt; that demonstrates how to build an app-level AI interaction UI, including prompt input, summarization, translation, and rewriting panels with the Syncfusion React DOCX Editor. The sample shows how AI-generated results are bound and inserted into the document through the editor’s API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. How to enable the AI in this DOCX Editor?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; You can enable AI by using the AI Enabled option available at the top-right of the editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Does the DOCX Editor include built‑in AI?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; No, the DOCX Editor does not include built‑in AI. Developers integrate their own AI service using an API key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. How to set the tone, format, and length for AI results?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; While generating or rewriting content, you can adjust tone, format, and length by clicking the settings icon before sending the AI request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Which AI services can I use with the DOCX Editor?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; You can connect any AI provider that exposes an API—such as OpenAI, Azure OpenAI, or a custom LLM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Where does AI processing happen?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; All AI processing happens in your application layer, not inside the editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Can the AI interaction UI be customized?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes. The AI input panel and controls are fully customizable since they are implemented at the application level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Do AI features require internet access?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; AI features require internet access only if the chosen AI provider requires connectivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Thanks for reading! AI is now a core expectation in modern document workflows. The Syncfusion &lt;a href="https://www.syncfusion.com/docx-editor-sdk/react-docx-editor" rel="noopener noreferrer"&gt;React DOCX Editor&lt;/a&gt; with AI integration gives developers a production-ready foundation to embed  &lt;strong&gt;AI content generation&lt;/strong&gt;, &lt;strong&gt;grammar correction&lt;/strong&gt;, &lt;strong&gt;document summarization&lt;/strong&gt;, and &lt;strong&gt;intelligent **&lt;/strong&gt; Q&amp;amp;A** directly into their apps, with full control over the AI provider, data privacy, and security.&lt;/p&gt;

&lt;p&gt;Whether you’re building an  &lt;strong&gt;enterprise document editor&lt;/strong&gt;, a  &lt;strong&gt;SaaS writing tool&lt;/strong&gt;, or a  &lt;strong&gt;collaborative document platform&lt;/strong&gt;, the DOCX Editor provides the API infrastructure to make it happen.&lt;/p&gt;

&lt;p&gt;You can also try the core editing features of the Syncfusion DOCX Editor in your browser, the &lt;a href="https://www.syncfusion.com/free-tools/online-docx-editor/" rel="noopener noreferrer"&gt;free online editor&lt;/a&gt; lets you create, format, and export high‑quality DOCX documents instantly, no setup, downloads, or sign‑in required.&lt;/p&gt;

&lt;p&gt;If you’re a Syncfusion user, you can download the setup from the &lt;a href="https://www.syncfusion.com/account/downloads" rel="noopener noreferrer"&gt;license and downloads&lt;/a&gt; page. Otherwise, you can download a free &lt;a href="https://www.syncfusion.com/downloads/" rel="noopener noreferrer"&gt;30-day trial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also contact us through our &lt;a href="https://www.syncfusion.com/forums" rel="noopener noreferrer"&gt;support forum&lt;/a&gt;, &lt;a href="https://support.syncfusion.com/" rel="noopener noreferrer"&gt;support portal&lt;/a&gt;, or &lt;a href="https://www.syncfusion.com/feedback" rel="noopener noreferrer"&gt;feedback portal&lt;/a&gt; for queries. We are always happy to assist you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Blogs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/open-and-render-docx-files-with-react" rel="noopener noreferrer"&gt;How to Open and Render DOCX Files in the Browser with React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/embed-docx-editor-in-web-page" rel="noopener noreferrer"&gt;How to Embed a DOCX Editor in a Web Page Using React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/embed-docx-editor-in-react" rel="noopener noreferrer"&gt;Embed a DOCX Editor in React for Seamless Word Document Editing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/react-docx-editor-auto-save-with-postgresql" rel="noopener noreferrer"&gt;Auto Save Documents in React DOCX Editor with PostgreSQL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/ai-in-docx-editor-generate-refine-summarize" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>documenteditor</category>
      <category>smartcomponents</category>
      <category>word</category>
    </item>
    <item>
      <title>How to Export Excel, CSV, and PDF Files from a React Spreadsheet</title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Wed, 04 Mar 2026 18:46:37 +0000</pubDate>
      <link>https://forem.com/syncfusion/how-to-export-excel-csv-and-pdf-files-from-a-react-spreadsheet-e2k</link>
      <guid>https://forem.com/syncfusion/how-to-export-excel-csv-and-pdf-files-from-a-react-spreadsheet-e2k</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Learn how to export spreadsheet data from React applications to Excel, CSV, and PDF formats using an enterprise-ready Spreadsheet component from Syncfusion. This guide covers exporting via ribbon UI and programmatic save methods, customizing output with beforeSave and saveComplete events, and optimizing performance using server-side processing or Docker-based deployment for large datasets.&lt;/p&gt;

&lt;p&gt;Exporting spreadsheet data is a must-have feature in modern React apps, dashboards, reports, admin tools, and internal data workflows all need it. Users expect to download data for sharing, analysis, and archiving.&lt;/p&gt;

&lt;p&gt;This guide shows how to export Excel, CSV, and PDF in React using the &lt;a href="https://www.syncfusion.com/spreadsheet-editor-sdk/react-spreadsheet-editor" rel="noopener noreferrer"&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt; React Spreadsheet&lt;/a&gt; in two common ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ribbon UI&lt;/strong&gt; (end-user driven).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom export&lt;/strong&gt; with the &lt;strong&gt;&lt;code&gt;save()&lt;/code&gt;&lt;/strong&gt; method (developer controlled).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You’ll also learn how to customize exports with &lt;strong&gt;&lt;code&gt;beforeSave&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;saveComplete&lt;/code&gt;&lt;/strong&gt; for better performance and more control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Syncfusion React Spreadsheet for exporting files?
&lt;/h2&gt;

&lt;p&gt;The Syncfusion React Spreadsheet component is designed for enterprise-grade scenarios and includes export support that works well for both end users and developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multiple export formats:&lt;/strong&gt;  Export to XLSX, XLS, CSV, and PDF.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible UX:&lt;/strong&gt; Users can export via the Ribbon, or you can trigger export from your own UI using &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#save" rel="noopener noreferrer"&gt;save&lt;/a&gt; method.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preserves workbook features:&lt;/strong&gt;  Keeps styles, formulas, and formatting in exports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-side processing:&lt;/strong&gt;  Offloads file generation to the backend for better performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable export lifecycle:&lt;/strong&gt; Use events like &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#beforesave" rel="noopener noreferrer"&gt;beforeSave&lt;/a&gt; and &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#savecomplete" rel="noopener noreferrer"&gt;saveComplete&lt;/a&gt; to fine-tune behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need simple downloads or heavily formatted exports, this approach scales without forcing you to build export logic from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported file formats
&lt;/h2&gt;

&lt;p&gt;You can export spreadsheet data to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microsoft Excel (.xlsx)&lt;/li&gt;
&lt;li&gt;Microsoft Excel 97-2003 (.xls)&lt;/li&gt;
&lt;li&gt;Comma-Separated Values (.csv)&lt;/li&gt;
&lt;li&gt;PDF (.pdf)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How exporting works behind the scenes (server-side)
&lt;/h2&gt;

&lt;p&gt;Syncfusion Spreadsheet export uses server-side processing via the &lt;a href="https://www.nuget.org/packages/Syncfusion.EJ2.Spreadsheet.AspNet.Core" rel="noopener noreferrer"&gt;Syncfusion.EJ2.Spreadsheet&lt;/a&gt; server library (ASP.NET Core / MVC). The high-level flow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The React client sends spreadsheet content to the server as  &lt;strong&gt;JSON&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The server uses &lt;a href="https://help.syncfusion.com/document-processing/excel/excel-library/net/overview" rel="noopener noreferrer"&gt;Syncfusion.XlsIO&lt;/a&gt; to convert JSON into the target format (XLSX/XLS/CSV/PDF).&lt;/li&gt;
&lt;li&gt;The server streams the generated file back to the client.&lt;/li&gt;
&lt;li&gt;The client downloads the file (or you can handle it programmatically, e.g., as a Blob).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The export runs in memory during the request lifecycle; no data is stored on the server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FReact-spreadsheet-export-workflow-using-Syncfusion-XlsIO.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FReact-spreadsheet-export-workflow-using-Syncfusion-XlsIO.jpg" alt="React spreadsheet export workflow using Syncfusion XlsIO" width="720" height="480"&gt;&lt;/a&gt;&lt;br&gt;React spreadsheet export workflow using Syncfusion XlsIO
  &lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before implementing export functionality;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js and npm installed&lt;/strong&gt; on your machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A React development environment&lt;/strong&gt; set up using tools like &lt;em&gt;VS Code&lt;/em&gt; or any preferred IDE.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A React project created&lt;/strong&gt; (e.g., using create-react-app, Vite, or Next.js).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Syncfusion Spreadsheet component&lt;/strong&gt; added to your React app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Syncfusion.XlsIO&lt;/strong&gt; or equivalent library configured on the backend for file generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend environment ready&lt;/strong&gt; (Node.js, .NET, or any server stack) to handle spreadsheet generation and stream the file back to the client.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the prerequisites ready, we can now integrate the Spreadsheet component and wire it up to the app logic. We’ll now set up the React front end and configure the backend services that will generate and export the spreadsheet files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Set up your React app
&lt;/h3&gt;

&lt;p&gt;Integrate the Syncfusion Spreadsheet component into your React project using the &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/getting-started" rel="noopener noreferrer"&gt;Getting Started&lt;/a&gt; guide (install packages, add styles, render the Spreadsheet).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Configure backend services for export (required)
&lt;/h3&gt;

&lt;p&gt;Exports rely on a backend service. You have two common options:&lt;/p&gt;

&lt;h4&gt;
  
  
  Option A: Self-host with .NET (ASP.NET Core)
&lt;/h4&gt;

&lt;p&gt;Best when you want full control over infrastructure and logic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow the guide: &lt;a href="https://www.syncfusion.com/blogs/post/host-spreadsheet-open-and-save-services" rel="noopener noreferrer"&gt;Host Open and Save Services for JavaScript Spreadsheet with ASP.NET Core&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use the GitHub sample: &lt;a href="https://github.com/SyncfusionExamples/EJ2-Spreadsheet-WebServices" rel="noopener noreferrer"&gt;Essential Studio Spreadsheet Web Services&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Option B: Deploy the Spreadsheet Server using Docker
&lt;/h4&gt;

&lt;p&gt;Best when you want consistent deployments and easy scaling.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read: &lt;a href="https://www.syncfusion.com/blogs/post/spreadsheet-docker-image-deployment" rel="noopener noreferrer"&gt;Deploy Syncfusion Spreadsheet Docker Image&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Docker Hub: &lt;a href="https://hub.docker.com/r/syncfusion/spreadsheet-server" rel="noopener noreferrer"&gt;syncfusion/spreadsheet-server&lt;/a&gt; (ASP.NET Core 8.0)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once your backend is running, configure the Spreadsheet component to point at your endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#openurl" rel="noopener noreferrer"&gt;openUrl&lt;/a&gt; for opening content&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#saveurl" rel="noopener noreferrer"&gt;saveUrl&lt;/a&gt; for exporting/saving content&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Exporting approach
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Export via Ribbon UI
&lt;/h3&gt;

&lt;p&gt;If you want a familiar, user-driven workflow, the built-in Ribbon is the simplest option:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to  &lt;strong&gt;File → Save As.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose a format:  &lt;strong&gt;XLSX&lt;/strong&gt;, &lt;strong&gt;XLS&lt;/strong&gt;, &lt;strong&gt;CSV&lt;/strong&gt;, or &lt;strong&gt;PDF&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Download the file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is ideal when users should control export format without any custom UI work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FExporting-files-through-the-ribbon.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FExporting-files-through-the-ribbon.png" alt="Exporting files through the ribbon" width="660" height="406"&gt;&lt;/a&gt;&lt;br&gt;Exporting files through the ribbon
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Programmatic export with the save Method
&lt;/h3&gt;

&lt;p&gt;When you need more control (custom buttons, workflow-based export, default naming, extra server params), use the Spreadsheet &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#save" rel="noopener noreferrer"&gt;save&lt;/a&gt; API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How the Save workflow operates:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pick an export format (XLSX, XLS, CSV, PDF) from the dropdown.&lt;/li&gt;
&lt;li&gt;The save action calls the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#save" rel="noopener noreferrer"&gt;save&lt;/a&gt; API.&lt;/li&gt;
&lt;li&gt;Spreadsheet JSON is posted to the backend for processing.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#beforesave" rel="noopener noreferrer"&gt;beforeSave&lt;/a&gt; and &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#savecomplete" rel="noopener noreferrer"&gt;saveComplete&lt;/a&gt; to modify routing, performance, or output.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Code example (React)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SpreadsheetComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@syncfusion/ej2-react-spreadsheet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DropDownListComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@syncfusion/ej2-react-dropdowns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ButtonComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@syncfusion/ej2-react-buttons&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;…&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Initial save type&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;saveType&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Xlsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Dropdown data &lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;saveAsOptions&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;saveAs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;XLSX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;saveType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Xlsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;saveAs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;XLS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;saveType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Xls&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;saveAs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CSV&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;saveType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Csv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;saveAs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PDF&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;saveType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pdf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;saveAs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;saveType&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Update save type on selection&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;onSaveTypeChange&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt; &lt;span class="nx"&gt;saveType&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Trigger export programmatically&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;onSaveClick&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt; &lt;span class="nx"&gt;spreadsheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://document.syncfusion.com/web-services/spreadsheet-editor/api/spreadsheet/save&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;            &lt;/span&gt;&lt;span class="na"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sample&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;            &lt;/span&gt;&lt;span class="na"&gt;saveType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;saveType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;// Optional (PDF): customize PDF layout if saveType === 'Pdf'&lt;/span&gt;
&lt;span class="err"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;// pdfLayoutSettings: { orientation: 'Landscape', fitSheetOnOnePage: true }&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Fires before save; great place to customize behavior&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;onBeforeSave&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// Disable full form submission to improve performance on large workbooks&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isFullPost&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// Example: send custom data to the server&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// args.customParams = { tenantId: 'contoso', exportSource: 'marketing' };&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// Example: request Blob data back (for custom handling in saveComplete)&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// args.needBlobData = true;&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt; 

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Fires after save completes if isFullPost is false&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;onSaveComplete&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// Example: show a toast or handle Blob&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// if (args.blobData) { uploadToServer(args.blobData); }&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;File saved successfully&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt; 
    &lt;span class="err"&gt;…&lt;/span&gt;  
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;control-pane&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;        &lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DropDownListComponent&lt;/span&gt;
                &lt;span class="nx"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;saveAsOptions&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSaveTypeChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
            &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ButtonComponent&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cssClass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;save-btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSaveClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Save&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ButtonComponent&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
            &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;control-section spreadsheet-control&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;            &lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SpreadsheetComponent&lt;/span&gt;
                    &lt;span class="nx"&gt;openUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://document.syncfusion.com/web-services/spreadsheet-editor/api/spreadsheet/open&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
                    &lt;span class="nx"&gt;saveUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://document.syncfusion.com/web-services/spreadsheet-editor/api/spreadsheet/save&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
                    &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;ssObj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;spreadsheet&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ssObj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
                    &lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onCreated&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;beforeSave&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onBeforeSave&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;saveComplete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSaveComplete&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="err"&gt;                &lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SheetsDirective&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="err"&gt;                    &lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SheetDirective&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Car Sales Report&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;                        &lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt;
                            &lt;span class="err"&gt;…&lt;/span&gt;
&lt;span class="err"&gt;                        &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SheetDirective&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
                    &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SheetsDirective&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
                &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SpreadsheetComponent&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
            &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
        &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Highlights:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic format selection&lt;/strong&gt;: The dropdown updates the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/saveOptions/#savetype" rel="noopener noreferrer"&gt;saveType&lt;/a&gt; based on user input.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance optimization&lt;/strong&gt;: The &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#beforesave" rel="noopener noreferrer"&gt;beforeSave&lt;/a&gt; event disables full form submission (&lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/performance-best-practices#handling-large-file-saves-with-isfullpost-option" rel="noopener noreferrer"&gt;isFullPost&lt;/a&gt; = false)&lt;/li&gt;
&lt;li&gt; for better performance exports. This switches the request to a lightweight fetch call, making the export faster and more reliable, especially with large workbooks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom server endpoint&lt;/strong&gt;: The export is sent to Syncfusion’s hosted service, but you can replace the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/saveOptions/#url" rel="noopener noreferrer"&gt;url&lt;/a&gt; with your own backend if self-hosted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF customization&lt;/strong&gt;: You can optionally pass &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/pdflayoutsettings/" rel="noopener noreferrer"&gt;pdfLayoutSettings&lt;/a&gt; to control orientation and layout.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see this feature in action with the &lt;a href="https://stackblitz.com/edit/7k4m44h1-p27mnpgx?file=index.js" rel="noopener noreferrer"&gt;Live demo&lt;/a&gt;, and for more technical details, check out the API guide for &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#save" rel="noopener noreferrer"&gt;save&lt;/a&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Spreadsheet component supports multiple save workflows. Beyond downloading directly, you can &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#save-an-excel-file-as-blob-data" rel="noopener noreferrer"&gt;save the file as a Blob&lt;/a&gt;, or &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#save-an-excel-file-to-a-server" rel="noopener noreferrer"&gt;send exported files to a server&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Export events you can customize (most useful hooks)
&lt;/h2&gt;

&lt;p&gt;Syncfusion gives you powerful hooks to customize the export process through two key events: &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#beforesave" rel="noopener noreferrer"&gt;beforeSave&lt;/a&gt; and &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#savecomplete" rel="noopener noreferrer"&gt;saveComplete&lt;/a&gt;. These events let you fine-tune how exports behave, add custom logic, or even intercept the process entirely.&lt;/p&gt;

&lt;h3&gt;
  
  
  beforeSave event
&lt;/h3&gt;

&lt;p&gt;Runs right before export starts. Use it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Override file name/format or change the target &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/index-default#saveurl" rel="noopener noreferrer"&gt;saveUrl&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Pass custom parameters to your backend (&lt;strong&gt;&lt;code&gt;customParams&lt;/code&gt;&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Cancel export (&lt;strong&gt;&lt;code&gt;args.cancel = true&lt;/code&gt;&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Improve performance by switching to fetch-based export (&lt;strong&gt;&lt;code&gt;args.isFullPost = false&lt;/code&gt;&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Request Blob data for custom handling (&lt;strong&gt;&lt;code&gt;args.needBlobData = true&lt;/code&gt;&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Customize &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/pdflayoutsettings/" rel="noopener noreferrer"&gt;PDF Layout&lt;/a&gt; (layout/orientation via &lt;strong&gt;&lt;code&gt;pdfLayoutSettings&lt;/code&gt;&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  saveComplete event
&lt;/h3&gt;

&lt;p&gt;Runs after export completes (especially when &lt;strong&gt;&lt;code&gt;isFullPost = false&lt;/code&gt;&lt;/strong&gt; ). Use it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Show a toast or success message.&lt;/li&gt;
&lt;li&gt;Access Blob data (if requested) for uploads or alternate storage flows.&lt;/li&gt;
&lt;li&gt;Trigger logging/analytics hooks in your app.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Enterprise considerations (performance, scalability, maintainability)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt;  For larger workbooks, set &lt;strong&gt;&lt;code&gt;args.isFullPost = false&lt;/code&gt;&lt;/strong&gt; in &lt;strong&gt;&lt;code&gt;beforeSave&lt;/code&gt;&lt;/strong&gt; to avoid heavier form-style submissions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt;  Host the export service in your own infrastructure (or Docker) so you can scale independently from the React frontend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability:&lt;/strong&gt;  Keep export logic centralized on the server. The client stays thin: it sends workbook JSON and receives a file stream back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt;  Exports run in memory during the request lifecycle; design your endpoints with auth, rate limits, and auditing if you handle sensitive data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. How do I enable export functionality in my project?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Enable the export feature by configuring the &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/index-default#saveurl" rel="noopener noreferrer"&gt;saveUrl&lt;/a&gt; property to point to your backend export service. The backend must use Syncfusion’s &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#open" rel="noopener noreferrer"&gt;Open&lt;/a&gt; and &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#save" rel="noopener noreferrer"&gt;Save&lt;/a&gt; service or your own ASP.NET Core service to handle file generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Can I customize the export process?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes. You can use lifecycle events such as &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#beforesave" rel="noopener noreferrer"&gt;beforeSave&lt;/a&gt; to modify parameters, change file names, customize formats, or cancel exports. You can also use &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#savecomplete" rel="noopener noreferrer"&gt;saveComplete&lt;/a&gt; to trigger notifications, analytics, or follow-up actions after successful export.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. What export options are available besides downloading from the Ribbon UI?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; You can export using custom UI buttons, &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#save-an-excel-file-as-blob-data" rel="noopener noreferrer"&gt;save the file as a Blob&lt;/a&gt;, &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#save-an-excel-file-to-a-server" rel="noopener noreferrer"&gt;send exported files to a server&lt;/a&gt;, or &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#save-data-as-a-base64-string" rel="noopener noreferrer"&gt;generate Base64&lt;/a&gt; output for advanced workflows. These methods allow full control over export behavior depending on your application’s requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Are formatting and formulas preserved during export?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes. Exported Excel files retain formatting such as fonts, colors, borders, alignment, merged cells, and conditional formatting. Formulas, values, and data validation rules are also preserved in supported formats.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Is there a Docker image available for easy deployment of the export server?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes, Syncfusion offers a pre-built Docker image on &lt;a href="https://hub.docker.com/r/syncfusion/spreadsheet-server" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt; based on an  &lt;strong&gt;ASP.NET Core&lt;/strong&gt;  project, which requires no additional .NET code from your side. Configure your React app’s &lt;a href="https://ej2.syncfusion.com/react/documentation/api/spreadsheet/#saveurl" rel="noopener noreferrer"&gt;saveUrl&lt;/a&gt; to point to this containerized server for file exports (e.g., for Excel/CSV processing). It’s lightweight, secure, and deployable on any platform supporting &lt;a href="https://www.syncfusion.com/blogs/post/spreadsheet-docker-image-deployment" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;, like Kubernetes or &lt;a href="https://www.syncfusion.com/blogs/post/spreadsheet-server-eks-deployment" rel="noopener noreferrer"&gt;AWS EKS&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Thank you for reading! Exporting Excel, CSV, and PDF from React apps is fast and reliable with the &lt;a href="https://www.syncfusion.com/react-components/react-spreadsheet" rel="noopener noreferrer"&gt;Syncfusion React Spreadsheet&lt;/a&gt;. Use the Ribbon for a familiar user experience, or use the &lt;strong&gt;&lt;code&gt;save()&lt;/code&gt;&lt;/strong&gt; method for full control in custom UIs. With &lt;strong&gt;&lt;code&gt;beforeSave&lt;/code&gt;&lt;/strong&gt; and  &lt;strong&gt;&lt;code&gt;saveComplete&lt;/code&gt;&lt;/strong&gt;, you can optimize performance, pass custom parameters, and support advanced workflows like Blob-based handling, while keeping export generation reliable on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it out today&lt;/strong&gt; and let us know your thoughts in the comments!&lt;/p&gt;

&lt;p&gt;If you’re a Syncfusion user, you can download the setup from the &lt;a href="https://www.syncfusion.com/sales/pricing" rel="noopener noreferrer"&gt;license and downloads&lt;/a&gt; page. Otherwise, you can download a free &lt;a href="https://www.syncfusion.com/downloads" rel="noopener noreferrer"&gt;30-day trial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also contact us through our &lt;a href="https://www.syncfusion.com/forums" rel="noopener noreferrer"&gt;support forums&lt;/a&gt;, &lt;a href="https://support.syncfusion.com/" rel="noopener noreferrer"&gt;support portal&lt;/a&gt;, or &lt;a href="https://www.syncfusion.com/feedback" rel="noopener noreferrer"&gt;feedback portal&lt;/a&gt; for queries. We are always happy to assist you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ej2.syncfusion.com/react/documentation/spreadsheet/getting-started" rel="noopener noreferrer"&gt;Syncfusion React Spreadsheet Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ej2.syncfusion.com/react/documentation/spreadsheet/open-save" rel="noopener noreferrer"&gt;Open and Save Files in React Spreadsheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/performance-best-practices#how-to-improve-save-performance-in-the-spreadsheet" rel="noopener noreferrer"&gt;Performance best practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Other save options:&lt;/strong&gt; &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#save-an-excel-file-as-blob-data" rel="noopener noreferrer"&gt;Save as Blob&lt;/a&gt;, &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#save-data-as-a-base64-string" rel="noopener noreferrer"&gt;Save as Base64&lt;/a&gt;, &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#save-an-excel-file-to-a-server" rel="noopener noreferrer"&gt;Save to server&lt;/a&gt;, &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#add-custom-header-during-save" rel="noopener noreferrer"&gt;Add custom headers&lt;/a&gt;, &lt;a href="https://help.syncfusion.com/document-processing/excel/spreadsheet/react/open-save#configure-json-serialization-options" rel="noopener noreferrer"&gt;Configure JSON serialization&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Related Blogs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/react-spreadsheet-aws-s3-integration" rel="noopener noreferrer"&gt;React Spreadsheet AWS S3 Integration: Open and Save Excel Files in the Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/boost-react-spreadsheet-performance" rel="noopener noreferrer"&gt;Smooth Scrolling, Fast Saves: Boost React Spreadsheet Performance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/custom-formulas-in-spreadsheet" rel="noopener noreferrer"&gt;Custom Formulas in Spreadsheet: A Practical Guide for React Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/spreadsheet-server-eks-deployment" rel="noopener noreferrer"&gt;How to Deploy Spreadsheet Server on AWS EKS with Docker for React&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/react-spreadsheet-export-excel-csv-pdf" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>dataexport</category>
      <category>excelexport</category>
      <category>export</category>
    </item>
    <item>
      <title>How to Diagnose and Fix Font Issues in a JavaScript PDF Viewer</title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Tue, 03 Mar 2026 14:55:40 +0000</pubDate>
      <link>https://forem.com/syncfusion/how-to-diagnose-and-fix-font-issues-in-a-javascript-pdf-viewer-3n64</link>
      <guid>https://forem.com/syncfusion/how-to-diagnose-and-fix-font-issues-in-a-javascript-pdf-viewer-3n64</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; PDF font issues in JavaScript PDF Viewer typically occur due to missing embedded fonts, browser differences, corrupted font data, or unsupported multilingual scripts. This guide explains common causes and shows how Syncfusion’s JavaScript PDF Viewer, powered by the Pdfium engine, ensures accurate, multilingual, and custom‑font rendering across browsers.&lt;/p&gt;

&lt;p&gt;Accurate font rendering in PDFs isn’t “nice to have.” It affects readability, layout, branding, and sometimes compliance, especially for invoices, contracts, reports, and multilingual documents.&lt;/p&gt;

&lt;p&gt;The tricky part: PDF font rendering in the browser is deceptively complex. Many apps look fine until a production document triggers a JavaScript PDF viewer font problem, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PDF text garbled or scrambled.&lt;/li&gt;
&lt;li&gt;PDF font replaced or incorrect.&lt;/li&gt;
&lt;li&gt;Missing fonts in PDF Viewer.&lt;/li&gt;
&lt;li&gt;PDF shows boxes/tofu squares instead of characters.&lt;/li&gt;
&lt;li&gt;Layout shifts between Chrome, Firefox, and embedded viewers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re hitting “&lt;strong&gt;PDF font issues in JavaScript PDF Viewer&lt;/strong&gt;”, this guide breaks down the most common technical causes, what to check, and practical ways to fix it using &lt;a href="https://www.syncfusion.com/pdf-viewer-sdk/javascript-pdf-viewer" rel="noopener noreferrer"&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt; JavaScript PDF Viewer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why PDF font not display in browser-based viewers
&lt;/h2&gt;

&lt;p&gt;There were several reasons that affected the font rendering in the JavaScript PDF Viewers. Here are the most common technical reasons for broken fonts and PDF font display problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Font embedding and cross‑viewer rendering differences in PDFs
&lt;/h3&gt;

&lt;p&gt;If a PDF &lt;strong&gt;references a font but doesn’t embed it&lt;/strong&gt;, the viewer must substitute a system font. Substitution often fails for corporate fonts, decorative fonts, or fonts with unusual metrics, leading to spacing issues, line breaks changing, or glyphs missing entirely.&lt;/p&gt;

&lt;p&gt;Even when fonts are embedded, different viewers may interpret font programs and encodings differently. That’s why developers often see “works in Adobe Acrobat but breaks in browser viewer” scenarios.&lt;/p&gt;

&lt;p&gt;Real-world examples show this mismatch across viewers and browsers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reddit: “PDF viewer is not detecting the fonts correctly, but Google PDF viewer / Adobe shows correct fonts.”
Ref: &lt;em&gt;&lt;a href="https://www.reddit.com/r/zen_browser/comments/1i39va8/pdf_viewers_fonts_issues/" rel="noopener noreferrer"&gt;PDF viewer’s fonts issues: r/zen_browser&lt;/a&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FBroken-fonts-in-browser-PDF-viewers.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FBroken-fonts-in-browser-PDF-viewers.png" alt="Broken fonts in Browser PDF viewers" width="800" height="525"&gt;&lt;/a&gt;&lt;br&gt;Broken fonts in Browser PDF viewers
  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: “The issue occurs in Chrome, but not Firefox.”
Ref: &lt;em&gt;&lt;a href="https://github.com/stephanrauh/ngx-extended-pdf-viewer/issues/2950" rel="noopener noreferrer"&gt;Text appears broken · Issue #2950 · stephanrauh/ngx-extended-pdf-viewer&lt;/a&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPDF-fonts-render-differently-in-Chrome-vs-Firefox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPDF-fonts-render-differently-in-Chrome-vs-Firefox.png" alt="PDF fonts render differently in Chrome vs Firefox" width="706" height="726"&gt;&lt;/a&gt;&lt;br&gt;PDF fonts render differently in Chrome vs Firefox
  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prefer PDFs with  &lt;strong&gt;embedded fonts&lt;/strong&gt;  (especially for generated PDFs).&lt;/li&gt;
&lt;li&gt;Validate the PDF’s font embedding and encoding if you control the PDF generation pipeline.&lt;/li&gt;
&lt;li&gt;Test across browsers early to catch cross browser PDF compatibility issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CJK/complex scripts and “Base‑14” assumptions
&lt;/h3&gt;

&lt;p&gt;Languages like Chinese, Japanese, and Korean (CJK) and complex scripts like Arabic/Hebrew depend on correct font selection, shaping rules, and glyph mapping. Some PDFs also rely on assumptions around common built-in fonts (like Helvetica/Times), but those assumptions don’t always hold in browser-based renderers.&lt;/p&gt;

&lt;p&gt;This is where you’ll often see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tofu squares (missing glyphs)&lt;/li&gt;
&lt;li&gt;incorrect character widths (layout drift)&lt;/li&gt;
&lt;li&gt;broken shaping or direction for RTL text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;References from PDF.js-related issues highlight these edge cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mozilla/pdf.js/issues/20260" rel="noopener noreferrer"&gt;[Bug]: ASCII control characters not properly filtered · Issue #20260 · mozilla/pdf.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mozilla/pdf.js/issues/18806" rel="noopener noreferrer"&gt;[Bug]: Glitchy text when opening pdf · Issue #18806 · mozilla/pdf.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FReported-bugs-show-PDF.js-font-problems.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FReported-bugs-show-PDF.js-font-problems.png" alt="User-reported discussion on PDF.js font rendering issues" width="714" height="210"&gt;&lt;/a&gt;&lt;br&gt;User-reported discussion on PDF.js font rendering issues
  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FChinese-text-breaks-in-PDF.js-but-displays-fine-in-Adobe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FChinese-text-breaks-in-PDF.js-but-displays-fine-in-Adobe.png" alt="Chinese text renders incorrectly in PDF.js but works in Adobe" width="780" height="623"&gt;&lt;/a&gt;&lt;br&gt;Chinese text renders incorrectly in PDF.js but works in Adobe
  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure PDFs include proper font programs and mappings for the target scripts.&lt;/li&gt;
&lt;li&gt;For multilingual apps, treat font rendering as a first-class test scenario (CJK + RTL + mixed-language documents).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Font &lt;strong&gt;data issues in PDFs: Corrupt streams and subset mapping&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;PDFs often use  &lt;strong&gt;subset fonts&lt;/strong&gt;  (only embedding glyphs that are used). That’s normal, but it increases reliance on correct mapping tables. If font streams are malformed, compressed oddly, or mappings are incomplete, some viewers fail to map glyphs correctly, leading to random characters, missing symbols, or messy spacing.&lt;/p&gt;

&lt;p&gt;Developers frequently report issues like this in popular JavaScript viewer stacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/wojtekmaj/react-pdf/issues/1805" rel="noopener noreferrer"&gt;PDF text and spaces are messy · Issue #1805 · wojtekmaj/react-pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/72904670/how-do-i-fix-garbled-text-in-my-react-pdf-viewer" rel="noopener noreferrer"&gt;How do I fix garbled text in my react-pdf viewer? – Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCorrupt-font-streams-cause-garbled-text-in-JavaScript-PDF-Viewer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FCorrupt-font-streams-cause-garbled-text-in-JavaScript-PDF-Viewer.png" alt="Garbled text caused by corrupted font streams in PDF.js" width="511" height="805"&gt;&lt;/a&gt;&lt;br&gt;Garbled text caused by corrupted font streams in PDF.js
  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the same PDF renders differently across viewers, suspect font stream parsing or subset mapping.&lt;/li&gt;
&lt;li&gt;Try rendering the same file in multiple engines to isolate whether it’s a PDF issue or a viewer limitation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it works (why font rendering is hard in JavaScript viewers)
&lt;/h2&gt;

&lt;p&gt;A browser PDF viewer typically has to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parse PDF objects (including font dictionaries, encodings, and streams).&lt;/li&gt;
&lt;li&gt;Decode embedded font programs (TTF/OTF/CFF/CID fonts).&lt;/li&gt;
&lt;li&gt;Map character codes to glyphs (often via ToUnicode maps).&lt;/li&gt;
&lt;li&gt;Apply shaping/direction rules for complex scripts.&lt;/li&gt;
&lt;li&gt;Rasterize or draw text consistently across browsers and devices.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Small differences in any step can cause “looks fine here, broken there” behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix checklist: What to try before switching viewers
&lt;/h2&gt;

&lt;p&gt;Use this as a practical debugging flow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Confirm fonts are embedded&lt;/strong&gt;  (especially custom/corporate fonts).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test across Chrome + Firefox + Edge&lt;/strong&gt;  with the same file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try a known-good viewer&lt;/strong&gt;  (Adobe Acrobat / Chrome built-in) to compare output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check if the PDF is subset-heavy&lt;/strong&gt;  and whether ToUnicode mappings exist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Re-generate the PDF&lt;/strong&gt;  (if you own the pipeline) with explicit embedding and standard encodings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collect a minimal repro PDF&lt;/strong&gt;  (one page, one problematic font) to speed up debugging.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don’t control the PDFs (common in enterprise), the most reliable fix is often choosing a viewer that handles real-world font edge cases consistently.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Syncfusion resolves PDF font issues in JavaScript PDF Viewer
&lt;/h2&gt;

&lt;p&gt;Syncfusion addresses this with intelligent font handling and robust support for embedded and custom fonts, enabling your documents to appear exactly as intended, every time they’re viewed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pdfium font rendering engine for consistent output
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.syncfusion.com/pdf-viewer-sdk/javascript-pdf-viewer" rel="noopener noreferrer"&gt;Syncfusion JavaScript PDF Viewer&lt;/a&gt; uses the Pdfium rendering engine, an industry-standard library from the Chromium project renowned for its precise font rendering. This eliminates common font issues in JavaScript PDF Viewer and ensures flawless display across browsers.&lt;/p&gt;

&lt;p&gt;By leveraging Pdfium, Syncfusion accurately preserves every character, symbol, and layout, along with high-fidelity images and graphics, ensuring PDFs display flawlessly across all browsers and devices without issues like blurry text, missing glyphs, or broken layouts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPdfium-ensures-flawless-fonts-in-JavaScript-PDF-Viewer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FPdfium-ensures-flawless-fonts-in-JavaScript-PDF-Viewer.png" alt="PDFium ensuring proper font rendering in a JavaScript PDF viewer" width="800" height="446"&gt;&lt;/a&gt;&lt;br&gt;PDFium ensuring proper font rendering in a JavaScript PDF viewer
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Multilingual PDFs and Unicode characters (CJK + RTL)
&lt;/h3&gt;

&lt;p&gt;Global businesses require support for diverse languages and special characters. Syncfusion’s PDF Viewer excels in rendering in global languages, unique characters, solving pdf font display problems for CJK and right-to-left scripts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CJK (Japanese/ Chinese/ Korean)&lt;/strong&gt; languages have unique font structures and character sets. Syncfusion loads these fonts from the server side, ensuring accurate representation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Right-to-left languages&lt;/strong&gt; like Arabic and Hebrew with proper text direction and alignment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unicode support for&lt;/strong&gt; symbols, emojis, and special characters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FProper-CJK-and-RTL-support-in-JavaScript-PDF-Viewer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syncfusion.com%2Fblogs%2Fwp-content%2Fuploads%2F2026%2F03%2FProper-CJK-and-RTL-support-in-JavaScript-PDF-Viewer.png" alt="RTL text rendering (Arabic) in JavaScript PDF viewer" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;RTL text rendering (Arabic) in JavaScript PDF viewer
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Custom font rendering (bring your own TTF resources)
&lt;/h3&gt;

&lt;p&gt;Syncfusion JavaScript PDF Viewer supports rendering the custom fonts in the PDF with the respective resources. To view PDFs containing custom fonts in the Syncfusion PDF Viewer, simply place your TTF font files in the designated resource URL directory and configure the viewer to access them. This ensures your documents display every unique font exactly as designed.&lt;/p&gt;

&lt;p&gt;Example code for custom fonts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create PdfViewer instance and configure with document path, resource URL, and custom fonts&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;pdfviewer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ej&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pdfviewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PdfViewer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;documentPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://cdn.syncfusion.com/content/pdf/pdf_font.pdf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resourceUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://cdn.syncfusion.com/ej2/24.1.41/dist/ej2-pdfviewer-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;customFonts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; 
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;arialbd.ttf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;arial.ttf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BKANT.TTF&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calibri.ttf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GARA.TTF&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GARAIT.TTF&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;msgothic.ttc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;trebuc.ttf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wingding.ttf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// Render the PDF Viewer control to the target HTML element&lt;/span&gt;
&lt;span class="nx"&gt;pdfviewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#PdfViewer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GitHub reference
&lt;/h2&gt;

&lt;p&gt;You can find a detailed reference sample for &lt;strong&gt;custom font rendering&lt;/strong&gt; &lt;a href="https://github.com/SyncfusionExamples/react-pdf-viewer-examples/tree/master/How%20to/Custom%20Fonts" rel="noopener noreferrer"&gt;here&lt;/a&gt;. This solution ensures that the &lt;strong&gt;custom font rendering in JavaScript PDF Viewer&lt;/strong&gt; with own TTF resource.&lt;/p&gt;

&lt;p&gt;For deeper insights, explore our comprehensive &lt;a href="https://help.syncfusion.com/document-processing/pdf/pdf-viewer/javascript-es5/overview" rel="noopener noreferrer"&gt;user guide&lt;/a&gt;, which includes extensive documentation, &lt;a href="https://document.syncfusion.com/demos/pdf-viewer/javascript-es5/#/tailwind3/pdfviewer/right-to-left.html" rel="noopener noreferrer"&gt;live demo&lt;/a&gt;, advanced usage scenarios, and the full suite of powerful features available in the Syncfusion PDF Viewer.&lt;/p&gt;

&lt;p&gt;Empower your applications with industry-leading accuracy, flexibility, and seamless integration, starting today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Does any local installations required to use the Syncfusion JavaScript PDF Viewer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; No, you don’t need any local installation. The Syncfusion JavaScript PDF Viewer runs in the browser, and you just include the &lt;a href="https://help.syncfusion.com/document-processing/pdf/pdf-viewer/javascript-es5/getting-started" rel="noopener noreferrer"&gt;Syncfusion scripts and resources&lt;/a&gt; alone in your web project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Does the Syncfusion viewer allow text selection and text search inside a PDF?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes. If the PDF contains real text (not scanned images), you can select text and use the built‑in search feature. For scanned PDFs, you can convert them into searchable text using &lt;a href="https://www.syncfusion.com/document-sdk/net-pdf-library/ocr-process" rel="noopener noreferrer"&gt;Syncfusion’s OCR PDF library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Can Syncfusion display PDFs that contain form fields?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes! It supports text fields, checkboxes, radio buttons, dropdowns, and signature fields. You can fill and save &lt;a href="https://help.syncfusion.com/document-processing/pdf/pdf-viewer/javascript-es5/forms/form-filling" rel="noopener noreferrer"&gt;form fields&lt;/a&gt; directly in the browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Does Syncfusion PDF Viewer support dark themes?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes. You can apply &lt;a href="https://ej2.syncfusion.com/themestudio/?theme=tailwind3" rel="noopener noreferrer"&gt;Syncfusion themes&lt;/a&gt; like Material Dark, Fluent Dark, Bootstrap Dark, etc., and the viewer UI adapts automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Is any additional configuration required for PDFs that use special or custom fonts?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes, only if the PDF uses &lt;strong&gt;custom fonts&lt;/strong&gt; that aren’t embedded. In that case, you place the font files on your server and tell Syncfusion where to find them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Can Syncfusion PDF Viewer display fonts with special characters, emojis, or multi‑colored fonts?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes. The Syncfusion PDF Viewer can display multi‑color fonts, special characters, emojis, and other advanced font styles, as long as those font elements are already embedded in the PDF.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Thank you for reading! Font rendering in PDFs isn’t just cosmetic; it affects usability, branding, and compliance. &lt;a href="https://www.syncfusion.com/pdf-viewer-sdk/javascript-pdf-viewer" rel="noopener noreferrer"&gt;Syncfusion JavaScript PDF Viewer&lt;/a&gt; offers a robust, developer-friendly solution with server-side rendering, multilingual support, and custom font handling. It ensures that every PDF, no matter how complex, is displayed accurately and beautifully, solving PDF font rendering issues and ensuring cross-browser PDF compatibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ready to upgrade your PDF viewer?&lt;/strong&gt; Try &lt;a href="https://www.syncfusion.com/javascript-ui-controls/js-pdf-viewer" rel="noopener noreferrer"&gt;Syncfusion JavaScript PDF Viewer&lt;/a&gt; today and deliver a professional, polished experience your users will love.&lt;/p&gt;

&lt;p&gt;If you’re a Syncfusion user, you can download the setup from the &lt;a href="https://www.syncfusion.com/sales/pricing" rel="noopener noreferrer"&gt;license and downloads&lt;/a&gt; page. Otherwise, you can download a free &lt;a href="https://www.syncfusion.com/downloads" rel="noopener noreferrer"&gt;30-day trial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also contact us through our &lt;a href="https://www.syncfusion.com/forums" rel="noopener noreferrer"&gt;support forums&lt;/a&gt;, &lt;a href="https://support.syncfusion.com/" rel="noopener noreferrer"&gt;support portal&lt;/a&gt;, or &lt;a href="https://www.syncfusion.com/feedback" rel="noopener noreferrer"&gt;feedback portal&lt;/a&gt; for queries. We are always happy to assist you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Blogs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/multi-source-pdf-loading-in-javascript" rel="noopener noreferrer"&gt;Multi-Source PDF Loading in JavaScript: Why Most Viewers Fail and How Syncfusion Fixes It&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/pdf-hyperlink-issues-js-pdf-viewer" rel="noopener noreferrer"&gt;Why Hyperlinks Break in JavaScript PDF Viewers and How to Fix Them&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/auto-populate-pdf-form-fields" rel="noopener noreferrer"&gt;How to Auto-Populate PDF Form Fields in JavaScript PDF Viewer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/fillable-pdf-forms-in-javascript" rel="noopener noreferrer"&gt;Why Fillable PDF Forms in JavaScript PDF Viewers Break and How to Fix Them&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/pdf-font-issues-javascript-pdf-viewer" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>frontend</category>
      <category>javascriptpdfviewer</category>
      <category>pdfviewer</category>
    </item>
    <item>
      <title>SDKs vs APIs vs JavaScript: Modern Document Processing in 2026</title>
      <dc:creator>Lucy Muturi</dc:creator>
      <pubDate>Fri, 27 Feb 2026 14:54:54 +0000</pubDate>
      <link>https://forem.com/syncfusion/sdks-vs-apis-vs-javascript-modern-document-processing-in-2026-3ima</link>
      <guid>https://forem.com/syncfusion/sdks-vs-apis-vs-javascript-modern-document-processing-in-2026-3ima</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Modern document workflows in 2026 typically rely on three approaches: high-performance SDKs, scalable Docker-based Web APIs, and flexible JavaScript or Node.js tools. Each addresses different needs around performance, scalability, and user experience. This guide compares the trade-offs, explains when to use each approach, and shows why many teams now combine them to build faster, cloud-ready, and future-proof document-processing systems.&lt;/p&gt;

&lt;p&gt;Document processing is now a core feature in modern apps, from generating invoices and contracts to powering real-time PDF review and web-based document editing. But expectations have changed. Teams want automation that is  &lt;strong&gt;reliable&lt;/strong&gt;,  &lt;strong&gt;scalable&lt;/strong&gt;, and  &lt;strong&gt;compatible&lt;/strong&gt;  with both traditional deployments and cloud-native platforms.&lt;/p&gt;

&lt;p&gt;In 2026, most developers choose one of three approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SDKs&lt;/strong&gt; that run directly inside applications deliver raw speed and handle heavy workloads efficiently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web APIs&lt;/strong&gt; packaged as Docker containers help teams scale document processing easily across microservices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript/Node.js&lt;/strong&gt; solutions for web‑based, interactive experiences provide rich in‑browser viewing and editing without requiring additional installations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The real question isn’t “Which is best?” It’s “Which approach aligns with your workload, architecture, and UX requirements, and where does it make sense to combine them?”&lt;/p&gt;

&lt;p&gt;The best part is that &lt;strong&gt;Syncfusion&lt;sup&gt;®&lt;/sup&gt;&lt;/strong&gt; supports all three approaches, giving teams a single, reliable solution for any document‑processing workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 2026 dilemma: Speed, Scale, or Flexibility?
&lt;/h2&gt;

&lt;p&gt;Microsoft Office or Adobe‑based pipelines often struggle to keep up with modern automation demands, frequently introducing errors and bottlenecks.&lt;/p&gt;

&lt;p&gt;Document workloads keep getting more complex:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple formats:  &lt;strong&gt;PDF&lt;/strong&gt;, &lt;strong&gt;DOCX&lt;/strong&gt;, &lt;strong&gt;XLSX&lt;/strong&gt;, &lt;strong&gt;PPTX&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;More automation: Merge, split, convert, redact, sign, extract.&lt;/li&gt;
&lt;li&gt;Higher reliability requirements: Fewer failures, fewer “works on my machine” issues.&lt;/li&gt;
&lt;li&gt;More security pressure: sensitive documents, controlled environments, compliance needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Often create bottlenecks, add manual steps, and introduce dependency issues in server environments.&lt;/p&gt;

&lt;p&gt;So teams end up deciding two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Where does processing happen?&lt;/strong&gt;  In-process vs over HTTP vs in the browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How does it scale?&lt;/strong&gt;  Single service vs microservices vs client-side offload.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  3 approaches to modern document processing
&lt;/h2&gt;

&lt;p&gt;Each model plays a distinct role in meeting specific performance and scalability needs, which we’ll explore in detail below.&lt;/p&gt;

&lt;h3&gt;
  
  
  SDKs as the high-performance backbone
&lt;/h3&gt;

&lt;p&gt;If you need  &lt;strong&gt;low latency&lt;/strong&gt;  and  &lt;strong&gt;high throughput&lt;/strong&gt;, SDKs are usually the most direct path. They run inside your application process, so you avoid network overhead and keep tight control over document behavior.&lt;/p&gt;

&lt;p&gt;Syncfusion provides a complete &lt;strong&gt;.NET Document SDK&lt;/strong&gt; for programmatic processing across common formats, without any Microsoft Office dependencies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PDF Library&lt;/strong&gt;: Create, edit, merge, split, secure, and convert PDFs. You can process PDF files with advanced features like forms, OCR, redaction, digital signatures, and PDF/A compliance, all without relying on Adobe Acrobat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Word Library (DocIO)&lt;/strong&gt;: Create, edit, and convert Word documents with formatting, mail merge, charts, images, document protection, and PDF export.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Excel Library (XLSX)&lt;/strong&gt;: Create and modify spreadsheets, import and export data, use formulas, generate charts and pivot tables, apply conditional formats, and convert workbooks to PDF.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PowerPoint Library (PPTX)&lt;/strong&gt;: Build slide decks, update content, add images, create charts, apply animations and transitions, clone or merge slides, and export presentations to PDF.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why SDKs win&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Best fit for  &lt;strong&gt;performance-critical&lt;/strong&gt; services (conversion pipelines, batch jobs, high-volume generation).&lt;/li&gt;
&lt;li&gt;Strong option for  &lt;strong&gt;restricted environments&lt;/strong&gt; (no desktop installs, fewer moving parts).&lt;/li&gt;
&lt;li&gt;Deep APIs for document manipulation and compliance workflows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlock advanced PDF, Word, Excel, and PowerPoint automation with standalone, high‑performance libraries built for enterprise workloads. → Explore Syncfusion’s complete .NET Document Processing &lt;a href="https://www.syncfusion.com/document-sdk" rel="noopener noreferrer"&gt;Suite&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prefer building interactive, UI-driven document experiences instead of using libraries alone?&lt;/strong&gt; Syncfusion offers UI controls you can pair with the Document Libraries to create complete, end‑to‑end document workflows. Each UI SDK requires its own separate license and is not included with the Document SDK. If your application needs a fully interactive UI, the UI SDK is the right choice. For automation or server‑side processing, the Document SDK alone is sufficient.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.syncfusion.com/pdf-viewer-sdk" rel="noopener noreferrer"&gt;&lt;strong&gt;PDF Viewer SDK&lt;/strong&gt;&lt;/a&gt;: View, annotate, review, and redact PDFs directly in the browser.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.syncfusion.com/docx-editor-sdk" rel="noopener noreferrer"&gt;&lt;strong&gt;DOCX Editor SDK&lt;/strong&gt;&lt;/a&gt;: Create and edit Word documents online with full formatting, track changes, and comments.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.syncfusion.com/spreadsheet-editor-sdk" rel="noopener noreferrer"&gt;&lt;strong&gt;Spreadsheet Editor SDK&lt;/strong&gt;&lt;/a&gt;: Work with Excel-like spreadsheets online with formulas, formatting, and charts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cloud Native Scalability Web APIs (Docker)
&lt;/h3&gt;

&lt;p&gt;Using a &lt;strong&gt;ready-to-use Docker image&lt;/strong&gt; for document processing is a popular approach because it provides a consistent, portable, and easy-to-deploy environment. If your architecture is microservice-oriented or you need document processing accessible from multiple stacks Web APIs (Docker) are often the cleanest option.&lt;/p&gt;

&lt;p&gt;Dockerized APIs give you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A consistent runtime across dev/stage/prod.&lt;/li&gt;
&lt;li&gt;Easier scaling (run more containers when demand spikes).&lt;/li&gt;
&lt;li&gt;Language-agnostic access (anything that can call HTTP can use it).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Syncfusion’s  &lt;strong&gt;Docker-based Document Processing Web APIs&lt;/strong&gt;  are positioned for teams that want a ready-to-deploy container model, with benefits like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Preconfigured and ready to use&lt;/strong&gt;: Everything is included, so you can start processing documents immediately without manual setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scales easily&lt;/strong&gt;: Add more containers to handle higher workloads while keeping performance steady.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runs anywhere Docker runs&lt;/strong&gt;: Ensures consistent behavior across dev, staging, and production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure by design&lt;/strong&gt;: Host the API in your own infrastructure for full control over authentication, network rules, and compliance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible and customizable&lt;/strong&gt;: Extend the image or adjust configurations to fit your project’s needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When APIs win&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need document processing shared across multiple services or languages.&lt;/li&gt;
&lt;li&gt;You want predictable deployments and cleaner CI/CD.&lt;/li&gt;
&lt;li&gt;You prefer to centralize document logic behind versioned endpoints.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ready to deploy Syncfusion’s Document Processing Web APIs in Docker? Start with the official Docker setup &lt;a href="https://help.syncfusion.com/document-processing/web-apis/docker-image-hosting-guide" rel="noopener noreferrer"&gt;guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript &amp;amp; Node.js for Interactive and Collaborative Apps
&lt;/h3&gt;

&lt;p&gt;Using JavaScript and Node.js for document processing is increasingly popular because it enables fast, interactive, and fully client‑side workflows. With this approach, applications can generate and modify PDFs directly in the browser or in Node.js without relying on servers, plugins, or external software. This makes the experience lightweight, secure, and ideal for modern, real‑time, collaborative web applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syncfusion’s JavaScript PDF Library&lt;/strong&gt; enhances this approach by offering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A pure JavaScript PDF engine&lt;/strong&gt; that works entirely in the browser with zero installation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unified API for both browser and Node.js&lt;/strong&gt;, allowing client and server workflows to share the same code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No server dependencies&lt;/strong&gt;, making deployments simpler, faster, and more secure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full PDF creation and editing features&lt;/strong&gt;, including loading, editing, saving, and working with password‑protected files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rich PDF enhancements&lt;/strong&gt; such as adding text, images, shapes, hyperlinks, bookmarks, annotations, and form fields.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced operations&lt;/strong&gt;, including flattening, merging, splitting, redaction, text extraction, image extraction, and layer management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support for digital signatures&lt;/strong&gt;, enabling secure authentication and integrity checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Want to see the JavaScript PDF Library in action? Try the &lt;a href="https://document.syncfusion.com/demos/pdf/javascript/#/tailwind3/pdf/default.html" rel="noopener noreferrer"&gt;JavaScript PDF Library&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Document Processing SDK vs Web API vs JavaScript — Comparison Table
&lt;/h2&gt;

&lt;p&gt;Choosing the right document processing model depends on your performance needs, deployment style, and user experience goals. Here’s a simple table to help you decide the best approach for your needs.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Decision Factor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;.NET Document Processing SDKs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Web APIs (Docker)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;JavaScript / Node.js&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fastest &lt;strong&gt;in‑process&lt;/strong&gt; execution (no HTTP overhead)&lt;/td&gt;
&lt;td&gt;Slight overhead due to HTTP requests&lt;/td&gt;
&lt;td&gt;Fast in-browser; Node.js suitable for light–moderate workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup Requirements&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No Office/Acrobat required; works fully standalone&lt;/td&gt;
&lt;td&gt;Requires Docker + hosting environment&lt;/td&gt;
&lt;td&gt;Zero install in browser; Node.js runtime for server usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High‑performance backend automation in .NET&lt;/td&gt;
&lt;td&gt;Cloud‑native, microservice‑based architectures&lt;/td&gt;
&lt;td&gt;Interactive, real‑time client experiences&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Access Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;In‑app library calls&lt;/td&gt;
&lt;td&gt;HTTP API accessible from any stack&lt;/td&gt;
&lt;td&gt;Browser APIs + Node.js APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Scales by app instance&lt;/td&gt;
&lt;td&gt;Horizontal scaling by adding containers&lt;/td&gt;
&lt;td&gt;Browser scaling depends on client device; Node.js can scale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cross‑Platform Use&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;.NET-only&lt;/td&gt;
&lt;td&gt;Any language that can call HTTP&lt;/td&gt;
&lt;td&gt;Browser + Node.js (JavaScript ecosystems)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ideal Workloads&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Generation, conversion, protection, signing, heavy document processing&lt;/td&gt;
&lt;td&gt;High‑volume conversion/extraction shared across teams&lt;/td&gt;
&lt;td&gt;In‑browser viewing, annotation, collaboration, client‑side workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;When to Choose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You need maximum speed &amp;amp; deep control; automation-centric&lt;/td&gt;
&lt;td&gt;You need shared processing across teams or stacks; microservices&lt;/td&gt;
&lt;td&gt;You want real-time UX or privacy‑focused client-side operations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What the future suggests: Hybrid models win
&lt;/h2&gt;

&lt;p&gt;Most modern document apps don’t pick only one approach. They combine them to get speed, scale, and UX.&lt;/p&gt;

&lt;p&gt;Below are two practical hybrid patterns you can use.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SDK backend + JS frontend&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use  &lt;strong&gt;.NET SDKs&lt;/strong&gt; for high-speed creation/conversion/redaction/signing on the server.&lt;/li&gt;
&lt;li&gt;Use  &lt;strong&gt;in-browser JS&lt;/strong&gt; for viewing, forms, annotations, and interactive review.&lt;/li&gt;
&lt;li&gt;Optionally perform some edits fully in the browser using a JS PDF library.&lt;/li&gt;
&lt;li&gt;This pattern keeps heavy processing server-side while giving users a responsive UI.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Docker API + in-browser editors&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run document processing as  &lt;strong&gt;Dockerized Web APIs&lt;/strong&gt; for scalable conversions and operations&lt;/li&gt;
&lt;li&gt;Pair with  &lt;strong&gt;browser-based viewing/editing&lt;/strong&gt; for real-time interaction&lt;/li&gt;
&lt;li&gt;This pattern works well for microservices and multi-language organizations.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;With Syncfusion supporting SDKs, Docker‑based Web APIs, and JavaScript tools, you can mix and match to achieve the right balance of speed, scale, and user experience without locking yourself into a single approach. Syncfusion also offers UI controls like the PDF Viewer, DOCX Editor, and Spreadsheet Editor, which you can pair with any model to deliver rich in‑app viewing and editing experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Is client-side JavaScript PDF processing secure enough for sensitive documents?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A&lt;/strong&gt;: Client‑side processing improves privacy** because documents never leave the user’s device. Sensitive PDFs (medical forms, financial statements, legal drafts) can be viewed, annotated, and redacted safely without hitting a backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Are Docker-based document processing APIs suitable only for large enterprises?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A&lt;/strong&gt;: No. Even small products benefit from Web APIs because containers eliminate dependency headaches. Whether you run a single instance or thousands, Docker gives you predictable behavior and easy deployment—ideal for both startups and enterprise workloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Can Docker-based document APIs replace SDKs process entirely?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A&lt;/strong&gt;: Not fully. Docker‑based Web APIs scale easily and centralize document processing, but SDKs still offer the lowest latency because they run in‑process with no network calls. Many teams use Docker APIs for high‑volume workloads and SDKs for performance‑critical tasks inside core services. To learn more, see the &lt;a href="https://help.syncfusion.com/document-processing/web-apis/docker-image-hosting-guide" rel="noopener noreferrer"&gt;Docker Image Hosting Guide&lt;/a&gt;and the &lt;a href="https://help.syncfusion.com/document-processing/web-apis/overview" rel="noopener noreferrer"&gt;Ready to deploy Docker Image&lt;/a&gt; for Syncfusion document processing APIs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Do JavaScript libraries require Web Assembly or plugins to process PDFs?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A&lt;/strong&gt;: No. Syncfusion’s JavaScript PDF Library is a &lt;strong&gt;pure JS,&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/@syncfusion/ej2-pdf" rel="noopener noreferrer"&gt;non-UI library&lt;/a&gt;—no plugins or Web-Assembly needed. It supports full PDF manipulation: create, edit, annotate, sign, redact, merge, split, and more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Will Self-Hosted APIs lock me into a single tech stack?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A&lt;/strong&gt;: No. Because Web APIs are language‑agnostic (HTTP endpoints), they can be used from Java, Python, Go, Node.js, PHP, .NET, or anything else. This makes the API approach ideal for large teams using multiple stacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Are the UI components easy to integrate?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A&lt;/strong&gt;: Yes. Syncfusion’s UI components come with simple APIs, clear documentation, and ready-made examples, so you can add viewing or editing features to your app quickly and with minimal effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Thank you for reading! Document processing in 2026 isn’t about choosing one tool. It’s about choosing the right execution model for each part of your workflow.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pick  &lt;strong&gt;SDKs&lt;/strong&gt; for speed, deep control, and dependency-free backend automation.&lt;/li&gt;
&lt;li&gt;Pick &lt;strong&gt;Web APIs (Docker)&lt;/strong&gt; for cloud-native scaling and cross-stack reuse.&lt;/li&gt;
&lt;li&gt;Pick  &lt;strong&gt;JavaScript/Node.js&lt;/strong&gt; for interactive, zero-install browser experiences.&lt;/li&gt;
&lt;li&gt;Use a  &lt;strong&gt;hybrid&lt;/strong&gt; when you need both backend power and frontend UX.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Syncfusion supports all three approaches: .NET SDKs, Docker-based Web APIs, and JavaScript/Node libraries, so teams can implement the architecture that fits their product without re-platforming later.&lt;/p&gt;

&lt;p&gt;Ready to Power Your Apps with Syncfusion’s Document SDK? Explore the complete &lt;a href="https://www.syncfusion.com/document-sdk" rel="noopener noreferrer"&gt;Syncfusion Document Processing&lt;/a&gt; Suite.&lt;/p&gt;

&lt;p&gt;If you’re a Syncfusion user, you can download the setup from the &lt;a href="https://www.syncfusion.com/sales/teamlicense" rel="noopener noreferrer"&gt;license and downloads&lt;/a&gt; page. Otherwise, you can download a free &lt;a href="https://www.syncfusion.com/downloads/document-sdk?tag=es-seo-document-sdk-download-trial" rel="noopener noreferrer"&gt;30-day trial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also contact us through our &lt;a href="https://www.syncfusion.com/forums" rel="noopener noreferrer"&gt;support forum&lt;/a&gt;, &lt;a href="https://support.syncfusion.com/" rel="noopener noreferrer"&gt;support portal&lt;/a&gt;, or &lt;a href="https://www.syncfusion.com/feedback/document-sdk" rel="noopener noreferrer"&gt;feedback portal&lt;/a&gt; for queries. We are always happy to assist you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Blogs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/document-processing-libraries-2025-vol-2" rel="noopener noreferrer"&gt;Sneak Peek: Document Processing Libraries 2025 Volume 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/document-processing-library-2025-vol1" rel="noopener noreferrer"&gt;What’s New in Document Processing Libraries: 2025 Volume 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/document-processing-library-2024-vol4" rel="noopener noreferrer"&gt;What’s New in Document Processing Libraries: 2024 Volume 4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.syncfusion.com/blogs/post/document-processing-library-2024-vol3" rel="noopener noreferrer"&gt;What’s New in Document Processing Libraries: 2024 Volume 3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article was originally published at &lt;a href="https://www.syncfusion.com/blogs/post/modern-doc-processing-2026" rel="noopener noreferrer"&gt;Syncfusion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>documentprocessing</category>
      <category>net</category>
      <category>docker</category>
      <category>dockerbasedwebapis</category>
    </item>
  </channel>
</rss>
