Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
A glowing 3D cube with circuit patterns, representing Agentforce Script rendering Rich Text Area data.
Agentforce & AI

Agentforce Script: Rendering Rich Text Area Fields

How to render Rich Text Area (RTA) field content from an Agentforce Script: pulling the HTML out with SOQL, choosing between direct rendering and parsing, and the security and performance traps on the way.

Key takeaways Agentforce Scripts can dynamically render Rich Text Area fields inside AI-driven interactions. Retrieve RTA data using SOQL in your Apex script. Decide whether to render raw HTML directly (where that is supported) or to parse and reformat the content. The exact output structure for Agentforce depends on its configuration and the UI components used. Weigh security, performance, and the possibility of embedded images before you ship. Consult the Agentforce documentation and test iteratively.

Agentforce Script: Rendering Rich Text Area Fields

Agentforce Scripts orchestrate AI interactions, and they can return more than plain text. One of the things they can do, which gets overlooked, is render the contents of a Rich Text Area (RTA) field inside the interaction itself, so an agent or a customer sees formatted content instead of a wall of markup.

What follows is how to display RTA field content from an Agentforce Script: where the data comes from, what the output has to look like, and the parts that bite. It assumes you are a Salesforce developer, architect or administrator already working on an Agentforce implementation.

Understanding Rich Text Area Fields and Agentforce Scripts

Rich Text Area fields store formatted text: bold, italics, bullet points, numbered lists, hyperlinks, even embedded images. Push that through an AI interaction by concatenating the raw HTML and you get a cluttered, unreadable result. Agentforce Scripts give you a structured way to process and present it instead.

Agentforce Scripts are Apex classes that implement specific interfaces, which is how they hook into the AI interaction lifecycle. With RTA fields, the work is in how you retrieve the data and then how you instruct Agentforce to display it. Agentforce typically expects output in a structured format, often JSON, which it then interprets and presents to the end user.

Retrieving Rich Text Area data

First, get the data out of Salesforce, normally with a SOQL query inside your Apex class. Say you have a custom object called Case_Feedback__c with an RTA field named Customer_Comments__c:

List<Case_Feedback__c> feedbackRecords = [SELECT Id, Customer_Comments__c FROM Case_Feedback__c WHERE Id = :recordId LIMIT 1];

if (!feedbackRecords.isEmpty()) {
    Case_Feedback__c feedback = feedbackRecords[0];
    String richTextContent = feedback.Customer_Comments__c;
    // Process richTextContent here
}

A few things about RTA data will catch you out. The content is stored as HTML, so feedback.Customer_Comments__c hands you a string full of markup, and you have to decide whether to display it as-is (which Agentforce may interpret) or parse and sanitize it first. The field can also be empty, so your logic has to handle null and empty strings gracefully. And your Apex user needs read access to the RTA field you are querying, which is easy to forget until a test user sees nothing.

Strategizing the Output for Agentforce

Agentforce Scripts don't render HTML the way a Visualforce page might. They define structured responses, and Agentforce uses those responses to construct the user interface. Displaying RTA content therefore means telling Agentforce how to present the HTML, usually by returning a specific output structure it recognizes.

That structure is often JSON. A common approach uses the AgentBotResponse and AgentBotMessage objects, or whatever similar custom structures your Agentforce configuration expects.

Option 1: direct HTML rendering (if the Agentforce UI supports it)

In some Agentforce configurations, the UI components can render raw HTML. Where that holds, pass the HTML content straight through in your structured response.

// Inside your Agentforce Script Apex class
public virtual AgentBotResponse processRequest(AgentBotRequest request) {
    String recordId = request.get('recordId'); // Assuming recordId is passed in the request
    String htmlContent = '';

    List<Case_Feedback__c> feedbackRecords = [SELECT Id, Customer_Comments__c FROM Case_Feedback__c WHERE Id = :recordId LIMIT 1];
    if (!feedbackRecords.isEmpty() && feedbackRecords[0].Customer_Comments__c != null) {
        htmlContent = feedbackRecords[0].Customer_Comments__c;
    }

    AgentBotResponse response = new AgentBotResponse();
    List<AgentBotMessage> messages = new List<AgentBotMessage>();

    // Create a message that Agentforce can render as rich text
    // The exact structure depends on your Agentforce configuration.
    // Often, a 'text' or 'html' field is expected.
    AgentBotMessage richTextMessage = new AgentBotMessage();
    richTextMessage.set('type', 'text'); // Or 'html' if your Agentforce UI component supports it
    richTextMessage.set('value', htmlContent);
    messages.add(richTextMessage);

    response.set('messages', messages);
    return response;
}

A warning on that snippet: AgentBotMessage and its properties (type, value) are illustrative. You have to check your own Agentforce implementation's documentation, or an existing configuration, for the exact structure Agentforce expects when rendering rich text or HTML. The type might be text with the HTML sitting in value, or there might be a dedicated html type.

Option 2: parsing and reformatting HTML

Direct HTML rendering is not always what you want. Security concerns can rule it out, or you may want the content reformatted into a more standardized agent-facing view. That means parsing the HTML, extracting the text or structure you care about, and rebuilding it with simpler text elements or a more controlled HTML structure.

