Build a Rich Publisher App

Learning Objectives

After completing this unit, you’ll be able to:
  • List the interfaces and events provided in the Rich Publisher Apps platform.
  • Build a Rich Publisher App from scratch.
  • Configure Rich Publisher Apps in an Experience Cloud site.

Step 1. Upload Your Icon Image and Get Its File Asset ID

Rich Publisher App icons in the question publisher

To provide an icon to show in the feed publisher and to package it with your app, you need the icon’s fileAsset ID.

You use the fileAsset ID when you create the ChatterExtension entity. Adding the fileAsset ID to ChatterExtension lets you package the icon file with your app.

Here’s how you upload the icon image and get its fileAsset ID.



The Lightning Component framework has two programming models, Lightning Web Components and Aura. In this module, we build Rich Publisher Apps using Aura.

  1. Upload your icon file to Salesforce.
  2. Copy the file ID. Note You can get the file ID from file details in Salesforce. Go to the Files page, and view file details. Copy the file ID from your browser’s URL. It’s a long number, like 069R00000003roQ.
  3. Go to Workbench, and get the value for id under fileAsset.

    1. In the REST Explorer, select Post, and enter the path: /services/data/v43.0/connect/files/[file_ID]/asset
    2. For [file_ID], enter the file ID you copied in Step 2.
    3. In the Request Body, enter {}.

      A fileAsset ID in Workbench

    4. Click Execute.
    5. Expand the fileAsset node, copy the value for id, and paste it somewhere for later user.

Step 2. Create Lightning Components for Composition and Rendering

When a site member clicks a Rich Publisher App icon, the action causes a composition modal to open. The modal contains a Lightning component. The Lightning component enables the user to select something, search for something, or generate something. You have the freedom to customize this component for your use case.

Let’s see how one company uses the Rich Publisher Apps platform to attach cases to posts and questions.

Meet Capricorn

Capricorn sells coffee and high-end coffee brewing equipment and prides itself on its customer service. One of its secrets is the site it set up for customer service agents to discuss open cases and collaborate on solutions. Capricorn wants to develop a Rich Publisher App for attaching cases to posts and questions. They want to give their agents a way to mine past solutions for quick resolutions in the present. Here’s what they do.

A. Create the First Lightning Component

Create a Lightning component that extends the Lightning interface lightning:availableForChatterExtensionComposer. The composition component uses this interface.

The Capricorn developer team uses an aura iteration to show list items in the component code. Here is the Lightning component code.

<aura:component implements="lightning:availableForChatterExtensionComposer" controller="caseController">
    <aura:handler name="init" value="{!this}" action="{!c.init}"/>
    <aura:attribute name="items" type="List" description="Contains a list of items for user to select."/>
    <div class="container">
        <aura:iteration items="{!v.items}" var="item" indexVar="index">
            <div class="itemContainer" onclick="{!c.selected}">
                <div class="itemLeft">
                	<img class="itemIcon" src=""></img>
                <div class="itemRight">
                    <div class="itemTitle">{!item.title}</div>
                	<div class="itemDescription">Case Number: {!item.caseNo}</div>

