$category@ | formats | teaser | |||
---|---|---|---|---|---|
presentation |
|
|
![]() |
![]() |
![]() |
Description | Embed and play stories in a non-AMP website. |
Required Scripts |
<script async src="https://cdn.ampproject.org/amp-story-player-v0.js"></script>
<link href="https://cdn.ampproject.org/amp-story-player-v0.css" rel='stylesheet' type='text/css'>
|
Examples |
|
[TOC]
Use amp-story-player
to embed and play stories within a webpage.
The code snippet below demonstrates an embed of <amp-story-player>
in a non-AMP webpage.
[example preview="top-frame" playground="true"]
<head>
<script
async
src="https://cdn.ampproject.org/amp-story-player-v0.js"
></script>
<link
href="https://cdn.ampproject.org/amp-story-player-v0.css"
rel="stylesheet"
type="text/css"
/>
</head>
<body>
<amp-story-player style="width: 360px; height: 600px;" amp-cache="cdn.ampproject.org">
<a
href="https://preview.amp.dev/documentation/examples/introduction/stories_in_amp/"
>
Stories in AMP - Hello World
</a>
</amp-story-player>
</body>
[/example]
The inline width and height ensures that the player will not cause any jumps in your website while the script is being loaded. Feel free to modify the values, but we recommend maintaining a 3:5 aspect ratio.
Inline CSS properties for the width and height of the player. e.g. style="width: 360px; height: 600px;"
e.g. <amp-story-player amp-cache="cdn.ampproject.org">
If specified, the player will rewrite the URL using the AMP Cache prefix provided. Currently there are two AMP Cache providers:
cdn.ampproject.org
www.bing-amp.com
The <amp-story-player>
component contains one or more <a>
tags. Point the href attribute of each to the story URL.
Place the story's title within the <a>
tag. This provides a better user experience and allows search engines to crawl embedded stories.
URL pointing to the story.
Call the player's various methods to programmatically control the player. These methods are exposed on the HTML element, const playerEl = document.querySelector('amp-story-player')
and on instances of the global class variable, const player = new AmpStoryPlayer(window, playerEl)
.
Will initialize the player manually. This can be useful when the player is dynamically.
Note that the element must be connected to the DOM before calling load()
.
const playerEl = document.body.querySelector('amp-story-player');
const player = new AmpStoryPlayer(window, playerEl);
player.load();
Parameters
- number: the story in the player to which you want to move, relative to the current story.
- number (optional): the page of the story to which you want to move, relative to the current page.
If the player is currently on the third story out of five stories:
player.go(1)
will go forward one story to the fourth storyplayer.go(-1)
will go backward one story to the second storyplayer.go(-1, 1)
will go backward one story and navigate one page backwardsplayer.go(0, 5)
will stay in the current story and navigate 5 pages forward
Parameters
- string or null: the URL of the story to show.
- string (optional): the ID attribute of the page element.
Will change the current story being displayed by the player.
player.show('cool-story.html'); // Will display cool-story.html
player.show('cool-story.html', 'page-4'); // Will display cool-story.html and switch to page-4
player.show(null, 'page-4'); // Stay on current story and switch to page-4
Parameters
- array of story objects
Each story object contains the following properties:
- href string: story URL
- title string (optional): story title, to be added to the anchor's title
- posterImage string (optional): a URL for the story poster. Used as a placeholder while the story loads.
The player will rewrite the URL using the AMP Cache prefix if provided in the player level attribute.
player.add([
{href: '/stories/1', title: 'A great story', posterImage: 'poster1.png'},
{href: '/stories/2', posterImage: 'poster2.png'},
{href: '/stories/3'},
]);
Will mute/unmute the current story. This will not persist across stories, eg. calling player.mute()
on the first story will not mute the second story.
Please note that due to browser restrictions on autoplaying media with sound, the default state is muted and the story cannot be unmuted unless the user manually unmuted previously. Only webviews explicitly allowing autoplaying media with sound can use unmute()
right away.
player.mute();
player.unmute();
Will play/pause the current story. This will affect e.g. page auto-advancement or media playing.
player.play();
player.pause();
Parameters
- string: the story state, currently only
page-attachment
.
Will cause a custom event to be fired, see page-attachment-open
and page-attachment-close
.
player.getStoryState('page-attachment');
By default, the first story in the player will automatically start playing when the player becomes visible in the user's viewport.
You can opt-out of the default behavior by using the configuration below. This will prevent the first story in the player to start playing until you call play() on the player.
Here's the JSON configuration for opting out of autoplay:
<amp-story-player>
<script type="application/json">
{
"behavior": {
"autoplay": false
}
}
</script>
<a href="./story1.html"> ... </a>
<a href="./story2.html"> ... </a>
...
You can create an “infinite scroll” experience by fetching more stories as the user navigates through them in your player. Simply use the new JSON configuration to specify an endpoint, and the player will automatically fetch more stories as it gets closer to the last story in the player.
Here’s an example of how the configuration looks:
<amp-story-player>
<script type="application/json">
{
"behavior": {
"on": "end",
"action": "fetch",
"endpoint": "https://example.com/my-endpoint.json?offset=${offset}"
}
}
</script>
<a href="./story1.html"> ... </a>
<a href="./story2.html"> ... </a>
...
The configuration must be a direct child of the element, with the type=”application/json”
attribute.
The endpoint
property of the url takes in an optional variable ${offset}
that you can add as a parameter, which you can use for pagination.
The expected response payload coming from the endpoint should be a JSON containing an array of Story objects, the structure is described below.
The URL where your story is located.
The title of your story.
The poster image of your story.
Example:
[
{
"href": "https://example.com/story3.html",
"title": "My third cool story", // optional
"posterImage": "https://example.com/assets/story3.png" // optional
},
{
"href": "https://example.com/story4.html",
"title": "My fourth cool story", // optional
"posterImage": "https://example.com/assets/story4.png" // optional
}
]
Circular wrapping enables users to go back to the first story when they finish the last one. To do this, use the JSON configuration with the circular-wrapping
action.
Here’s an example of how the configuration looks:
<amp-story-player>
<script type="application/json">
{
"behavior": {
"on": "end",
"action": "circular-wrapping"
}
}
</script>
<a href="./story1.html"> ... </a>
<a href="./story2.html"> ... </a>
...
</amp-story-player>
The configuration must be a direct child of the element, with the type=”application/json”
attribute.
You can now customize controls of the story UI with a variety of options. These include new buttons, changing the position (start or end), among others.
See examples below to get an idea of what you can do.
![]() |
![]() |
![]() |
To configure them, specify a JSON configuration with the type=”application/json”
attribute as a child of the <amp-story-player>
element.
Inside the configuration, specify an array of “controls”. The “controls” structure is described below.
The configuration will end up looking like the following:
<amp-story-player>
<script type="application/json">
{
"controls": [
{
"name": "close",
"position": "start"
},
{
"name": "skip-next"
}
]
}
</script>
<a href="./story1.html"> ... </a>
<a href="./story2.html"> ... </a>
</amp-story-player>
Specify a control object with the “close” name to get the close icon.
event
: The close button dispatches theamp-story-player-close
event.
The “close” control supports the following customizable properties:
position
: “start” or “end”.- Places the icon either on the left or right on LTR languages.
visibility
: “hidden” or “visible” (default).- Toggles the control’s visibility. If omitted, the default is visible.
- See Example #2 - Showing skip-to-next story on desktop.
backgroundImageUrl
: string with url or data string (escaped).- Changes the icon image to the provided url or data string (for inline svgs).
Skips to the next story inside the player (only available on desktop).
The “skip-next” control supports the following customizable properties:
position
: “start” or “end”.- Places the icon either on the left or right on LTR languages.
visibility
: “hidden” or “visible” (default).- Toggles the control’s visibility. If omitted, the default is visible.
backgroundImageUrl
: string with url or data string (escaped).- Changes the icon image to the provided url or data string (for inline svgs).
You can add a custom control to the stories inside the player with a custom control. Simply specify a “name” and an “backgroundImageUrl”, and any optional properties:
name
(required): a string with the name of the control. e.g. “lightbox”. The dispatched event will depend on this name. The custom event will be the name of the control prefixed withamp-story-player-*
. E.g.amp-story-player-lightbox
:
const player = document.body.querySelector("amp-story-player");
// Listen to when the specified control was clicked.
player.addEventListener("amp-story-player-lightbox", () => {
// This will trigger when the control with the "lightbox" name is clicked.
performCustomAction();
});
backgroundImageUrl
(required): Accepts URLs, as well as svgs anddata
paths (note that strings must be JSON escaped). See example 3.- Changes the control icon.
position
: “start” or “end”.- Places the icon either on the left or right on LTR languages.
visibility
: “hidden” or “visible” (default).- Toggles the control’s visibility. If omitted, the default is visible.
Since by default the close button will be placed to the end, all we have to do is move the close button to the start.
<script type="application/json">
{
"controls": [
{
"name": "close",
"position": "start"
}
],
}
</script>
...
|
![]() |
On desktop, you can now display a button that navigates from the current story to the next one. It will also automatically be disabled once the user reaches the end of the stories in the player.
<script type="application/json">
{
"controls": [
{
"name": "skip-next"
}
],
}
</script>
...
|
![]() |
<script type="application/json">
{
"controls": [
{
"name": "close",
"backgroundImageUrl": "data:image\/svg+xml;charset=utf-8,<\/svg>",
"position": "start"
}
]
}
</script>
...
|
![]() |
Fired when the player is ready for interaction. There is also a sync property isReady
that can be used to avoid race conditions.
player.addEventListener('ready', () => {
console.log('Player is ready!!');
})
if (player.isReady) {
console.log('Player is ready!');
}
Fired when the player changes to a new story and provides the index
, the player's story after changing, and remaining
, the number of stories left.
player.addEventListener('navigation', (event) => {
console.log('Navigated from story 0 to story 1 of 3');
console.log('Current story:' event.index); // 1
console.log('Current story:' event.remaining); // 1
})
Fired when the story inside the player changes to a new page. It provides the pageId
and progress
of the story. The progress is the completion percentage of the story represented as a number between 0 and 1.
player.addEventListener('storyNavigation', (event) => {
console.log('User navigated from one page to the other.');
console.log('Current page id:' event.pageId); // page-2
console.log('Story progress:' event.progress); // Number from 0 to 1.
})
Dispatched when there is no next story. Note that this will not be dispatched when using Circular wrapping.
player.addEventListener('noNextStory', (event) => {
console.log('User is tapping on the last page and there are no more stories.');
});
Dispatched when there is no next story. Note that this will not be dispatched when using Circular wrapping.
player.addEventListener('noPreviousStory', (event) => {
console.log('User is tapping back on the first page and there are no more stories.');
});
Fired when the exit control close button is clicked.
player.addEventListener('amp-story-player-close', () => {
console.log('Close button clicked');
})
Fired when a page attachment is opened or getStoryState('page-attachment')
was called and the story's page attachment is open.
player.addEventListener('page-attachment-open', () => {
console.log('The page attachment is open');
})
Fired when a page attachment is closed or getStoryState('page-attachment')
was called and the story's page attachment is closed.
player.addEventListener('page-attachment-close', () => {
console.log('The page attachment is closed');
})
This makes use of page-attachment-close
, page-attachment-open
and amp-story-player-back
.
player.addEventListener('page-attachment-close', () => {
textEl.style.backgroundColor = 'blue';
})
player.addEventListener('page-attachment-open', () => {
textEl.style.backgroundColor = 'red';
})
player.addEventListener('amp-story-back', () => {
textEl.style.backgroundColor = 'green';
})