Formatting with rich text

Intermediate

Wow, what a beautifully constructed message! Wouldn’t it be great to create a bot to keep your new hires informed of what they should be doing in their first days with the company, in a clear, organized message sent directly to them? Yes, the answer is yes, it would be great.

In this tutorial, we’ll walk through how to structure the Block Kit blocks to achieve this message, while explaining the ins and outs of rich text. To learn how to incorporate these blocks in messages and modals, read up on Building with Block Kit.

Rich text example

If you’d like to follow along with the code already constructed, you can check it out here in Block Kit Builder.

Step 1Mapping an outline

Building with Block Kit is layering one block on after another, all independent pieces with their own details within their structure. The main blocks of this message are:

Block Type Description of block in image
header Onboarding Week 1
context Line of text in smaller, lighter font providing context for the message
section Text and accessory image
divider Horizontal line
rich_text Company business header, bulleted and ordered lists
divider Horizontal line
rich_text Read about our culture header and bullet list
divider Horizontal line
rich_text Inspirational quote of the day section
input Component for text data collection
actions Button

Now let's step through these individually.

Step 2Introducing the content

To give the user context of the overall content of the message, we provide a header, a context sentence, and an introductory blurb.

Header block

The header block is straightforward. The only option for the text object's type field is plain_text, so if you wanted to add emoji here, it would need to be in a separate component. We'll explore adding emoji later.

Header code
{
    "type": "header",
    "text": {
        "type": "plain_text",
        "text": "Onboarding Week 1"
    }
},

View this block

Context block

The context block is a bit of text that gives the user context for the rest of the message. It is shown in smaller text that is grey instead of black. A context block's elements property is an array of objects, either image or text. Here we are using text. It's important to know that text in a context block cannot be rich text, only mrkdwn or plain_text.

Context code
{
    "type": "context",
    "elements": [
        {
            "type": "mrkdwn",
            "text": "Hello there! This is a weekly reminder of what you should be doing during onboarding."
        }
    ]
},

View this block

Introductory section block

The section block provides an introductory blurb with a fun gif welcoming the user to the team. While we strongly encourage rich text to markdown formatting, we've used a section block here (which offers only markdown formatting, not rich text) for use the of the accessory image. The same content could be achieved by creating a rich_text block followed by an image block, but they would be stacked, as opposed to side by side as shown in this example. Also note that we use a link to a gif, and while it is not animated in this screenshot, it will be in a message (and even in the Block Kit Builder preview). After this section, we'll use rich text for formatting text.

Intro section code
{
    "type": "section",
    "text": {
        "type": "mrkdwn",
        "text": "*Welcome aboard!*\n :eye: :lips: :eye:\n\nHere are some things you should do in week 1.\n Of course, reach out to your manager with any questions."
    },
    "accessory": {
        "type": "image",
        "image_url": "https://media.giphy.com/media/Ae7SI3LoPYj8Q/giphy.gif",
        "alt_text": "One of us"
    }
}

View this block

Divider block

The divider block is simply a horizontal line to provide a visual break in content.

Divider block code
{
    "type": "divider"
},

View this block

Step 3The main content

The main content of this message is comprised of a few visual sections: "Company business", "Read about our culture", and "Inspirational quote of the day".

Company business

The entirety of the "Company business" section of this message is contained within a single rich_text block. The flexibility of formatting is possible through many element types we'll dive into deeper here.

Rich text section

Within the top-level rich_text block, we have a rich_text_section, a rich_text_list, and another rich_text_list. Think of each rich_text_section as a single line of text. This may be deceiving, given that it holds an array of elements. However, structuring it as an array of elements provides maximum flexibility with styling each element (which can be as tiny as a single character), as well as ease in parsing. For instance, looking at the rich_text_section, we see two elements: an emoji and a text element. While these are different elements in the array, they appear on the same line.

The rich_text_section block allows for elements of the following types, providing many possibilities for styling: text, link, emoji, user, user_group, and channel.

Our text object has a style field, in which we specify bold. Other style options include italic, strike, and code. You apply them in the same manner as bold is shown here.

Rich text list

Moving on to the lists, you'll see in the code that we have two lists. One is the bulleted list, containing the first three bullets, and the second is an ordered list containing the last two elements. Notice how the rich_text_list is comprised of another elements array. This again allows for flexibility in the types of text you want to show, whether that be links, quotes, code snippets, or simply formatted text. To achieve the style of linking one word in a line of plain text, we use a rich_text_section, remembering that each rich_text_section is read as a single line of text.

To achieve the nested list that is part of the third bullet point, we simply create another rich_text_list below the prior one and set the indent property to 1. To indent a list further, you keep increasing the number by one to create deeply nested lists.

This section ends with another divider block.