The Capricorn team makes an Apex request in the controller init function to fetch support case information for the selection list. Here is the controller code associated with the Lightning component.

	init : function(cmp, event, helper) {
        var action = cmp.get("c.getCases");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                var caseList = [];
                var response = response.getReturnValue();
                for (var i=0;i<response.length;i++) {
                        "title": response[i].Subject,
                        "caseNo": response[i].CaseNumber
                cmp.set("v.items", caseList);
    selected: function(cmp, event, helper) {
        var selectedItem = helper.getSelectedItem(cmp, event);
		var compEvent = cmp.getEvent("sendChatterExtensionPayload");
			"payload" : helper.getPayload(selectedItem),
			"extensionTitle" : helper.getTitle(selectedItem),
			"extensionDescription" : helper.getDescription(selectedItem)

Here is the helper code to go along with the controller.

    getSelectedItem: function(cmp, event) {
        var clicked = event.currentTarget;
        var parent = clicked.parentElement;
        var total = parent.children.length;
        var selectedIndex = -1;
        for(var i=0; i<total; i++) {
            if(clicked === parent.children.item(i)) {
                selectedIndex = i;
            $A.util.removeClass(parent.children.item(i), "selected");
        $A.util.addClass(clicked, "selected");
        var selectedTh = cmp.get("v.items")[selectedIndex];
        return selectedTh;
    getPayload: function(item) {
        return item;
    getTitle: function(item) {
        return item.title;
    getDescription: function(item) {
        return item.caseNo;


Here’s one way to write an Apex call for the getCases function.

public class caseController {
    public static List<Case> getCases() {
       List<Case> cases = [SELECT AccountId,CaseNumber,Subject,Description,Id FROM Case ORDER BY CreatedDate ASC NULLS FIRST LIMIT 20];
       return cases;

You can implement your own way for users to make a selection. You can have any logic in Apex for getting smart or fresh data using internal or third-party services to build powerful Rich Publisher Apps.

The important thing is to make sure that a user-click triggers the aura event lightning:sendChatterExtensionPayload in the controller code. In Capricorn’s code sample, the team set up the event in the selected function. Setting the event in the selected function sends the payload to associate with the feed item when the user makes a selection.

The team sets the extensionTitle and extensionDescription metadata using helper functions to associate with the payload. This metadata is for non-Lightning use cases, like email notifications or Classic view. Optionally, you can also add a thumbnail URL.

Here is a modal with a title and thumbnails.

List items in a composer component

The Rich Publisher Apps platform also provides the Add and Cancel buttons. In the previous image, the Add button is disabled. The Add button is enabled only after the lightning:sendChatterExtensionPayload event is fired with a non-empty payload. Notice in the previous image that no case is selected, and in the next image a case is selected. If the event is fired with an empty payload, then the button stays disabled.

Enabled Add button

B. Create the Second Lightning Component

Next, the Capricorn team creates a Lightning component that extends the Lightning interface lightning:availableForChatterExtensionRenderer. This interface renders the selected payload in the publisher when the FeedItem is rendered. There are two essential attributes as part of this interface: variant and payload. The variant attribute lets you decide how to render something based on whether the selected app is previewed in the publisher or rendered in the FeedItem. The payload attribute is the JavaScript Object that the user selected in the composition component.

<aura:component implements="lightning:availableForChatterExtensionRenderer">
    <div class="container">
        <a target="_blank" href="{!v.payload.url}">
            <div class="{! (v.variant == 'FEED' ? 'itemContainerBorder' : '') + ' itemContainer'}">
                <div class="itemLeft">
                    <img class="itemIcon" src="{!v.payload.icon}"></img>
                <div class="itemRight">
                    <div class="itemTitle">{!v.payload.title}</div>
                    <div class="itemSubtitle">{!v.payload.subtitle}</div>
                    <div class="itemDescription">Case Number: {!v.payload.caseNo}</div>

Capricorn uses the variant FEED to decide which CSS class to use. The use of FEED signals the rendering of the Rich Publisher App in a FeedItem. To render the app in the publisher, use the variant PREVIEW. The payload information shows which case to render. In this example, the payload is static. But you can also use server-side Apex controllers to get live, dynamic information inside your renderer component.

Here’s how the payload looks as a preview inside the publisher (PREVIEW):

Preview of a Rich Publisher App payload

Here’s how the payload looks in the final rendered feed item (FEED):

Rich Publisher App payload published with a feed item

Step 3. Create a Rich Publisher App in Workbench

Now that you’ve created the Lightning components and grabbed the fileAsset ID, you’re ready to create the Rich Publisher App in Workbench.

Go to Workbench, and insert a ChatterExtension object (Workbench > Data > Insert > ChatterExtension). Then associate all your component values with ChatterExtension fields.



One way to get component values is to go to Setup and search for Lightning Components. Click a listed component to view its details. Copy the component ID from the browser URL.

The ChatterExtension object

  • Provide the Lightning component ID for the composition component.
  • Add text for the modal header.
  • Add hover text for the app icon (the icon that appears in the feed publisher).
  • Provide the fileAsset ID for the app icon.
  • Provide the Lightning component ID for the render component.
  • For Type enter Lightning. Currently, Lightning is the only type available.


You can localize header and hover text in Translation Workbench.

Step 4. Enable Rich Publisher Apps in Your Experience Cloud Site

When everything’s ready to go, the Capricorn team adds the app to the feed publisher in their site. You can add up to five Rich Publisher Apps to your site through the Administration Workspace in Experience Workspaces.

  1. Go to Experience Workspaces, and click the Administration tile.
  2. In the navigation column, click Rich Publisher Apps.
  3. Select up to five apps from the Available Apps column, and move them to the Selected Apps column.Rich Publisher Apps in the Administration Workspace]
  4. To set the order of icons in the publisher, move selected apps up or down the list.
  5. Click Save.
Keep learning for
Sign up for an account to continue.
What’s in it for you?
  • 1 in 4 land a new job
  • 50% receive a promotion or raise
  • 80% learn new technologies that boost their resume
  • 66% say it increases productivity
Source: Trailblazer Community Impact Survey 2019