感谢您的访问。此页面目前仅提供英语版本。我们正在开发中文版本。谢谢您的理解。

Build Responsive APL Documents

Users can invoke skills on devices with a wide variety of screen sizes, shapes, and aspect ratios. To make your skill look good across all these different devices, you need to build a responsive APL document.

What is a responsive APL document?

A responsive Alexa Presentation Language (APL) document can adjust to the characteristics of the viewport. For example, a skill might show title and subtitle text on the top of the screen on a device with a large screen, but just an icon representing the skill on a small device like an Echo Spot.

In contrast, a non-responsive APL document built with Fire TV in mind is unlikely to be usable on the very small Echo Spot or Echo Show 5. This results in a poor customer experience for your users, and increases the likelihood that they won’t try your skill again.

To be most effective, tie the responsiveness to the viewport profile of the device, not specific devices. That is, you might define a layout to use when the screen is a particular shape (such as landscape) and falls within a size range (greater than x, less than y). This is more flexible than targeting an exact screen size. If a new device becomes available and it falls into the same general range, your APL document is already ready to work properly on it.

How APL supports building responsive documents

APL has been designed to support creating responsive documents. However, APL also offers flexibility in how you build your document. You can build a document that works on many devices, or a document that only works on one device and completely breaks when used on a different device.

When you create your APL documents, choose to use the responsive features whenever possible. These features include:

  • Conditional logic. You can define criteria that determines whether a particular component or layout should display on the viewport. This criteria can use the characteristics of the device, such as the viewport size.

  • Styles and resources. You can group together and name a set of properties, then use the style or resource name instead of hard-coding property values. These items can also have conditional logic, so you could define a style with one font size for small viewports and a different one for large viewports.

  • Viewport profiles. You can use viewport profiles as criteria in your conditional logic. Viewport profiles are named resources that represent a range of viewport characteristics. A profile specifies a shape, orientation, range of sizes, and range of densities, so the profile can represent multiple physical devices. Basing your logic off of these profiles makes your logic more robust as new devices become available.

  • Relative dimensions. Most sizes can be expressed in relative dimensions, such as "100%". You can also use absolute dimensions based off the size of the viewport, such as "100vw" for 100% of the viewport width. Choosing the right type of dimensions to use ensures that the design and the components adjust to different sized viewports.

  • Alexa Responsive components. A set of ready-to-use components are provided as part of the Alexa Design System for APL. These combine components (primitive UI elements) into building blocks you can use in your documents. Using a responsive component instead of building from scratch gives you responsiveness with less effort.

  • Alexa Responsive templates. A set of ready-to-use templates are provided as part of the Alexa Design System for APL. Templates combine the components (primitive UI elements) and responsive components into a complete layout that fills the viewport. Using a responsive template instead of building from scratch gives you responsiveness with less effort.

  • Alexa styles. A set of ready-to-use styles are also part of the Alexa Design System for APL. The Alexa styles are built with conditional logic so the can adapt to different viewports.

The remaining sections of this document provide more details around using these features and concepts to make your document responsive.

Use the Alexa Design System for APL

The Alexa Design System provides packages with pre-built responsive components, templates, and styles you can use in your skill. All of these items are already built to be responsive to different viewports. See the following topics:

Responsive templates

The responsive templates provided in the Alexa Design System for APL are the easiest way to create responsive documents. Each of these templates provides a layout that fills the viewport and includes all the elements you would typically want, such as a header and background. You customize the content displayed by setting properties on the template. When using this option, you do not need to arrange any components in the visual hierarchy yourself. You can just place a single item in your document to get the complete result.

For example, the following APL document creates a scrolling list. The mainTemplate property contains one item of type AlexaTextList.

In contrast, to build a similar layout from scratch, you need to place all of these components correctly within mainTemplate yourself:

  • Text components to display the title at the top
  • Image component to display an icon at the top on small viewports
  • Image or Frame to create a background
  • Sequence to create a scrollable list
  • Text to show the number of each item
  • Text to show the text of each item
  • TouchWrapper to make the list items selectable

For more about the responsive templates, see Responsive Components and Templates

The following responsive templates are available:

Responsive components

The responsive components provided in the Alexa Design System for APL combine components (primitive UI elements) into building blocks you can use in your documents. Each responsive component is already built to be responsive. You can combine these components to create a custom layouts.

For example, you could combine these components to create a custom detail page:

In this case, the header, footer, and background all adjust to different viewports. You would only need to design the body portion of your layout to handle different viewports. The following example does this by setting the maxLines property on the Text component to only show 2 lines and truncate the text on small, round hubs. A more complex body layout would require more extensive conditional logic and techniques. Note that this sample uses a data source to produce the correct hint text. See Use the textToHint transformer for details and a sample.

