Live from Dreamforce: Turn Invocable Flow Actions into Reactive Screen Components

I’ve come up with a generalized method to actually make any existing Invocable Action available to a Flow as a Reactive Screen Component.  I’ll be showing the results of this Wednesday morning in the Breakout Session I’m presenting with Michelle Hansen and Adam White, When Is It Best to Be Reactive? When You’re a Screen Flow.

Get all of the details here.

Implementing a Simple Timeline in Salesforce Using Vis.js

Petr Novotný has created an excellent LWC component for showing a Gantt like chart. Here is his write-up on the component along with links to the installation package and the source code.

Petr Novotný – Salesforce Professional ★ Certified Consultant, Architect & DEV | PRINCE2 | 15+ Yrs in IT | Global Project Lead | Helping Companies Design, Lead & Develop CRM Implementations

Throughout my numerous Salesforce implementations, I’ve often yearned for a simple means to visualize tasks on a timeline. Fortunately, I’ve discovered a solution and I’m eager to share it with you. Salesforce has an exceptional community, particularly the contributors to, from whom I’ve learned a great deal. Now, it’s time for me to give back.

 With a basic understanding of Salesforce Flows and CSS, you can enhance your timeline with enriched features including different object grouping, dynamic task status visualization, and even task owner images.

So, what do you need to do? Let’s delve into the basics.

The Timeline is a Lightning Web Component (LWC) designed for Salesforce Screen Flows. It works primarily with two input collections. The first collection comprises the set of items you’d like displayed on the timeline. The second collection refers to the categories you’d like to use for grouping timeline items (this could be left blank if preferred).

The magic happens thanks to the external open-source Vis.js library, which is uploaded to Salesforce as a static resource. This LWC component leverages Vis.js to effectively visualize your tasks in a timeline format.

Let’s define a sample use case.

No alt text provided for this image
Sample Timeline

We have a Project object under which there are Task objects. Our objective is to show the project timeline on the Project record page.

Here’s how you can achieve this step-by-step:

           1.        Create a screen flow with recordId as an input variable.

           2.        Query all the tasks related to the given project.

           3.        Prepare the timeline item collection from these tasks.

           4.        Position the LWC on the screen and populate it with the timeline item collection.

           5.        Finally, place the screen flow on the Project record object page

No alt text provided for this image
Screen Flow

Given the basic understanding of Salesforce flows, steps 1, 2, and 5 should be quite straightforward – it’s the usual process of creating a screen flow, querying related tasks, and placing the flow on a record object page.

Therefore, in this article, let’s focus more on steps 3 and 4 where things get a bit more complex – preparing the timeline item collection and implementing the Lightning Web Component. These are the crucial steps in our process of visualizing tasks on a timeline.

Step 3 Task loop

Start by defining an apex-defined variable for the timeline item, followed by the timeline item collection.

No alt text provided for this image
Timeline Item Variable
No alt text provided for this image
Timeline Collection Variable

During the loop, we are creating timeline items and adding them to the collection. This collection will serve as an input for the timeline LWC.

Each Timeline Item encompasses the following attributes:

           •         itemContent: The contents of the item. Can be plain text or HTML code.

           •         itemStart: The start date of the item on the timeline.

           •         itemEnd: The end date of the item. This is optional and can be left null. If an end date is provided, the item is displayed as a range; without it, the item is displayed as a box.

           •         itemGroup: A group ID to use if you wish to group timeline items.

           •         itemType: The type of the item. Options include ‘box’ (default), ‘point’, ‘range’, or ‘background’. ‘Box’ and ‘point’ need a start date, while ‘range’ and ‘background’ require both a start and an end date.

           •         itemStyle: A CSS text string to apply custom styling for an individual item, for example, “color: red; background-color: pink;”.

Within the flow, we are filling the itemContent with a picture and a task description in HTML, handling situations when a task has only a due date without a start date. Finally, we assign different colors to timeline items based on the task status: Green for resolved tasks and Red for overdue tasks.

Step 4: Placing the LWC Component

In this step, we position the Lightning Web Component (LWC) in the screen flow, and integrate the itemCollection variable into the LWC. This ensures that the timeline displays the items we structured in the prior step.

No alt text provided for this image
Edit Screen


To get started, download the package and install it in your Salesforce organization.

The package contains the following components. Allow me to explain each of them:

No alt text provided for this image
package components

Ideas for Implementation

The true power of an effective timeline visualization lies in its potential for enhancement and customization. Picture yourself as a project manager who can, with a single click, get a comprehensive view of the entire project.

For instance, we could incorporate a refresh button into the flow. This would re-query the data, keeping the timeline updated in real time – an essential feature for managing dynamic projects.

Beyond tasks, we could extend this model to display multiple types of objects related to the project, providing a holistic, one-glance understanding of diverse project elements.

The addition of filter buttons might prove helpful too. These could help the project manager focus on key aspects like overdue tasks, upcoming milestones, or tasks assigned to specific individuals or teams.

Isn’t it wonderful to envision a tool that enables Project Managers to quickly grasp the project status and swiftly make informed decisions?

Quite intriguing, isn’t it?

Wishing you success on your Salesforce journey. Cheers!


Documentation of Attributes and Sample Values

TimelineItem Attributes:

           •         itemContent: The contents of the item. This can be plain text or HTML code.

           •         itemStart: The start date of the item on the timeline.

           •         itemEnd: The end date of the item. This is optional and can be left null if unavailable. If an end date is provided, the item is displayed as a range. If not, the item is displayed as a box.

           •         itemGroup: Group ID. Utilize this if you want to group timeline items.

           •         itemType: The type of the item. Can be ‘box’ (default), ‘point’, ‘range’, or ‘background’. Note: ‘box’ and ‘point’ require a start date, while ‘range’ and ‘background’ require both a start and end date.

           •         itemStyle: A CSS text string to apply custom styling for an individual item, for example “color: red; background-color: pink;”.

Sample Values for TimelineItem:

           •         itemContent: “Data Design”

           •         itemStart: “2023-01-01”

           •         itemEnd: “2023-02-01”

           •         itemGroup: “deliveryGroupId”

           •         itemType: null

           •         itemStyle: “background-color:#F3E8FF;border-color:#9333EA;color:#9333EA

TimelineGroup Attributes:

           •         groupId: An ID for the group. The group will display all items having a ‘group’ property that matches the ID of the group.

           •         groupContent: The contents of the group. This can be plain text, HTML code, or an HTML element.

Sample Values for TimelineGroup:

           •         groupId: “deliveryGroupId”

           •         groupContent: “Delivery”

Links to Vis.js Library Documentation:

           •         Vis.js Timeline Examples

           •         Vis.js Timeline Docs

