Display Text on the Screen

Almost all skills that use Alexa Presentation Language display basic text. This document shows how to place simple text content on the viewport.

Display a short headline with a background

The easiest way to put short text on the screen with a background is to use the Alexa headline (AlexaHeadline) responsive template. You provide the text to display, the optional background you want to use (such as a color, image, or video), and the optional header or footer text. The template handles displaying all of this on the viewport and automatically adjusts the layout to accommodate viewports of different sizes. The template automatically fills the entire viewport.

Alexa headline lets you specify primaryText and secondaryText text. The primary text is displayed in a larger font in the center of the screen and truncates after two lines. The secondary text is smaller and limited to a single line.

Use this template when you have a very short amount of text to display. See Headline for design guidance.

To use Alexa headline to place simple text with a background

  1. Add the current version of alexa-layouts to the import array in your document:
     {
       "import": [
         {
           "name": "alexa-layouts",
           "version": "1.2.0"
         }
       ]
     }
    
  2. Add the AlexaHeadline component to the items array for mainTemplate. At a minimum, set the primaryText to the text you want to show:

     {
       "type": "AlexaHeadline",
       "primaryText": "Headline text to display",
       "secondaryText": "Optional secondary text." 
     }
    

    See AlexaHeadline for the full set of parameters.

This example displays the text over a background, with header attribution image in the upper-right and a hint on the bottom. This example uses data-binding expressions for the text properties, using the data source headlineExampleData provided after the example.

Display simple text with the Alexa headline template
Display simple text with the Alexa headline template

In the "daily cheese" example, the footer of the template uses the textToHint transformer to properly format the text "What is today's cheesy joke?" as a hint. The transformer adds the wake word configured on the user's device (such as "Alexa", "Echo", etc.), places the text within the quotation marks, and adds the "Try" at the beginning.

For details, see Use the device wake word in your hints in Combine Content with Backgrounds, Borders, and Headers.

Build your own design with the Text component

To display text, place the Text component in your document and set its text property to the content to display. Use a data source and data-binding to set the text property.

This example displays "Hello World!" on the screen:

Copied to clipboard.

{
  "type": "APL",
  "version": "1.4",
  "mainTemplate": {
    "parameters": [
      "helloworldData"
    ],
    "items": [
      {
        "type": "Text",
        "text": "${helloworldData.helloText}"
      }
    ]
  }
}

The example gets the content for the Text component from a data source called helloworldData.

Copied to clipboard.

{
  "helloworldData": {
    "helloText": "Hello, World!"
  }
}
<code>Text</code> component with no properties for positioning
Text component with no properties for positioning

The previous example displays "Hello, World!" in the upper-left corner of the viewport with a default font style and size. Since you would normally want to control the placement and look of the content, APL offers different ways to position and format the Text component on the viewport:

  • Place the component within a Container. A Container can display multiple child components (unlike mainTemplate, which displays a single component) and provides several options for how its child components should be laid out.
  • Set the size of the invisible bounding box that contains the text to constrain the text and use the Text component's alignment properties (textAlign and textAlignVertical) to position the text within the box.
  • Use the padding properties (paddingTop, paddingLeft, and so on) to add margins and spacing around the component. Every APL component has these properties, so you can set them on the Text component itself or on its parent component, depending on the needs of your layout.
  • Use text styles, typography properties, and markup to format the text.

Format the text

The Text component has several properties that control the appearance of the text, such as fontSize, fontStyle, fontFamily, and letterSpacing. See the Text component properties for details about these properties. The Alexa styles package contains resources and text styles you can use to set these values for a consistent look.

You can also use some basic markup tags within the text for inline formatting.

Understand the bounding box for the Text component

A Text component has an invisible bounding box that constrains the text inside. You can set the height and width of this box with the corresponding properties on the Text component itself.

When the height and width properties on a Text component are not specified, they default to auto. This means that the bounding box is sized to fit the content, within the constraints of the component's parent.

For example, suppose you have a Container with height/width set to 100vh/100vw, so the Container fills the entire viewport. The following table summarizes how the bounding box for a Text component works when you place it inside this Container and set the height and width properties of the Text component in different ways.

Text component height and width settings Bounding box behavior

height and width not set (auto)

Bounding box takes up as much space within the Container as it needs for the content. Therefore the bounding box is the width and height of the text, within the constraints of the Container. See Example: Text component with auto-size.

height and/or width set to a relative dimension