When you use the responsive components to build custom layouts, be sure to follow the best practices described later to make the rest of your design responsive.

The following responsive components are available:

Alexa styles

A style names a set of visual characteristics that you can apply to the components in your document. The Alexa styles package (alexa-styles) provided in the Alexa Design System for APL includes a set of styles you can use in your document. These styles are built with the conditional logic needed to make them responsive to different viewports and situations.

For example, the style fontSizeLarge defines a large font size. The actual size changes depending on the viewport of the device, so the font is larger on landscape hubs and smaller on round hubs.

In addition, using the styles gives your skill a consistent look and feel.

For details about the styles, see Alexa Styles.

For a reference to which component properties are styled, see Styled Properties

Responsive document best practices

When you build your APL document from a combination of APL components and responsive components, follow these best practices to make your document work on all different viewports.

Use dimensions correctly

You can specify the height and width of a component in either absolute or relative dimensions.

  • An absolute dimension refers to a specific number of display-independent pixels, such as "20dp". You can specify an absolute dimension based on the viewport height or width with the vh and vw units. For example, "100vw" represents the full width of the viewport. For a large hub such as the Echo Show, specifying "100vw means 1280dp, while "50vh" means 640dp. Specifying a dimension in this way is responsive, since it is always relative to the actual viewport in use.
  • A relative dimension is a percentage relative to the size of the component's parent, such as "80%".

Combine these different ways to express dimensions in different ways to achieve your layout. For example, consider this simple hierarchy:

mainTemplate
    Container
        Text
        Text

In this example, you might set the height and width of the top-level Container to 100vh / 100vw so that it uses the entire viewport. Then, you might use percentages for the dimensions of the Text components. This sizes the Text blocks in relation to the Container, not the viewport.

For a responsive document:

  • Use the vh / vw units to specify the size of a component relative to the viewport.
  • Use percentage dimensions to specify the size of a component relative to its parent container.
  • Avoid hard-coding absolute dimensions such as "60dp".

Use viewport profiles in your conditional logic

Conditional logic is key concept for responsive APL documents, but it is important to define your logic in the most responsive way. When you write data-binding expressions that evaluate device characteristics, use the viewport profiles provided in the viewport profiles package instead of low-level viewport characteristics.

For example, each APL component has a when property that expects a boolean value. This determines whether or not Alexa displays the component on the viewport. If you want the component to display on large hubs, write a statement like this:

"when": "${@viewportProfile == @hubLandscapeLarge}"

In contrast, do not specify a width like this:

"when": ${viewport.width == "1280dp"}

The second version targets a very narrow set of devices and is not responsive. If another similar hub becomes available with a 1030dp wide screen, the component with the viewport.width condition won't display. In contrast, hubLandscapeLarge includes screens between 1280 and 1920 wide, so this condition works on the new, unknown device. When you write logic for viewport profiles, rather than for specific devices or low-level characteristics, your logic can work multiple, similar devices at once.

You can encounter a similar issue with other single, low-level device characteristics such as viewport.shape. Consider the expression ${viewport.shape == 'round'}. This evaluates to true for any device with a round screen, regardless of size. If you use this expression to handle content on small, round hubs (such as the Echo Spot), your skill may break if a new device with a large round screen becomes available. Only use something like ${viewport.shape == 'round'} if the component would display as you want on a round screen of any size.

Finally, if you do need to create a condition based on a size rather than a full viewport profile, use the size resources also defined in the viewport profiles package. For example:

"when": "${viewport.width == @viewportSizeMedium}"

You can also use size classes, which group the height and width:

"when": "${@viewportSizeClass == @viewportClassMediumLarge}"

As with the viewport profiles, the size resources work off of ranges, so multiple different devices can fall in to the same viewportSizeMedium size.

Build your conditional logic into the document

Build your conditional logic into your APL document instead of branching the experience in your skill code at runtime. Use the viewport profiles discussed earlier, and the properties of the Viewport object in the data-binding context to create your conditional logic.

Note that information about the viewport is also available to your skill code in the Viewport object in the skill request. However, there are downsides to putting your logic in code instead of the document:

  • The Viewport object in the request only exposes low-level viewport characteristics like width and height. To get the equivalent of the viewport profiles described earlier, you need to either use one of the ASK SDKs with helper functions, or write your own helper functions to calculate profiles from the low-level data.
  • It is harder to test and experiment in the authoring tool. If your logic is in the document, you can upload your document to the authoring tool and click between the viewports to see how it displays and experiment with changes. If your logic is in code, such as maintaining entirely separate documents and choosing the right one at runtime, you need to switch out the entire document in the authoring tool to see how it looks on different viewports.