Source Code

Build Lightning Styled Screen Flows that Users will Love

Screen Flows have become an indispensable tool for Salesforce admins and developers to quickly construct guided wizards, prompts, input forms, and more without writing code. However, when it comes to look and feel, the default styling for displaying things has limited options and may not match user expectations. Many developer and third party hours have been spent building custom components or packages to help fill this styling gap instead of helping tackle more complex problems. But what if we could customize the appearance of screen flows without having to write or install any custom components?

The answer is the Salesforce Lightning Design System (SLDS), a collection of design guidelines, resources, and code samples that help you create consistent and beautiful user experiences across the Salesforce platform. The design system is intended to help developers build user interfaces that can seamlessly integrate across the platform by providing a set of styling keywords (CSS classes) that you can apply to elements to change their style, layout, and behavior. Here’s the thing: its not just for developers and designers anymore! You can take advantage of this design system directly in your Screen Flows, and its a lot easier than you might be imagining. The best part is worth repeating: this is all without building or installing any custom components.

Is this too good to be true? What if I told you that the below screenshot was built entirely using out-of-the-box configuration in a screen flow?

Look, Ma! No Code! An array of elements styled with the Lightning Design System using the Display Text Screen Flow component

In this post, we’ll walk through how SLDS CSS classes can be used directly in Screen Flows to style your screen flows in a few simple steps.

  • The trick that makes this work (hint: Display Text and Data Table are your friends)
  • How to make it easy to incorporate and use across any Screen Flow (hint: Custom Labels are your new best friend)
  • Some examples of my favorites

Good news: you don’t have to be an expert in HTML or CSS to use this to your advantage. Better news: the more you learn about it, the more you do with it!

For this post, I will provide all of the “markup” you need to get going right away on your own, as well as a repository of examples you can use for reference, but I encourage you to learn more, because there is a lot more that is possible than what I have space to show you here.

How it works: HTML Markup in Display Text

I’ll try to keep this post light on the nitty-gritty details of how HTML works, but its important to give some context as to what’s going on. There are three key facts that work together that allow us to lightning-ify our Screen Flows:

  1. At its core, the standard Display Text component is really an HTML editor plus a mechanism at runtime to display that HTML after the Flow engine resolves any references to Flow resources you’ve includeed. When you build some formatted content in the rich text editor for the Display Text component, under the hood it is saving it as styled HTML. This means that when a Screen Flow runs and has a Display Text component, all it really is doing is rendering that HTML in the same way that HTML is rendered anywhere else on the platform.
  2. One of the things that the Display Text component does under the hood is that it accepts Flow Resource references, such as a field value from a record, or the result of a Flow Formula resource. Before a Screen renders, these references are resolved using the most current values in the Flow. If the resolved value of one of those Flow resources includes HTML markup elements, that markup gets treated the same as any other markup that gets displayed on the page!
  3. The CSS classes that make up the Salesforce Lightning Design System are loaded into the browser in almost every context that you might be running a Screen Flow, and any HTML elements on the page can use those classes to define how it is styled and displayed. (there are some exceptions to this: Screen Flows in Slack and Screen Flows in Classic come to mind)

With these three facts taken together, we can see that we can use Display Text to include Lightning Design System styling by simply including the HTML markup that uses SLDS classes merged in from a Flow Resource, like a variable, formula, or text template.

If you’re a bit lost at this point, don’t panic! You don’t have to understand this part, and if you keep following along, you’ll see how easy it is to use, whether you understand why or not. Let’s start with a basic example: let’s put an SLDS box around some text.

The Basics with Box

If you have a Screen Flow that includes some instructional text, how nice would it be to draw users’ attention to it by using SLDS’s Box utility?

A screen shot from the lightning design system website demonstrating what the slds box blueprint looks like, showing what is called a regular sized box: text with a border around it that fills the width of the region it is in.

The SLDS box is pretty simple, you can see the markup for it is just:

<div class="slds-box">STUFF INSIDE THE BOX!</div>

How can we use this in Screen Flows without installing VS Code, firing up the Lightning Web Component Trailheads, and building a custom component? Let’s start by creating a Text Template called textInABox that has this example in it.

Important: use “Plain text” as the type of Text Template for this!

A screenshot of editing a text template resource in Flow Builder, with an API name of "textInABox", a body with HTML markup, and the "view as Plain Text" option set

Add a Screen, and in that Screen, add a Display Text component. In that Display text component, add your textInABox resource.

A screenshot of a screen editor in Flow Builder with a Display Text component that has the "{!textInABox}" resource included in its content

Now, if you save your flow and use “Debug” to see it in action, you should see a nice rounded box with padding around the text “STUFF INSIDE THE BOX!” like this:

A screenshot of the Flow at run time, showing the lightning-styled rendered markup that was in the text template

You can even place this inside a section’s column to constrain it to a smaller size!

Pretty cool stuff already! There are a two extra steps I think are important to really make this a practical reusable technique for use in the real world.


But if you stop here and only use what I’ve shown above, you’d have to build a separate Text Template for each lightning-styled text that you want to display, and if you want to edit the content, you’d have to find which text template has the content and go edit that. Not very reusable or maintainable. We can do better by taking advantage of a quirk of how Display Text components show HTML markup. You’ll notice that our little HTML snippet starts with <div ...> and ends with </div>. Those are what’s known as opening and closing tags. If HTML markup for an element has an opening tag, but doesn’t have a closing tag, that’s what’s known as malformed HTML and it doesn’t show up right in the page! Luckily for us, the engineers at Salesforce are very smart people and understand that just a little bit of malformed HTML could mess up the whole page, so as part of rendering the HTML from a Display Text component, they automatically look for and add closing tags for any HTML that is missing them!

How does this help us? This means that all we need in our Text Template is the opening tag, then we can put our content inside the Display Text after the Text Template, and the closing tag gets automatically added when we run the flow!

Let’s try our example now with an updated boxTemplate Text Template that has just <div class="slds-box"> without its corresponding </div>

Now when we add it to a Display Text component, we can add the content immediately after the boxTemplate resource (I like putting a line break between them for readability, it won’t affect the results)

And when we run the Flow, you’ll see it displays inside the box, just like before, even though we didn’t properly close the tag:

This enables us to reuse that boxTemplate resource wherever we need to in this Flow!

Getting pretty cool, right? There’s still one more step to go to really become practical in terms of reusability and maintenance. With what we’ve got so far, we can reuse the boxTemplate resource within this Flow, but we can’t use it in other Flows. That one last thing we need to make this reusable across Flows in our org: Custom Labels. If we add a Custom Label to the org with that HTML markup, we can reference it from any Flow, and Display Text will treat it just like it does any other resource! We can add each SLDS “blueprint” that we want to use just once now, and simply reference them where we need them. I like adding the prefix “FlowStyles_” to each Custom Label, and at the bottom of this post I’ll link you to a resource that has all my favorite reusable FlowStyles as custom labels.