Bounding box is sized relative to the size of the parent Container. For example, a Text component with width set to 50% has a bounding box 50% of the Container size. See Example: Text component with relative height and width.

height and/or width set to an absolute dimension

Bounding box has the specified absolute size, but still constrained by the size of the parent Container and is therefore truncated if it is larger than the parent Container. For example, if the Container has a width of "50vw" (50% of the viewport's width) and the Text has a width of "100vw", the Text bounding box is too large for its parent and is truncated.

Avoid using absolute dimensions to size components within a Container for this reason.

height and width not set (auto) and grow is set to 1

Bounding box takes up as much space as it needs for the content, and then also expands to fill in any available space within the Container. This can be useful when arranging multiple components within a Container. See Example: Text component that grows to fill the Container.

Note that the Text component has the grow and shrink properties only when it is within a Container and therefore has the additional properties for Container children.

The bounding box is always a rectangle

The text bounding box is always rectangular. On a device with a round screen, this means that text close to the edges of the bounding box (such as the top and bottom) might be clipped. For example:

Copied to clipboard.

{
  "type": "APL",
  "version": "1.4",
  "mainTemplate": {
    "parameters": [
      "textNoMarginsData"
    ],
    "items": [
      {
        "type": "Container",
        "height": "100vh",
        "width": "100vw",
        "items": [
          {
            "type": "Text",
            "text": "${textNoMarginsData.textAboutMargins}"
          }
        ]
      }
    ]
  }
}

Copied to clipboard.

{
  "textNoMarginsData": {
    "textAboutMargins": "This <code>Text</code> component has no margins, so it goes right up to the edge of the bounding box. The text is cut off on a small, round hub."
  }
}

On a rectangular viewport, this is readable, but doesn't look good since the text goes all the way to the edge of the screen. On a round device, the sides of the screen clip the text and make it unreadable.

The round viewport clips the edges of the <code>Text</code> bounding box
The round viewport clips the edges of the Text bounding box

To correct this, use the padding properties to put spacing around the text and push it away from the edge of the bounding box. Larger padding for the paddingTop and paddingBottom properties is especially helpful for round viewports.

This example uses the Spacing resources provided in the Alexa styles package to add padding around the text. This also uses the textStyleBody style from the same package to format the text appropriately for body text, and the textAlign property to center the text.

Top padding, center text alignment, and a better font size make the text work on a small, round hub
Top padding, center text alignment, and a better font size make the text work on a small, round hub

See Make your text look good on different-sized screens for additional techniques you can use to make text look good on different screens.

The following sections show some examples of how the Text component's bounding box intersects with properties meant to position the text in the component.

Example: Text component with auto-size

This example shows Text with size set to auto, within a Container that fills the viewport. The text takes up as much room as it needs. Since the text bounding box is the exact same height as the text itself, the textAlignVertical property has no effect.

Text component with the size defaulted to auto
Text component with the size defaulted to auto

Example: Text component with relative height and width

This example illustrates setting height and width on the Text component to relative dimensions (100%). The bounding box of the Text component now fills the Container, regardless of the size needed for the content. This lets you use alignment properties such as textAlignVertical to position the text.

<code>Text</code> component with height and width defined
Text component with height and width defined

Example: Text component that grows to fill the Container

You can also let the Text component dynamically adjust in size based on the amount of room in the parent container by setting the grow property to 1. Note that this property only applies when the Text component is within a Container and therefore has the additional Container children properties.

This can be especially useful for arranging multiple components in the Container. This example shows two Text components, one displayed at the top of the viewport, and one pushed to the bottom. The grow property ensures that the bounding box for the second component always fills all the vertical space remaining after the first component, so textAlignVertical can align the text with the bottom of the viewport.

<code>Text</code> component with size set to auto, but <code>grow</code> set to 1
Text component with size set to auto, but grow set to 1

The grow and shrink properties accept values between 0 and 1 and work proportionally. For example, set grow to 0.5 to let the component grow to fill half the empty space in the Container.

<code>Text</code> component with size set to auto, but <code>grow</code> set to 0.5
Text component with size set to auto, but grow set to 0.5

Display long, scrolling text

The Text component does not scroll, so longer content may be truncated, especially on smaller devices. When you have longer content, use the ScrollView component to create a scrollable area on the screen for your text and other components. Users can touch the screen to scroll the content. You can also configure the ScrollView to let users scroll the content by voice with utterances like "Alexa, scroll down."

Display a Text component in a ScrollView

A ScrollView has a single child component. To display a text block, use a Text component as the ScrollView child. To display multiple components, place them within a Container and then use the Container as the ScrollView child.

This example shows a large block of text on an area that uses most of the viewport, with some padding on all sides. Since the ScrollView is the only top-level component in this example, place it directly in mainTemplate:

Copied to clipboard.

{
  "type": "APL",
  "version": "1.4",
  "import": [
    {
      "name": "alexa-styles",
      "version": "1.1.0"
    }
  ],
  "mainTemplate": {
    "parameters": [
      "scrollTextData"
    ],
    "items": [
      {
        "type": "ScrollView",
        "id": "simpleScrollViewExample",
        "height": "100vh",
        "paddingLeft": "@marginHorizontal",
        "paddingRight": "@marginHorizontal",
        "paddingBottom": "@spacingSmall",
        "paddingTop": "@spacingSmall",
        "items": [
          {
            "type": "Text",
            "text": "${scrollTextData.simpleScrollingText}",
            "style": "textStyleBody"
          }
        ]
      }
    ]
  }
}

<code>ScrollView</code> component with a <code>Text</code> component child
ScrollView component with a Text component child

Use padding for round viewports

Be sure to use enough padding on the top of the ScrollView to avoid clipping text on a round device. The previous example sets paddingTop to the resource spacingSmall, which works on a rectangular viewport, but doesn't look good on a round viewport:

This long text does not look good on a round viewport
This long text does not look good on a round viewport

Increase the paddingTop value for round viewports and consider centering the text horizontally with textAlign to push the text content into the largest part of the viewport, away from the curved sides:

Padding and centering the text to fit better on a round viewport
Padding and centering the text to fit better on a round viewport

You can use custom styles and resources to set these properties to different values based on conditions such as the viewport, as described in Make your text look good on different-sized screens, later.

Create a fixed area above and/or below the scrolling content

In the previous example, it might appear that the paddingBottom property is not being used, as the text runs all the way to the bottom of the viewport. The "top" and "bottom" of a ScrollView are based on the full vertical size of the component, including the scrollable content. The padding properties add the padding at the start and the end of the scrollable content. Scroll to the end of the content to see padding.

Padding on the bottom of the <code>ScrollView</code> displays when the content is scrolled to the end.
Padding on the bottom of the ScrollView displays when the content is scrolled to the end.

If you want a non-scrolling area above or below the scrolling content, put the ScrollView inside a Container and set the padding properties on the Container instead of on the ScrollView.

Fixed scrolling area
Fixed scrolling area

Using a fixed area around scrolling content is not recommended for small hubs since it reduces the content area on an already-small device. Use the when property to build different layouts for different devices.

  • For small, round hubs, set the padding properties on the ScrollView itself, so that the spacing scrolls off the screen and gives more room to the content. Place any other components (such as a header or footer) inside the ScrollView, so all content on the screen can scroll.
  • For all other types of viewports, put the ScrollView inside a Container. Set padding on the Container and include other components that should be persistent on the screen as child components of the Container rather than the ScrollView.

You can also do something similar if you want content to display in the fixed area, such as a header or footer. See Combine scrolling text with the header and footer in Combine Content with Backgrounds, Borders, and Headers.

Let users scroll the content by voice

Although users can scroll a ScrollView by touching the screen, they will expect to be able to scroll the content by voice as well.

Use the built-in intents to enable voice-based scrolling:

  • AMAZON.ScrollDownIntent
  • AMAZON.ScrollUpIntent
  • AMAZON.PageUpIntent
  • AMAZON.PageDownIntent
  • AMAZON.MoreIntent

A ScrollView always scrolls in a vertical direction, so the built-in intents for scrolling left and right have no effect.

For examples of the utterances users can say to invoke these intents, see Available standard built-in intents for Alexa-enabled devices with a screen.

Enable users to scroll the content by voice

  1. In your interaction model, add the built-in intents for scrolling:
    • AMAZON.ScrollDownIntent
    • AMAZON.ScrollUpIntent
    • AMAZON.PageUpIntent
    • AMAZON.PageDownIntent
    • AMAZON.MoreIntent
  2. Rebuild your interaction model.
  3. In your document, set the id property on the ScrollView component to an ID. Use an ID that is unique within that document.

If you do not provide an id for the ScrollView, the scroll intents will not work.

When you test your skill, invoke the intent that displays the ScrollView, then use the relevant utterances for your skill's language. For example:

…interaction that displays the ScrollView. Note that this response left shouldEndSession undefined, so the session is open, but the microphone is closed.
User: Alexa, Scroll down (User must use the wake word to open the microphone.)
The content scrolls to show more content.

Make your text look good on different-sized screens

When working with text, there are several strategies you can use to ensure that your text looks good and is readable on all the different Alexa devices with screens.

The easiest option is to use the Alexa headline responsive template if the brief headline text suits your use case. This layout is built to work well on all different devices, so you only need to provide your content.

When you build your own layout, consider the recommendations in these sections.

Use styles for alignment and typographic properties

Use styles to set visual characteristics of your text like font size, alignment, and other typographic properties. You can use the pre-defined styles in the Alexa styles package or create your own. Styles can use the when clause to adjust the visual characteristics based on conditions like the current viewport.

The earlier examples that show the Text component used the textStyleBody style. This style works well for longer-form content and automatically adjusts the font size for different viewports.

You can build your own custom style, and you can use the pre-defined styles as a starting point. For example, since text sometimes looks better when centered on round hubs, you could define this custom style based off of textStyleBody. The style centers text on viewports with the hubRoundSmall profile, but leaves it set to the default (auto) for all other types of viewports:

{
  "styles": {
    "customTextStyleBody": {
      "extend": "textStyleBody",
      "values": [
        {
          "when": "${@viewportProfile == @hubRoundSmall}",
          "textAlign": "center"
        }
      ]
    }
  }
}

Use resources for property values

When you set property values for the Text component, consider using resources instead of hard-coding values. A resource is a named constant that can be assigned a value. As with styles, you can create resources with a when clause so that they change value depending on conditions such as the viewport. A resource can be used to set any property, unlike styles.

The Alexa styles package also includes several pre-defined resources. For Text, look at:

  • Text resources provide values useful for setting values in the typographic properties such as fontSize, fontWeight, and so on.
  • Spacing resources provide values useful for setting the padding properties.

All of the earlier examples that show the Text component used the spacing resources for padding properties. The marginHorizontal and spacing3XLargeresources automatically adjust based on the viewport.

For example, you may want different padding for small round hubs to push text away from the edges of the bounding box:

{
  "resources": [
    {
      "dimensions": {
        "myTopAndBottomSpacing": "@spacingSmall"
      }
    },
    {
      "when": "${@viewportProfile == @hubRoundSmall}",
      "dimensions": {
        "myTopAndBottomSpacing": "@spacing3XLarge"
      }
    }
  ]
}

Use the @ syntax anywhere you want the specified value. In this example, both the paddingBottom and paddingTop properties are set to resource myTopAndBottomSpacing:

{
  "type": "ScrollView",
  "id": "simpleScrollViewExample",
  "height": "100vh",
  "paddingLeft": "@marginHorizontal",
  "paddingRight": "@marginHorizontal",
  "paddingBottom": "@myTopAndBottomSpacing",
  "paddingTop": "@myTopAndBottomSpacing",
  "items": [
    {
      "type": "Text",
      "text": "${payload.scrollTextData.properties.simpleScrollingText}",
      "style": "customTextStyleBody"
    }
  ]
}

Truncate text on small devices

Depending on your content, you might want to truncate or hide longer text on smaller devices. For example, consider the "grow" example shown earlier. On a larger viewport, there is space between the two Text components. On a small round hub, the components display with no space between them, and making the text even a bit longer cuts it off.

In this scenario, you could set the maxLines property on the second Text component. This truncates any text that won't fit within the specified number of lines and adds an ellipsis ("…") to make it more clear that the text ends deliberately.

Use a style to set maxLines conditionally depending on the viewport. In this example, customTextStyleBody extends the textStyleBody style from the Alexa styles package, sets textAlignVertical for all viewports, and changes textAlign and maxLines for hubRoundSmall:

{
  "styles": {
    "customTextStyleBody": {
      "extend": "textStyleBody",
      "values": [
        {
          "textAlignVertical": "bottom"
        },
        {
          "when": "${@viewportProfile == @hubRoundSmall}",
          "textAlign": "center",
          "maxLines": 3
        }
      ]
    }
  }
}

Purposely truncating text on a small, round hub
Purposely truncating text on a small, round hub

For more about ensuring that your document looks good on different devices, see Build Responsive APL Documents.