Make your document modular

APL is designed to support modular documents. The responsive components provided in the alexa-layouts package are an example of this. The responsive components combine the APL components and conditional logic into a single building block you can place in your document that handles all of the responsiveness.

You can take this same approach by building your own responsive components when the provided ones don't meet your needs. Add your custom components to the layouts property in your APL document. Then, you use your custom component in mainTemplate, just as you use the APL components and responsive components.

This lets you encapsulate the look, functionality, and responsiveness of the component in a single place, which is easier to understand and maintain.

For example, a simple "fact skill" might render a document that displays the relevant fact along with a related background image and caption. Since the fact text is long, you might want to hide it for small, round hubs and just show the image caption. You could create a FactTextAndCaptionBlock layout that does this, then place that layout along with the AlexaBackground responsive component.

This example shows the layouts property with this custom layout definition, along with a custom style to format the caption text:

Copied to clipboard.

{
  "styles": {
    "mainFactText": {
      "description": "Visual properties for the main text we want to display.",
      "values": [
        {
          "textAlign": "center",
          "textAlignVertical": "center",
          "fontSize": "@fontSizeLarge"
        }
      ]
    },
    "captionText": {
      "description": "Style for a red, italic caption.",
      "extends": "mainFactText",
      "values": [
        {
          "color": "red",
          "fontStyle": "italic",
          "fontSize": "@fontSizeMedium"
        }
      ]
    }
  },
  "layouts": {
    "FactTextAndCaptionBlock": {
      "description": "Display fact text, followed by a caption relevant to an image. Only show the caption on small round hubs.",
      "parameters": [
        "factText",
        "imageCaption"
      ],
      "items": [
        {
          "type": "Container",
          "height": "100%",
          "width": "100%",
          "justifyContent": "center",
          "grow": 1,
          "items": [
            {
              "type": "Text",
              "when": "${@viewportProfile != @hubRoundSmall}",
              "paddingLeft": "@spacingLarge",
              "paddingRight": "@spacingLarge",
              "text": "${factText}",
              "style": "mainFactText"
            },
            {
              "type": "AlexaDivider",
              "when": "${@viewportProfile != @hubRoundSmall}",
              "width": "50%",
              "alignSelf": "center",
              "paddingTop": "@spacingSmall",
              "paddingBottom": "@spacingSmall"
            },
            {
              "type": "Text",
              "paddingLeft": "@spacingSmall",
              "paddingRight": "@spacingSmall",
              "text": "Image: ${imageCaption}",
              "style": "captionText"
            }
          ]
        }
      ]
    }
  }
}

With this in place, your mainTemplate just needs a Container with the AlexaBackground and FactTextAndCaptionBlock:

Copied to clipboard.

{
  "mainTemplate": {
    "parameters": [
      "payload"
    ],
    "items": [
      {
        "type": "Container",
        "width": "100vw",
        "height": "100vh",
        "items": [
          {
            "type": "AlexaBackground",
            "backgroundImageSource": "https://d2o906d8ln7ui1.cloudfront.net/images/BT1_Background.png",
            "colorOverlay": "true"
          },
          {
            "type": "FactTextAndCaptionBlock",
            "factText": "This is the fact text. We want to display it on devices where the screen is large enough that it shows up comfortably. The skill speaks this text in the response, so it is OK if we don't show it on devices that are too small.",
            "imageCaption": "This is a very brief caption for the background image."
          }
        ]
      }
    ]
  }
}

Test your responsive APL document

As you build your skill, test the presentation on the different viewports. Testing on an actual device is always best, but you can also use the authoring tool or the simulator on the Test page.

  • Use the authoring tool to see the document as you build it. If you do have devices on your account, you can push your document to the device as you build.
  • Use the Test page to test the document with your skill code, with your voice input and Alexa responses. Testing your runtime code (such as your Lambda function) is also necessary for testing any commands you with the ExecuteCommands directive.

In both the authoring tool and the simulator, you can test with different viewports. You can also create custom viewports to see how your skill would look on potential future devices.

For details about using this tools, see:

Select the viewport profiles your skill supports

Once you've made your document responsive and are confident that it looks good on all different devices, revisit the Build > Custom > Interfaces page and make sure you've selected that your skill supports all the viewport profiles. This is important, because Alexa checks for this support before displaying your document. If the device does not match one of your supported profiles, your content is scaled to fit the screen.

Scaling like this should be considered a last resort and should not be needed if your document is responsive.

For details about supported profiles and how scaling works, Select the Viewport Profiles Your Skill Supports.