To try this out, in Setup -> Custom Labels, add a new Custom Label

Using Custom Labels in a Flow is exactly the same as other resources, you’ll find them under the $Label global resource in the resource picker.

So there it is! Reusable lightning styling without building a custom component or installing a package!

What else can we do with this? I’d love to hear how this technique can be used with all the creative Flow builders out there. I’ll show a couple more examples below, and link to a resource where you can download a custom labels file that has a bunch of prebuilt SLDS blueprints ready for you to use.


Notification Messages

Wouldn’t it be nice to show success, warning, and error messages in a way that’s familiar and expected to users? You can do that with the SLDS Scoped Notification blueprint!

Custom Label: FlowStyles_Notification_Success

<div class="slds-scoped-notification slds-theme_success" role="status">

Custom Label: FlowStyles_Notification_Warning

<div class="slds-scoped-notification slds-theme_warning" role="status">

Custom Label: FlowStyles_Notification_Error

<div class="slds-scoped-notification slds-theme_error" role="status">

How these look in the Screen Editor:

And how they look when you run the Flow:

Section Headers

In Summer 22, Sections got an upgrade to allow you to display a Header Label with the Section. It’s been a great feature. But there are a few limitations in its current state:

  • If you provide a label, it will be collapsible, with no option to disable the collapsibility.
  • You can only apply the header label across the entire section, not within a column of a section.
  • The label is static, meaning it can’t be derived from an “upstream” variable reference from the Flow.

With our SLDS in Flows technique (I like the word “technique” better than “trick”, don’t you?), we can have non-collapsible, dynamic Section Headers that can be placed within a single column of a Flow Section (or spread the entire width if that’s what you need)

Here’s the markup for a Custom Label we’ll call FlowStyles_SectionHeader

<div class="slds-section slds-section__title slds-theme_shade slds-p-horizontal_small">

How it looks in the editor:

And finally when we run the Flow:

Links that look like Buttons

Many screen flow use cases end up with a need to provide users with a link to a record, page, or external website. A plain old hypertext link simply does not capture the attention of users in the way that the use case often demands. A common way to address this is to use custom navigation components to, for instance, navigate the user to a record page when they click “Finish”. Not even that will help much if you need to give the user more than one option or place to go.

But what if we could simply style those plain old hypertext links to look like buttons? Our little SLDS technique can do just that.

Note: This example can’t really leverage (easily) the same $Label reusability, because you can’t just stick the content at the end. You’ll see what I mean.

This time, instead of a Text Template resource, let’s try using a Formula resource in the Flow. Let’s say you have a record variable in your flow called NewRecord and on a Screen after creating that record, you want to provide the user a button/link that will open the record page for that newly created record. You could create a Formula Resource like the following:

'<a class="slds-button slds-button_brand" target="_top" href="' &
    LEFT( {!$Api.Partner_Server_URL_580} , FIND( '/services/' , {!$Api.Partner_Server_URL_580})) & {!NewRecord.Id} &
'">View Record</a>'

Now when you place that formula resource into a Display Text component…. voila! …. you’ve got a link that is styled just like a button.

Some notes:

  • The “View Record” part is the label- change that to whatever you want the label for this “button” link to be
  • If you want to have the link open in a new browser tab, replace target="_top" with target="_blank"
  • If you want a different style of button, you can replace slds-button_brand with other button styles, like slds-button_outline-brand or slds-button_neutral
  • The stuff with LEFT() and Partner_Server_URL_580? That helps construct the base url dynamically so that this will work just as well in a community or in lightning experience or wherever you need to use it.

A really neat use case for this for presenting a button to generate a Conga document.

Data Table cells

Until now, this post has focused on using the Display Text component as the “host” for our SLDS styling. There is one other component that we can leverage for this technique: Data Table! If the field for a given column in the Flow Data Table component supports rich text, it will render HTML in the same way that Display Text does. Better yet: it considers text formula fields as supporting rich text! This means we can add a formula field to an object that constructs HTML using SLDS styling, add that field as a column using Flow’s Data Table, and it will render each cell for that column as user-friendly, lightning styled goodness.

You could, for example, rework the above “Link as Button” formula into a Formula Field on an object, then display a button/link for each row in a Data Table:

'<a class="slds-button slds-button_brand" target="_top" href="' &
    LEFT( $Api.Partner_Server_URL_580 , FIND( '/services/' , $Api.Partner_Server_URL_580 )) & Id &
'">View Record</a>'

Winter 24: Display Text Reactivity (beta)

In the upcoming Winter 24 release, Display Text becomes one of the next Flow Screen components to achieve reactivity. Imagine all of the beautiful, reactive user interfaces that can be built by combining the lightning design system with the dynamism of reactivity! To give you a taste of the kind of power that reactive Display Text can bring to Screen Flows, I was able to make a (basic) game with just out of the box components:

Wrap It Up

The examples here are really just the tip of the iceberg in terms of what can be done with this technique, but I will leave you with a word of caution. I urge everyone using this technique to keep it light and simple. It may be tempting to try to use some of the more advanced design system blueprints, or attempt to gain very granular control over styling, but that comes at the cost of increased likelihood of messing it up, or increased maintenance overhead. Take the same approach you would take to building anything: consider balancing delivering for your users today with being able to deliver updates for them in the future.

Have fun spreading a serious user interface glow-up to your users, and be sure to share any cool things you’ve built or questions you have in the comments section below.

In the next few days I’ll add a link to a preconfigured Custom Label file and example Flow that you can use as reference, and later there will be a follow up post that dives further into using SLDS styling with Display Text reactivity in Winter 24!

Sneak Preview – Flow in Winter ’24

Here’s a preview of what’s coming to Flow in the next couple of months!

The Rollouts Begin: Panels

With this release, the conversion of property editors from modals to panels picks up momentum. The first panelized property editors showed up in Flow Orchestration, and more were seen in the Flow-based marketing features that started to roll out in Summer ’23 Starter edition. In Winter ’24 panels will show up in mainstream elements: Create Records, Wait, Start, Update Records elements at all times and Action & Subflow elements and Custom Property Editors when in edit mode.

Panelized property editors have a couple of useful benefits besides look more modern and feeling more fluid. They allow the user to see and manipulate the canvas while configuring the property editor and they are a key technology needed to enable Draft Mode (with modals, you can’t really leave things partially completed, which is the whole point of Draft mode).