For complex HTML parsing, a third-party Apex library or a more thorough parsing approach is worth the effort. For many everyday RTA fields, basic string manipulation or regular expressions will get you there.

The example below extracts plain text. It is a very basic illustration and it is not a robust HTML parser. For production, use something more careful if your RTA content is complex.

// Inside your Agentforce Script Apex class
public virtual AgentBotResponse processRequest(AgentBotRequest request) {
    String recordId = request.get('recordId');
    String plainTextContent = 'No comments available.';

    List<Case_Feedback__c> feedbackRecords = [SELECT Id, Customer_Comments__c FROM Case_Feedback__c WHERE Id = :recordId LIMIT 1];
    if (!feedbackRecords.isEmpty() && feedbackRecords[0].Customer_Comments__c != null) {
        plainTextContent = extractPlainTextFromHtml(feedbackRecords[0].Customer_Comments__c);
    }

    AgentBotResponse response = new AgentBotResponse();
    List<AgentBotMessage> messages = new List<AgentBotMessage>();

    AgentBotMessage textMessage = new AgentBotMessage();
    textMessage.set('type', 'text');
    textMessage.set('value', 'Customer Comments:\n' + plainTextContent);
    messages.add(textMessage);

    response.set('messages', messages);
    return response;
}

/**
 * Very basic HTML to plain text extraction. 
 * Does NOT handle complex HTML, nested tags, or attributes robustly.
 * Use with caution or opt for a dedicated HTML parser.
 */
private String extractPlainTextFromHtml(String htmlString) {
    if (String.isBlank(htmlString)) {
        return '';
    }
    // Remove common HTML tags
    String plainText = htmlString.replaceAll('<br\s*/?>', '\n'); // Replace <br> with newline
    plainText = plainText.replaceAll('<p[^>]*>', ''); // Remove <p> tags
    plainText = plainText.replaceAll('</p>', '\n\n'); // Add newlines after </p>
    plainText = plainText.replaceAll('<li[^>]*>', '- '); // Replace <li> with bullet point
    plainText = plainText.replaceAll('</li>', ''); // Remove closing </li>
    plainText = plainText.replaceAll('<strong[^>]*>', ''); // Remove <strong>
    plainText = plainText.replaceAll('</strong>', ''); // Remove </strong>
    plainText = plainText.replaceAll('<em[^>]*>', ''); // Remove <em>
    plainText = plainText.replaceAll('</em>', ''); // Remove </em>
    plainText = plainText.replaceAll('<a[^>]*href="([^"]*)"[^>]*>', '$1 '); // Extract link URL
    plainText = plainText.replaceAll('</a>', ''); // Remove closing </a>
    plainText = plainText.replaceAll('<h[1-6][^>]*>', ''); // Remove heading tags
    plainText = plainText.replaceAll('</h[1-6]>', '\n\n');
    plainText = plainText.replaceAll('<[^>]+>', ''); // Remove any remaining tags

    // Decode HTML entities (basic example)
    plainText = plainText.replaceAll('&nbsp;', ' ');
    plainText = plainText.replaceAll('&lt;', '<');
    plainText = plainText.replaceAll('&gt;', '>');
    plainText = plainText.replaceAll('&amp;', '&');

    return plainText.trim();
}

If you do parse, decide up front what you are parsing for. Do you need to preserve formatting like bullet points, or only extract the core text? The extractPlainTextFromHtml method above is a starting point. For anything sturdier, look at specialized Apex HTML parsing libraries if you have access to one, or carefully craft regular expressions against the RTA content patterns you actually expect.

Advanced Scenarios and Best Practices

1. Handling embedded images

Rich Text Area fields can contain embedded images, and you have three ways to deal with them. The simplest is to ignore them: strip the image tags in your HTML parsing logic. If the images are hosted publicly and you want them displayed, you can extract the src attribute from the <img> tag and pass that URL to an Agentforce component capable of displaying images, which takes a more sophisticated parser. And if the images are critical and stored as Salesforce Files related to the record, your Agentforce Script may need to query those Files and return their URLs or relevant metadata for display.

2. Security considerations

Rendering arbitrary HTML from RTA fields can open you up to cross-site scripting, particularly where the content is user-generated and not properly sanitized. Agentforce's rendering engine might have sanitization built in. Be aware of the risk rather than assuming it is handled.

If the RTA content is entered directly by users, sanitize it server-side in your Apex before passing it to Agentforce. Libraries like ApexSecurity (if you use it) or careful regex can help. Where you control what gets saved into the field in the first place, enforce a stricter set of allowed HTML tags with a validation rule or an Apex trigger on the object itself.

3. Performance

Keep the SOQL efficient: SELECT only the fields you need and LIMIT where appropriate. If RTA fields can hold very large amounts of HTML, cap how much data you process or display before it turns into a performance problem.

4. Agentforce configuration decides what works

Whether any of this renders comes down to how Agentforce itself is configured to interpret the responses coming back from your Apex scripts.

Check the latest Salesforce documentation for Agentforce and for the specific AI framework you are using (Einstein Bots, Copilot integrations, and so on) for how it handles rich text, HTML, and structured message types. If you already have Agentforce implementations running, look at how they return messages and data, which will tell you a lot about the expected JSON structure. Then build it up in stages: start with simple text outputs, add RTA rendering, and test at each step.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment