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, 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. However, the skill might show just an icon representing the skill on a small device like an Echo Spot.
In contrast, a nonresponsive APL document built with Fire TV in mind is unlikely to be usable on the small Echo Spot or Echo Show 5. This nonresponsive document results in a poor customer experience for your users, and increases the likelihood that customers 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 approach 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 ready to work properly on the device.
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 doesn't look good 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. You can express most sizes in relative dimensions, such as "100%". Using relative dimensions helps your document resize to fit different-sized viewports. Relative dimensions also help your document resize smoothly on devices that can change size during the skill session, such as tablets.
-
Alexa Responsive components. The Alexa Design System for APL provides a set of ready-to-use responsive components. A responsive component combines 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. The Alexa Design System for APL provides a set of ready-to-use responsive templates. A template combines 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. The Alexa Design System for APL provides a set of ready-to-use styles and resources. The Alexa styles and resources use conditional logic so that they 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 that you can use in your skill. All of these items are already built to be responsive to different viewports. See the following sections:
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 don't 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 must arrange seven components within mainTemplate
yourself:
Text
components to display the title at the topImage
component to display an icon at the top on small viewportsImage
orFrame
to create a backgroundSequence
to create a scrollable listText
to show the number of each itemText
to show the text of each itemTouchWrapper
to make the list items selectable
For more details 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 layout.
For example, you could combine these components to create a custom detail page:
AlexaHeader
AlexaFooter
AlexaBackground
Text
(component)
In this case, the header, footer, and background all adjust to different viewports. You design the body portion of your layout to handle different viewports. The following example does this design work by setting the maxLines
property on the Text
component to show only two lines and truncate the text on small, round hubs. A more complex body layout requires more extensive conditional logic and techniques. This code example uses a data source to produce the correct hint text. For more details and an example, see Use the textToHint transformer.
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:
- AlexaBackground
- AlexaButton
- AlexaCheckbox
- AlexaDivider
- AlexaFooter
- AlexaHeader
- AlexaIconButton
- AlexaImage
- AlexaImageListItem
- AlexaOrdinal
- AlexaPageCounter
- AlexaProgressBar
- AlexaProgressBarRadial
- AlexaProgressDots
- AlexaRadioButton
- AlexaRating
- AlexaSlider
- AlexaSliderRadial
- AlexaSwipeToAction
- AlexaSwitch
- AlexaTextListItem
- AlexaTransportControls
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 use conditional logic 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 relative dimensions whenever possible
- Use viewport profiles in your conditional logic
- Build conditions into the document
- Make your document modular
Use relative dimensions whenever possible
You can specify the height and width of a component in either absolute or relative dimensions:
- A relative dimension is a percentage relative to the size of the component's parent. For the top-level component in the document, setting
width
to100%
represents the full width of the viewport. - An absolute dimension refers to a specific number of display-independent pixels, such as
20dp
.
For example, consider this simple hierarchy:
mainTemplate
Container
Text
Text
In this example, you might set both the height
and width
of the top-level Container
to 100%
so that it uses the entire viewport. Then, you might set the Text
component sizes to smaller percentages to size the Text
blocks in relation to the Container
.
For a responsive document, use either relative dimensions or auto
whenever possible. When you use relative dimensions to size a component, the layout is more likely to work on different-sized screens.
In addition, relative dimensions give you more options for supporting devices that change screen size during the skill session, such as tablets. Users can rotate a tablet to switch between a portrait and landscape orientation. You can configure your document to automatically resize the content when the device orientation changes. If you use absolute dimensions in this case, the content is likely to resize poorly.
For details automatically resizing, see Let APL automatically resize your document.
Are the vh
and vw
dimensions responsive?
No. A dimension with vw
or vh
as the unit is an absolute dimension that works as a shortcut for the viewport.width
or viewport.height
properties. For example, on an Echo Show, the dimension "100vw" resolves to "1024dp". The dimension "50vw" resolves to "512dp".
The viewport.width
and viewport.height
properties are constants that don't change after the document is displayed unless you run the Reinflate
command. This means that on a device that can change its screen size during the skill session, such as a tablet, using the vw
and vh
dimensions creates an experience that resizes poorly when the user rotates the device when you use the default resizing option.
To avoid this poor experience, don't use vw
or vh
when specifying dimensions. Use relative dimensions whenever possible.
For details about supporting tablets, see Support Tablets and Other Devices that Can Change Size.
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 Boolean when
property. When the when
property is true
, Alexa displays the component on the viewport. When the when
property is false, Alexa skips the component and doesn't display it on the viewport.
For example, if you want the component to display on large hubs, write a statement like this:
"when": "${@viewportProfile == @hubLandscapeLarge}"
In contrast, don't specify a width like this:
"when": ${viewport.width == "1280dp"}
The second version targets a narrow set of devices and isn't responsive. If another similar hub becomes available with a 1030-dp wide screen, the component with the viewport.width
condition doesn't display. In contrast, hubLandscapeLarge
includes screens between 1280 dp through 1920 dp 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 expression 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 might not work the way you expect 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 must 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. 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.
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 exposes low-level viewport characteristics like width and height. To get the equivalent of the viewport profiles described earlier, you must write a function to calculate profiles from the low-level data. - Some devices can change their viewport characteristics when in use. This action invokes the
onConfigChange
handler in the APL document, but it doesn't send a new request to your skill. For example, a user can flip a tablet from landscape to portrait. A skill that uses conditionals built into the document can adjust the layout to fit the new viewport and reinflate the document. A skill that uses logic in the code can't respond to this situation. - It's 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 one at runtime, you must switch out the entire document in the authoring tool to see how it looks on different viewports.
Make your document modular
APL supports modular documents. For example, a responsive component from the alexa-layouts
package combines the APL components and conditional logic into a single building block you can place in your document. You can build out a complete document by assembling these separate building blocks in different ways.
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.
When you create a custom component, 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. Because 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 hides or shows the caption depending on the viewport size. Then, place that layout along with the AlexaBackground
responsive component.
The following example shows the layouts
property with a custom layout definition, along with a custom style to format the caption text.
{
"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 code in place, your mainTemplate
just needs a Container
with the AlexaBackground
and FactTextAndCaptionBlock
.
{
"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 will look on potential future devices.
For details about using these tools, see the following topics:
Select the viewport profiles your skill supports
After you've made your document responsive and are confident that it looks good on all different devices, revisit the Build > Custom > Interfaces page. Make sure you've selected that your skill supports all the viewport profiles. This selection is important, because Alexa checks for this support before displaying your document. If the device doesn't match one of your supported profiles, your content is scaled to fit the screen.
You should consider scaling like this a last resort. Scaling shouldn't be needed if your document is responsive.
For details about supported profiles and how scaling works, see Select the Viewport Profiles Your Skill Supports.
Related topics
- Alexa Design System for APL
- Responsive Components and Templates
- Viewport Profiles
- Select the Viewport Profiles Your Skill Supports
Last updated: Jan 26, 2024