The Rollouts Begin: Save as Draft

This feature lets you save flows that are missing required features. In Winter ’24, it’s only going to be present in Create Records and the Start element of flows with a Record-Change trigger.

Draft Mode is fundamentally intended as a usability feature to make Flow easier to work with. You don’t have to have all of your ducks in a row.

The Rollouts Begin: Fourth Generation Merge Field Picker

The team has been hard at work on an overhaul of the merge field picker. This component is a wolf in sheep’s clothing. It’s extremely complicated because of its need to not only support a wide range of data types but also dynamically show just the appropriate types in different contexts. The current merge field picker has served Flow well since its creation 5 years ago but there are a lot of overdue enhancements that required a full reworking.

In Winter ’24 you’ll encounter the new picker in just one place, the Create Records element. You’ll see some of the immediate enhancements, like the clickable breadcrumbs shown above. More enhancements are on the way along with a broader rollout. Developer Note: This component has been designed to be made available in the Public namespace for use in custom property editors, although the release date for that is TBD.

HTTP Callout is GA and supports the full range of HTTP methods.

Transform Data with the new Transform Element (Beta)

Transform is probably the most powerful, complex element we’ve yet created. It provides the ability to declaratively shape and mold data. It’s particularly well-paired with the HTTP Callout element because of its ability to extract useful data from the complex response structures returned from typical web calls.

The beta implementation includes. the ability to map collections from JSON structures to collection resources:

You can also apply a formula to data to shape it:

Your transformations are also supported in the debugger:

Note the following considerations on Winter ’24:

  • Source data doesn’t support global variables.
  • The Transform element is available for only autolaunched, screen, and triggered flows.
  • Packaging not supported yet
  • Primitive collection not supported yet
  • Collection Choice Set, Picklist Choice Set, and Record Choice Set are treated like strings
  • Support only 1 level of nested collection
  • Read only fields are hidden on the target side
  • No traversals for sobjects
  • Only 1 input source will show on UI
  • Manual output mapping not supported
  • No built-in aggregation yet (count, sum, exist, first, etc)
  • No collection transform yet (join, filter, sort, etc)
  • 10 nested levels max

Reactive Screens – GA with Formula support and Reactive Choice Selections

Reactive Screens is finally GA with this release. This feature fundamentally allows the creation of single-page applications and forms, reducing the amount of ‘Next’ clicking and enabling a more dynamic and satisfying visual experience.

This release brings several enhancements that flesh out the Reactive Screen toolset. Display Text is reactive (this component has been deemed Beta for Winter ’24. Note that that means you have to enable the ‘Opt in to Reactive Display Text Beta’ checkbox in Setup -> Process Automation Settings for this particular feature). That allows easy implementation of text that updates based on inputs:

The above example also leverages the new ability to use formulas reactively. That means that if you create a formula in a flow that references an input that changes, like the text fields in the example above, the formula will immediately recalculate, and anything else on the screen that makes use of that formula will update.

Choice Selections also react to changes on the screen. In this example, one set of choice settings change based on a value selected in another radio button group:

Select a Radio Button Based on Another Radio Button

Auto-select an Opportunity Stage from a Data Table

Here, you can see how it’s done, with a formula that is used to set the default value:

Formulas can mix values provided by the user with Custom Settings, Profile data and other Global Variables, as shown in this example:

Other improvements:

  • Screens will now apply reactive updates when a screen first loads.
  • Formula support has been extended to SUBSTITUTE, ^, ADDMONTHS, and ISPICKVAL.
  • Screen Readers will now announce reactive changes.

You can surface Custom Error Messages when a Record-Triggered Flow detects a problem with a user’s actions

Record-triggered Flows in many ways provide a great toolset for custom validation checking, but have always had an inability to surface an error right to where the user is taking action. You can now choose to either surface a custom, dynamic error message as an inline field error or as a pop-up window.

Two New Wait Elements Provide Extra Delay Control

Extended Support for Revisitation Controls

A pair of radio buttons was added a couple of years ago to enable builders to control the behavior of screen components when the user returns to a screen. This was necessary because there are a bunch of valid use cases where you want the component to recalculate with updated values and other equally valid use cases where you want the component to remember what the user last provided. These slides are from a 2021 RRL where we described the new control, which was then released for Lightning Components in screens.

In Winter ’24, support for Revisited policy has been extended to Choices, Text, Number, Currency, Long Text Area, Date, and DateTime components:

Values are now remembered when going back to a previous screen.

Reactive Steps Enhance Flow Orchestration

You can now trigger a step to start or end with an expression that will set up a record-change listener. That means that an active stage can have multiple steps all waiting for different data changes.

Additionally, Flow Orchestration Objects now support Custom Fields and lookups.

Trigger Flows when Data Cloud events are generated

New List View Column: API Version

You can choose to view the Api Version in the Flow list view in Setup.

ISV Spotlight: Pimly’s Product Cloud Solution Uses Flow

Editor’s Note: UnofficialSF is pleased to enable commercial creators of products that use Flow like Pimly to introduce their products and demonstrate useful use cases. One of our goals is to see a rich tier of commercial solutions in addition to the many free extensions that will continue to be available.

The Pimly CEO, long time Salesforce leader Mike Milburn, published a post describing how Pimly leverages flow:

Learn more about Pimly:

Text Area Plus Adds Text Input and Help Text

Version 1.8 for Text Area Plus adds help text and a new Text Input option for standard Text Input. I’ve also added a height option for the Rich Text and Text Area modes to allow you to set a specific height in pixels for the text input box for a better UI. For full details and the install link visit the main post here.

From Justin Condren: Use Flow with Salesforce ‘Pay Now’ to Collect Payments Anywhere on Salesforce

Salesforce has just launched Pay Now, a new product that embeds commerce everywhere. It’s a faster, simpler way to collect payments without the need for a full commerce storefront. 

Pay Now allows you to generate payment links in a snap, attach them to any Salesforce object, and send them off to your customers wherever they are. Voila, you’ve just created a revenue-generating transaction that can be dispatched across any channel.

Pay Now makes any object in Salesforce “payable”. Therefore, Pay Now is designed to be an embeddable building block for Salesforce Admins to embed into their workflows. 

Thanks to its embeddable nature, the sky’s the limit for potential use cases of Pay Now. Here are a few key use cases of Pay Now:

  • Collect payments for quotes to cash workflows (Invoices, Quotes, etc.).
  • Send payment links via your social channels like WhatsApp or Facebook Messenger.
  • Incorporate payments right into your Field Service Reports.
  • Push out payment links through those handy chatbots.
  • Encourage payments within your marketing email campaigns.

In this article, we’re going to zero in on the Quote to Cash example, showcasing just how powerful Pay Now can be when used with Flow. 