Company business code
{
    "type": "rich_text",
    "elements": [
        {
            "type": "rich_text_section",
            "elements": [
                {
                    "type": "emoji",
                    "name": "office"
                },
                {
                    "type": "text",
                    "text": " Company business",
                    "style": {
                        "bold": true
                    }
                }
            ]
        },
        {
            "type": "rich_text_list",
            "style": "bullet",
            "elements": [
                {
                    "type": "rich_text_section",
                    "elements": [
                        {
                            "type": "text",
                            "text": "Fill out your W-2"
                        }
                    ]
                },
                {
                    "type": "rich_text_section",
                    "elements": [
                        {
                            "type": "text",
                            "text": "Enroll in "
                        },
                        {
                            "type": "link",
                            "text": "benefits",
                            "url": "https://salesforcebenefits.com"
                        }
                    ]
                },
                {
                    "type": "rich_text_section",
                    "elements": [
                        {
                            "type": "text",
                            "text": "Fill out your Slack profile, including:"
                        }
                    ]
                }
            ]
        },
        {
            "type": "rich_text_list",
            "style": "ordered",
            "indent": 1,
            "elements": [
                {
                    "type": "rich_text_section",
                    "elements": [
                        {
                            "type": "text",
                            "text": "Time zone"
                        }
                    ]
                },
                {
                    "type": "rich_text_section",
                    "elements": [
                        {
                            "type": "text",
                            "text": "Pronouns"
                        }
                    ]
                }
            ]
        }
    ]
},

View this block

Read about our culture

The entirety of the "Read about our culture" section is also contained within a single rich_text block. Let's look at how to format links in a list like the ones shown in this example.

Again within this block we see it is constructed using a rich_text_section and a rich_text_list. Unlike the prior section, we have decided to link the entire text line of the bullet, which can be done using the text property of the link element, instead of breaking it into multiple link and text elements.

This section ends with another divider block.

Read about our culture code
{
    "type": "rich_text",
    "elements": [
        {
            "type": "rich_text_section",
            "elements": [
                {
                    "type": "emoji",
                    "name": "green_book"
                },
                {
                    "type": "text",
                    "text": " Read about our culture",
                    "style": {
                        "bold": true
                    }
                }
            ]
        },
        {
            "type": "rich_text_list",
            "style": "bullet",
            "elements": [
                {
                    "type": "rich_text_section",
                    "elements": [
                        {
                            "type": "link",
                            "text": "Four tips for building a digital first culture",
                            "url": "https://slack.com/blog/collaboration/four-tips-build-digital-first-culture"
                        }
                    ]
                },
                {
                    "type": "rich_text_section",
                    "elements": [
                        {
                            "type": "link",
                            "text": "6 simple ways to foster a positive hybrid work environment",
                            "url": "https://slack.com/blog/collaboration/ways-foster-positive-work-environment"
                        }
                    ]
                }
            ]
        }
    ]
},

View this block

Inspirational quote

While the header and emoji of the last section of content also use the rich_text block, the following rich text element is different: the rich_text_quote. Using this element creates the vertical bar to the left of the text that indicates it is a quote, similar to how it is shown in messages in the Slack client or app.

The next piece is an input block, which allows collection of data, in this case, a quote, from the user that can be stored and recalled again at a later date.

The final block is the actions block, which is the call to action after the user submits their favorite quote — they push the button, letting the app know the action has been completed and the data is submitted. Read more about button function on the Block elements & interactive components reference page. We've added a block_id for both the input and actions block in order to reference them later. When a block_id is not explicitly added for a block, one will be automatically generated.

Inspirational quote code
{
    "type": "rich_text",
    "elements": [
        {
            "type": "rich_text_section",
            "elements": [
                {
                    "type": "emoji",
                    "name": "speech_balloon"
                },
                {
                    "type": "text",
                    "text": " Inspirational quote of the day",
                    "style": {
                        "bold": true
                    }
                }
            ]
        },
        {
            "type": "rich_text_quote",
            "elements": [
                {
                    "type": "text",
                    "text": "Having no destination I am never lost. - Ikkyū."
                }
            ]
        }
    ]
},
{
    "type": "input",
    "block_id": "quote_input_block",
    "element": {
        "type": "plain_text_input"
    },
    "label": {
        "type": "plain_text",
        "text": ":envelope: Enter your favorite quote, to be shared with future hires like you:",
        "emoji": true
    }
},
{
    "type": "actions",
    "block_id": "submit_button_action_block",
    "elements": [
        {
            "type": "button",
            "text": {
                "type": "plain_text",
                "text": "Submit"
                },
            "value": "submit",
            "action_id": "button_1"
        }
    ]
}

View this block

Step 4Summary

This concludes our guide on how to construct a beautiful message with Block Kit! We hope you will continue to explore all that blocks have to offer in Block Kit Builder and by reviewing the material below.

Further reading

Check out these articles to expand your knowledge and skills of Block Kit:

➡️ Building with Block Kit

➡️ Designing with Block Kit

➡️ Block Kit reference

Slack developer tools helper

Another tool to help you in your rich text journey is the Slack Developer Tools Inspect tool. Once installed, you can click the kebab (or three dots) menu on the upper-right of any message in Slack, then click "more message shortcuts." Search for the Inspect tool and click on it. This tool shows you the json behind any given message in Slack, which helps you understand how blocks are used to construct them. Magic. ✨