For those of you keen to see Pay Now in action within Salesforce Field Service, we’ve got you covered. Check out this video:

How Does Pay Now Work?

Pay Now comes with two building blocks out of the box. These building blocks are the defining factors of your Salesforce user and buyer experiences. 

  1. Payment Link Object

The Payment Link Object creates your Payment Links. You are able to specify the Amount, Currency Code, Payment Method Set (Credit Card, Apple Pay, etc.), Title and Description. 

Once you create a Payment Link record, it is available within the Payment Links list view. From here, the Payment Link record displays all relevant information regarding the Payment Link. 

  1. Pay Now Experience Cloud Template

Once the Payment Link Record is created, the buyer must access the page to complete their payment. 

Once the payment is completed, the buyer is directed to the Payment Confirmation page.

Use Case: Quote to Cash Workflow

Here’s a demo to show how Pay Now can be neatly embedded into Quote to Cash workflows. This will allow you to collect payments without straying from the Salesforce platform.


The Flow works by embedding the Screen Flow into a Quick Action on the Quote Record Page Layout. 

The first step of the Flow is to get the context of the Quote from which it is being called. This is done by using a “Get Records” in which the Quote Id is the Id of the Record from which the Screen Flow is triggered.

Next, we collect the necessary information from the user. We use some default values from the Quote object to save time here. 

Next, we use Get and Create Records actions to do the following tasks: Retrieve the Payment Method Set ID, Generate the Payment Link Record, and retrieve the URL from the newly created Payment Link.

Next, we display the Payment Link URL on the screen to the user, giving them the option to copy the URL to their clipboard using the UnofficialSF Copy to Clipboard extension. 

If the user decides to send an email containing the Payment Link, then we leverage the UnofficialSF Send Better Email action. After retrieving the Quote PDF associated with the Quote Record, we send an email to the Quote contact including the Payment Link with the Quote PDF attached.

How to Access Pay Now

If you have any questions or are interested in learning more about Pay Now, reach out to your Account Executive. 

ISV Spotlight: Avonni Flow Screen Components Provides More than 50 UI Components

Editor’s Note: UnofficialSF is pleased to enable commercial creators of Flow extensions like Centro to introduce their products and demonstrate useful use cases. One of our goals is to see a rich tier of commercial solutions in addition to the many free extensions that will continue to be available.

The Avonni Flow Screen Components library is a managed package that contains over 50+ customizable UI components to enhance Salesforce Flows. This library facilitates the creation of user-friendly interfaces, improving the user experience.

Flow Screen Components

The Avonni Flow Screen Components library offers various reactive UI components for Salesforce screens, catering to various needs like inputs, displays, indicators, pickers, and interactions for improved user experience. The components are designed to be “Reactive,” ensuring seamless interactions and real-time updates based on user input. 

Input Components for Easy Data Collection

  • Rating: Gather user feedback effortlessly with a star rating system.
  • Dual Listbox: Let users move options between two lists.
  • Color Picker: Enable intuitive color value selection for your users.

Presentation Components for Engaging Interfaces

  • Calendar: Boost data management with a visually organized component.
  • Tabs: Organize content effectively.
  • QR Code: Generate QR codes for easy scanning.

Special Input Components for Advanced Functionality

  • Barcode Scanner: Scan and easily process barcodes.
  • Slider: Allow users to adjust values using a draggable slider.
  • DateTime Picker: Combine date and time selection in one component.

Data Display Components for Effective Visualization

  • List: Display collections of items in a structured format.
  • Data Table: Enhance tabular data with sorting, filtering, and pagination.
  • Map: Showcase records on an interactive map for better context.

Progress Components for Visual Feedback

  • Progress Bar: Provide a visual indication of progress with percentage values.
  • Progress Indicator: Track task progress with clear step indicators.

Visual Picker Components for Engaging Selection

  • Visual Picker: Offer users visually appealing selection tools for multiple options.

Content Components to Enrich Your Flows

  • Carousel: Rotate images to highlight important information.
  • Illustration: Include eye-catching illustrations.
  • Buttons: Add clickable buttons for seamless interactions.

Interaction Components to Enhance User Experience

  • Flow Navigation: Control the flow of navigation in your app.
  • Show Toast: Display toast notifications for real-time user feedback.
  • Navigate: Direct users to specific locations within your app.

This is just a glimpse of the components within the Avonni Flow Screen Components library. To view the complete list of components available in the Avonni Flow Screen Components library, visit

Custom Property Editor

The Avonni Flow Screen Components library has a built-in Custom Property Editor that seamlessly integrates with the Flow Builder. This editor makes it easy to customize and configure your components in various ways:

  1. Drag-and-drop functionality: Effortlessly rearrange fields within a component by dragging and dropping them.
  2. Dynamic customization: Adjust component settings to fit your specific requirements.
  3. Live preview: See changes to the component in real time.
  4. Interaction configuration: Personalize the user experience by adding custom interactions.
  5. Style Editor: Fine-tune the component’s look to match your brand or design preferences.

The Custom Property Editor streamlines adapting Avonni Components to meet your unique needs.

Use Case example: Create an accounts management component with Flow Builder

Let’s dive into a practical use case where we create a comprehensive account management component. This detailed guide will lead you through designing an account management component.

Install the managed package to begin using the Avonni Flow Screen Components library. It’s free to use within a sandbox environment, and for production organizations, you can utilize it for up to 10 users at no cost. This allows you to create and test Avonni  components within Salesforce Flows without any initial investment.

The accounts management component lets users:

  • View and manage accounts in a single location
  • Quickly search, filter, and sort accounts using the Avonni Data Table
  • Review onboarding process stages for selected accounts using the Avonni Path
  • Access and edit account-specific information, such as contact details, billing information, and notes, using the Avonni Tabs component
  • Visualize the geographical location of an account using the Avonni Map component.

Account Management component built with Flow Builder

We’re using the following Avonni Components to create this specific use case: 

  • Avonni Header: Provides a customizable header section
  • Avonni Data Table: Displays a list of accounts, allowing users to select an account and view various associated information.
  • Avonni Path: Showcase the onboarding process stage upon account selection.
  • Avonni Tabs: Organizes additional account information into accessible sections.
  • Avonni Map: Provides a visual representation of the location for the selected account.

The main steps to build this component are:

Define a header using the Avonni Header Component

Think about adding the Avonni Header at the top of your screen flow. This will give all the following components a uniform look and feel and improve the overall design and harmony of the Account Management component. It’s a small change that can make a big difference in your layout.

Screen flow settings

  • Add a screen element and name it: Main Screen
  • Hide the Header and Footer Section

Avonni Header configuration

  • Drag the Avonni Header Components
  • Configure the Avonni Header properties
    • Open the Component Builder
    • In the Title field, enter: “Accounts Management”
    • Check the toggles “Is Joined” and “Pull to Boundary” – to make this component more consistent with the subsequent component. 
    • Expand the Avatar Section to set the Account icon as an avatar next to the title.
    • Expand the Actions Section to create a “New” button action to let end-users create a new account on the fly.

Avonni Header Styling Configuration

  • Set the Header background color to white

Avonni Header interaction configuration

Now, let’s configure an interaction for the ‘New’ button present on our Avonni Header Component. Clicking this button will allow users to create a new account. Here’s how we proceed:

  • Add a “New” action button
  • Click on the interaction tab to create an Action click interaction:
    • Target Name: New
    • Type: Navigate
    • Page reference type: Object Page
    • Object API Name: Account
    • Action name: New

Adding the Section component

Adding a ‘ Section ‘ element is important before incorporating the Avonni Data Table component into our screen flow. This element is crucial because it allows us to create two distinct sections within our screen element. These separate sections allow us to easily organize and drag the desired components into their respective places. This ensures a well-structured and logical layout, paving the way for a smooth integration of the Avonni Data Table component.

Utilize the Avonni Data Table to display a list of records

Here we will configure the Avonni Data Table for our Accounts management use case. We’ll customize row selections, data source connections, column layouts, and actions and define specific interactions. Additionally, we will set filters and designate searchable fields to optimize the user experience. Let’s dive into these steps to create a robust, user-friendly table.

Configuration steps

  • Set the settings “Maximum row selection value” to 1 to permit a maximum row selection of just one. This way, users can concentrate on one account at a time.

Data Source configuration steps

Let’s set up the Data Source on the Avonni Data Table. We’ll link the source to our ‘Get Records’ collection, customize the table layout by adding columns, and add ‘Row Actions’ for user interactivity. Let’s get started.

  • In the Data Source section: Link the data source to the previously created ‘Get Records’ collection that fetches account records information.
  • Adding columns by dragging and dropping fields from the collection allows a customized data table layout.
  • Adding a Row Actions column: Edit, Change Account Owner. 

Create the interactions on Row actions

Let’s delve into setup the interactions on row actions. We’ll establish an interaction for the “Change Account Owner” action, triggering another flow for effortless account owner changes. You’ll also learn to pass the Record ID input variable to access the corresponding record in the new flow.

Configuration steps

  • Create an interaction on the Change Account Owner action to open another flow allowing users to change the account owner
    • Pass the Record ID input variable to open the other flow to the corresponding record.
  • Set filters: Set the Account Type and Industry fields as filterable.
  • Searchable Field: Set the account name field as searchable.

Display the selected account name using the Avonni Header

Now, we’ll integrate another Avonni Header component at the top of the right section of our screen flow. This will act as a gateway to manage account-specific information, operating with the Avonni Data Table. Upon account selection, the Header will dynamically display the account name. Let’s configure it.

Configuration steps

  • Drag the Avonni Header component on the right section
  • Open the Component Builder
  • Map the Title to the Avonni Data Table component to display the account name value of the first selected row:
    Title > Mapped > Avonni Data Table > First Selected Row > Account Name

Showcase the account’s status using the Avonni Progress Indicator.

We’ll incorporate the Avonni Progress Indicator, a key component to present the account’s status visually. This component represents progress, giving users clear insights about the account’s status.

Configuration steps

  • Drag the Avonni Progress Indicator component under the Avonni Header added on the right section
  • Open the Component Builder
  • Select the Progress indicator type to Path
  • Map the Current Steps value to the Avonni Data Table component to display the Onboarding Progress value of the first selected:
    Current Step > Mapped > Progress > First Selected Row > Onboarding Process
  • Manually input the values for the Path Progress Indicator, ensuring they match those from your corresponding Salesforce field.

Organizing account information with the Avonni Tabs

Moving forward, the next component we’ll introduce is Avonni Tabs. This component helps organize various account information into separate, manageable tabs. By implementing Avonni Tabs, we’ll enhance user navigation, making finding and updating specific account details easier.

Configuration steps

  • Drag the Avonni Tabs Component
  • Open the Component Builder
  • For each tab, assign a manual label by entering a descriptive name in the “Label” field. This label will be displayed on the tab when users interact with your flow.

Use the Avonni Formatted Value to display a field information

As we continue to enhance our account management component, the next component we use is the Avonni Formatted Value. This component is designed to provide a visually appealing display of field information. In this use case, using the Avonni Formatted Value will make the field presentation more user-friendly and intuitive. 

Configuration steps

  • Drag the Avonni Formatted Value Component
  • Open the Component Builder
  • Map the Formatted Value to the Avonni Data Table component to display the account type value of the first selected row.
    Value > Mapped > Formatted Value > First Selected Row > Account Type

Visibility Configurations: Your Key to a Dynamic Screen Flow

  • Remember to configure component visibility settings for each component in your screen flow to ensure they are displayed based on specific criteria. For example, set the component visibility of the Avonni Header to only show when the first selected row key value in the Avonni Data Table is not false. Effectively handling component visibility will lead to achieving the final result. 

Upcoming Developments: Our Objectives and Request for Ideas

Our goal with the Avonni Flow Screen Components library is to improve the Salesforce end-user experience through a no-code approach, offering a broad selection of fully customizable UI components that can be tailored to specific needs.

Our Vision:

  1. Enhance the Salesforce end-user experience with no-code solutions
  2. Supply a wide array of customizable UI components for Salesforce Admins
  3. Leverage Flow Builder for seamless user experience and no-code custom business processes

We value your suggestions and ideas as we work towards these goals. 

Final Thought 

The Avonni Flow Screen Components library enhances the Salesforce end-user experience by offering a comprehensive range of customizable UI components. These components are integrated into Flow Builder, enabling you to create more user-friendly interfaces and custom business processes without coding. 

To elevate your Salesforce Flows, we encourage you to install the Avonni Flow Screen Components library from the AppExchange today. Remember, it’s free for up to 10 users in a production organization. Start exploring the potential of the Avonni Flow Screen Components library and transform your Salesforce experience!

Replacing Programmatic Tech Debt with Flow

How Playworks used Flow to replace multiple Visualforce pages and 1000s of lines of Apex code

The use case comes from a pro bono project for Playworks. Playworks is the leading national nonprofit leveraging the power of play to transform children’s social and emotional health. They’re a great organization, and I encourage you to learn more about what they do and consider supporting their work.

The Old Architecture

Playworks has a custom object called NCES Data, which contains information about 115,000 schools and 15,000 districts in the United States. The data is released by the National Center for Education Statistics each year, which the Playworks team then loads into their Salesforce org.

As Playworks establishes their presence at a new school, reps use a wizard to create an account for the school, along with a child record that stores the school’s current demographic information. The demographic information is important for various grants and funding. Districts are also represented with account records. School accounts, district accounts, and their respective demographic information records are created from data residing in the NCES Data object.

Reps interact with a Visualforce page embedded in a custom tab called Create New School, or they click an Add School button on the partner organization related list. Partner Organization is a junction object that allows Playworks to attach multiple account records to opportunities, where appropriate. A separate Visualforce page with its own controller is launched from the Add School button. When this occurs, a partner organization record is created in addition to the school or district account record. 

The rest of the logic remains the same. The search functionality is handled by Apex classes, and an Apex trigger creates the demographic information. Whether invoked by the Create New School tab or the Add New School button, each Visualforce page finishes with a redirect handled by a third Visualforce page with its own controller.

That’s a lot of custom dev work, and a lot of tech debt.

  • 9 Apex classes
  • 8 Apex test classes
  • 3 Visualforce pages
  • 1 Apex trigger

The good news is the code was written by highly competent developers, and has held up for nearly a decade. The bad news is that even a minor update requires the code to be modified.

The New Architecture

Speaking in terms of business logic, there are 5 possible outcomes when a user searches the NCES Data for a school or district. 

  1. NCES record is a school or district that already has an account record.
  2. NCES record is a district that does not have an account record.
  3. NCES record is a school that not have an existing account record. The school has an NCES record for the district, but there is no account record for the district.
  4. NCES record is a school that not have an existing account record. There is no NCES record for the district. (This can happen with some private schools.)
  5. NCES record is a school that not have an existing account record. There is an account record for the district.

Each of these outcomes has slightly different requirements, depending on if it was invoked by the Add New School button or the Create New School tab.

Regardless of the eventual path for each of the 5 possible outcomes, all flows begin the same way.

First, since there are multiple account record types, the school record type is retrieved. Next, a flow screen gathers the necessary information to perform the search.

After failed attempts to recreate the Apex search functionality using a Get Records element with filter logic, a decision is made to go with code. A small portion of the existing code base is refactored into an invocable method. The method accepts the search parameters from the previous screen, and returns a list of NCES records.

public class CreateNewSchoolOrDistrictSearch {
    private static String maxresults = '25';
    @InvocableMethod(label='Search for NCES Data')
    public static List<Results> searchForNCESData(List<Requests> requests){
        Requests request = Requests[0];
        String queryString = generateNCESDataQuery(request.schoolNCESId, request.schoolName, request.schoolCity, request.schoolState, request.schoolZip);
        Results result = new Results();
        result.ncesRecords = Database.query(queryString);
        System.debug('NCES Records: ' + result.ncesRecords);
        List<Results> results = new List<Results>();

        return results;
    public static String generateNCESDataQuery(String schoolNCESId, String schoolName, String schoolCity, String schoolState, String schoolZip){
        return generateNCESDataQuery(schoolNCESId, schoolName, schoolCity, schoolState, schoolZip, false, false);
    public static String generateNCESDataQuery(String schoolNCESId, String schoolName, String schoolCity, String schoolState, String schoolZip, Boolean exactIdMatch, Boolean isDistrict){
        String ncesDataQuery = 'SELECT Id, Existing_Organization_in_Salesforce__c, School_Level__c, NCES_Id__c, School_Name__c, School_Mailing_Street__c, School_Mailing_City__c, School_Mailing_State__c, School_Mailing_Zip__c, School_Physical_Street__c, School_Physical_City__c, School_Physical_State__c, School_Physical_Zip__c, NCES_District_ID__c, District_Name__c, District_Mailing_Street__c, District_Mailing_City__c, District_Mailing_State__c, District_Mailing_Zip__c FROM NCES_Data__c '; 
            ncesDataQuery += ' WHERE NCES_ID__c != NULL AND NCES_ID__c != \'0\' '; 
            ncesDataQuery += ' WHERE NCES_ID__c = NULL AND NCES_District_ID__c != NULL AND NCES_District_ID__c != \'0\' ';             
                    ncesDataQuery += ' AND (NCES_ID__c = \'' + schoolNCESId + '\') ';                
                    ncesDataQuery += ' AND (NCES_ID__c = \'' + schoolNCESId + '\' OR NCES_ID__c LIKE \'%' + schoolNCESId + '%\') ';
                    ncesDataQuery += ' AND (NCES_District_ID__c = \'' + schoolNCESId + '\') ';                
                    ncesDataQuery += ' AND (NCES_District_ID__c = \'' + schoolNCESId + '\' OR NCES_District_ID__c LIKE \'%' + schoolNCESId + '%\') ';
        } else {
                ncesDataQuery += ' AND (School_Name__c LIKE \'%' + encodeForQuery(schoolName) + '%\')';                
                ncesDataQuery += ' AND (School_Mailing_City__c LIKE \'%' + encodeForQuery(schoolCity) + '%\')'; 
                ncesDataQuery += ' AND (School_Mailing_State__c LIKE \'%' + encodeForQuery(schoolState) + '%\')'; 
                ncesDataQuery += ' AND (School_Mailing_Zip__c LIKE \'%' + encodeForQuery(schoolZip) + '%\')'; 
        ncesDataQuery += ' ORDER BY Name LIMIT ' + maxresults;
        return ncesDataQuery;           
    private static String encodeForQuery (String inputVal) {
        return String.escapeSingleQuotes(inputVal.trim());
    public class Requests{
        @invocableVariable(label='NCES Id')
        public String schoolNCESId;
        @invocableVariable(label='School Name')
        public String schoolName;
        @invocableVariable(label='School City')
        public String schoolCity;
        @invocableVariable(label = 'School State')
        public String schoolState;
        @invocableVariable(label='School Zip Code')
        public String schoolZip;
    public class Results{
        @invocableVariable(label = 'NCES Records')
        public List<NCES_Data__c> ncesRecords;

Next, the search results are displayed in a table, and a school or district is selected. Remember the results are a list of NCES data records returned by the invocable Apex. The selected NCES data record is used to create the necessary school account, district account, and corresponding demographic information record. If the school account or district account record already exists, the user is redirected.

Recall the 5 possibilities. 

  1. NCES record is a school or district that already has an account record.
  2. NCES record is a district that does not have an account record.
  3. NCES record is a school that not have an existing account record. The school has an NCES record for the district, but there is no account record for the district.
  4. NCES record is a school that not have an existing account record. There is no NCES record for the district. (This can happen with some private schools.)
  5. NCES record is a school that not have an existing account record. There is an account record for the district.

Each one of these is represented by a path in the flow. For example, if a school or district already exists as an account record, the user is redirected to that record. Before that happens, if the flow is launched from the Add School button, a partner organization is created. If the flow is launched from the Create New School tab, then it simply redirects to the school or district.

Each of the 5 possibilities is accounted for, in different branches of the flow. The programmatic complexity of the Visualforce and Apex are replaced by the flow. While complicated in its own right, the solution is now declarative.


While we fell short of a completely declarative solution, the logic of the search functionality is unlikely to change. By refactoring the Visualforce pages and 95% of the Apex logic into flow, the Playworks team can safely make changes in the future, without having to hire a developer.

From Teo Popa: Powerful Enhancements to the Decision Tree Sample App

from Alex: In internal conversations and conversations with customers, one of the posts I find myself sharing the most is the ‘Thousands of Screens’ post on how flow can drive record-based decision trees that are easy to edit and manage. Teo has extended the design with some clever enhancements and shares them here.

A Practical Application of the “Thousands of Screens” Flow Pattern with Enhancements for Supporting Multiple Troubleshooter Tools-in-One, Pathway Continuation without Selection, and Exit and Return-to-Start Functionality

The “Thousands of Screens” flow pattern (aka: the “Troubleshooter” pattern) is useful for providing a way for end-users to do more than just search a knowledge base for solutions based on keyword matches. It enables end-user guidance and can be applied to a multitude of contexts (i.e. service, sales, etc.).

Think of the “guessing game”, wherein one person thinks of a person, place, or thing in their mind, and another person asks them a series of elimination questions until they can deduce exactly what the first person is thinking. With every response, the person asking the questions is able to collect more information from the person with the solution and apply that information to adjust the questions they ask.Throughout the process, they inevitably work their way closer to the solution.The provision of a pathway to enable “guessing” in this game is the critical component to obtaining the solution. Without it, arriving at a solution is infinitely more difficult, if not–impossible. This pathway provision is what the “thousands of screens” flow pattern brings to Salesforce.

By providing the “thousands of screens” pattern through flow you’re able to utilize the native functionality of the Salesforce platform to provide a “skeleton” for building out “troubleshooting” pathways, while empowering your end-users to manage the actual building, configuration, and content management of these pathways themselves.

The example below provides a sample application of the “thousand of screens” flow pattern as applied to an organization that currently uses multiple service agent “troubleshooting” tools scattered throughout several powerpoint files housed on a common server. Pain points in this use case include:

  1. The troubleshooter files are cumbersome for service agents to locate and access daily from the server.
  2. When all opened and kept ready for immediate service agent use, the troubleshooter files take up valuable screen real estate from other applications.
  3. When all opened and minimized, the troubleshooter files cause confusion and waste service agent time when they are trying to locate the applicable file to maximize and use.
  4. The troubleshooter file contents have grown to hundreds of slides and are difficult for service managers to modify contents/pathways/configuration as information changes are needed over time.
  5. The troubleshooter file sizes continue to grow and impact each file performance.
  6. The troubleshooter file search functionality and pathway visualization is limited.

Supporting Multi-Troubleshooter-Tools-in-One

To begin utilizing the “thousands of screens” flow pattern to replace multiple existing powerpoint-based troubleshooter tools with a single Salesforce-based troubleshooter tool, we can combine the contents of the multiple powerpoint tools into a single troubleshooter tool in which the first question of the tool is, essentially, ”Which tool do you need?” (see Image 1). From this single flow screen, we can now support launching into multiple tool pathways. Additionally, we can use native Salesforce functionality to embed the single troubleshooter flow into the utility bar of the service console for easy, recurring access by service agents and pop-out ability.

These two actions combined 1) eliminate the need for multiple powerpoint files, 2) reduce the amount of screen real-estate dedicated to tools so that the agent can focus on case documentation, and 3) reduce the amount of minimized windows to comb through when searching for a tool.

Image 1: Multi-Pathway Utility Bar Troubleshooter Tool Using “Thousands of Screens” Flow Pattern

Using DiagnosticNode (the front-end accessible record representation of a flow screen’s contents and configuration) and DiagnosticOutcome records (the front-end accessible record representation of a flow screen’s picklist selection values) within Salesforce, we can create a series of pathways for each tool, which in turn, can contain a series of branching pathways based on outcomes themselves, and so on–all stemming from a single starting screen. Additionally, we can establish record naming conventions and ordering mechanisms that help us leverage native Salesforce search functionality and listviews to find, manage, modify, and visualize our troubleshooter tool pathways and content (see Image 2).

Image 2: Naming Convention and Ordering Examples for a Multi-Pathway Troubleshooter Tool

Pathway Continuation without Selection

The original “thousands-of-screens” flow pattern provided through, assumed the end user would select a response from the picklist values provided on every screen the agent passed through. However, in practice, instances do arise where end users need to be provided with information (i.e. an instructive statement) without necessarily being asked a question that warrants making a selection in order to move forward (see Image 3).

Image 3: Example of Necessary Pathway Continuation without Selection

To achieve this configuration for a particular DiagnosticNode screen, we can utilize the:

  • “Continuation Node” checkbox, and;
  • “ContinuationDiagnosticNode” lookup field.

Together, these identify 1) a DiagnosticNode record as a screen in a pathway that does not require a selection from the end user in order to move forward, and 2) which screen should be displayed next upon clicking the “Next” button (see Image 4).

Image 4: Marking a Diagnostic Node (Flow Screen) for Selection Exemption and Continuation

Exit and Return-to-Start-Screen Functionality

We can add more robust functionality to our multi-tool “troubleshooter” tool by recognizing when a tool pathway ends and handling these “endings” in an end-user-friendly manner. Essentially, once a pathway ending is reached 1) the end-user should be notified that no more action is required of them regarding the issue they are troubleshooting, and 2) the multi-tool “troubleshooter” tool should reset so that it is ready for our end users to troubleshoot the wide variety of issues that could occur with the next case (see Image 5).

Image 5: Example of a Pathway Ending

To solve for both of these desired outcomes when a pathway ending is reached, we can use the “End Node” checkbox to identify a DiagnosticNode that marks the end of a pathway (see Image 6). When the end-user encounters the flow screen represented by this End Node DiagnosticNode record, upon clicking “Next” on this screen, they will be routed to the flow “Finish” screen, instead of another DiagnosticNode record. From this standard flow “Finish” screen, they can click “Finish” to reset the tool back to the initial start screen.

Image 6: Marking a Diagnostic Node (Flow Screen) for Pathway Ending


There isn’t a straightforward installation package, but sample code is available in the repo here.