@gobistories/gobi-web-integration
Version:
This library will let you put your Gobi stories on your site.
695 lines (667 loc) • 23.8 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Gobi Web Integration Readme</title>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css">
<base target="_parent">
<script>
window.addEventListener('load', function () {
window.top.postMessage({
height: document.body.scrollHeight,
}, "*");
});
</script>
<style>
html {
font-size: 16px;
}
body {
font-family: Nunito, sans-serif;
font-size: 0.875rem;
color: #001c38;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 20px;
margin-bottom: 10px;
font-family: 'Lineto circular pro', sans-serif;
}
h1 {
font-size: 38px;
line-height: 44px;
font-weight: 700;
}
h2 {
font-size: 32px;
line-height: 36px;
font-weight: 700;
}
a {
color: #2ba6fc;
text-decoration: none;
}
tr {
text-align: left;
}
td,
th {
padding: 7px;
border: 1px solid #001c3817;
}
td code {
white-space: nowrap;
}
pre {
width: min-content;
border-radius: 5px;
}
@font-face {
font-family: 'Nunito';
src: url('https://uploads-ssl.webflow.com/606f59e162caa70af6365471/606f6512884094dadc4ee18f_Nunito-ExtraBold.ttf') format('truetype');
font-weight: 800;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Nunito';
src: url('https://uploads-ssl.webflow.com/606f59e162caa70af6365471/606f65122db596ff7b467fba_Nunito-Black.ttf') format('truetype');
font-weight: 900;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Nunito';
src: url('https://uploads-ssl.webflow.com/606f59e162caa70af6365471/606f65128840943d9e4ee18e_Nunito-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Nunito';
src: url('https://uploads-ssl.webflow.com/606f59e162caa70af6365471/606f6512ad2674216cdb2e7e_Nunito-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Nunito';
src: url('https://uploads-ssl.webflow.com/606f59e162caa70af6365471/606f65122db5963587467fbb_Nunito-ExtraLight.ttf') format('truetype');
font-weight: 200;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Nunito';
src: url('https://uploads-ssl.webflow.com/606f59e162caa70af6365471/606f65126543e443255c9e16_Nunito-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Nunito';
src: url('https://uploads-ssl.webflow.com/606f59e162caa70af6365471/606f65120a9f8b91984d4f31_Nunito-Light.ttf') format('truetype');
font-weight: 300;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Gt super display';
src: url('https://uploads-ssl.webflow.com/606f59e162caa70af6365471/606f65517d1c1d3d934e2cfc_GT-Super-Display-Light.ttf') format('truetype');
font-weight: 300;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Gt super display';
src: url('https://uploads-ssl.webflow.com/606f59e162caa70af6365471/606f6551d077567eed26663f_GT-Super-Display-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Lineto circular pro';
src: url('https://uploads-ssl.webflow.com/606f59e162caa70af6365471/6078727daa14d4f169dfec0e_lineto-circular-pro-book.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Lineto circular pro';
src: url('https://uploads-ssl.webflow.com/606f59e162caa70af6365471/6078727d16c3356c325cce38_lineto-circular-pro-bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
</style>
</head>
<body>
<div>
<h1 id="gobi-web-integration">Gobi Web Integration</h1>
<p>Welcome to Gobi Web Integration. This library will let you put your Gobi stories on your site. If you don't have any
Gobi Stories yet sign up in our <a href="https://studio.gobistories.com/">Story Manager</a> to get access to our production tools.</p>
<h2 id="story-bubbles-demo">Story Bubbles Demo</h2>
<p>To easily test the most used options, go to the code snippet editor in our <a href="https://studio.gobistories.com/">Story Manager</a>.</p>
<h2 id="troubleshooting--faq">Troubleshooting & FAQ</h2>
<h4 id="bubbles-dont-show">Bubbles don't show</h4>
<p>See the console. Can you spot any errors? Try to understand them. If there seems to be a bug in the library, please
email us.</p>
<h4 id="vidoes-or-thumbnails-dont-play-and-i-see-content-security-policy-errors">Vidoes or thumbnails don't play and I see Content Security Policy errors</h4>
<p>You may see an error similar to:</p>
<pre><code>Refused to load media from 'https://res.cloudinary.com/gobi-technologies-as/...' because it violates the following
Content Security Policy directive: ...</code></pre>
<p>If so, you need to update your <code>Content-Security-Policy</code> HTTP headers to include <code>blob:</code> and the sources that we use.</p>
<p>Sources used by our library are:</p>
<ul>
<li><a href="https://api.gobistories.com/">https://api.gobistories.com/</a></li>
<li><a href="https://widget.gobistories.com/">https://widget.gobistories.com/</a></li>
<li><a href="https://res.cloudinary.com/gobi-technologies-as/">https://res.cloudinary.com/gobi-technologies-as/</a></li>
</ul>
<p>Example using the fallback <code>default-src</code>:</p>
<pre><code>default-src 'self' blob: <your other sources> https://widget.gobistories.com https://api.gobistories.com https://res.cloudinary.com/gobi-technologies-as/;</code></pre>
<p>Example using stricter fetch directives:</p>
<pre><code>script-src 'self': <your other sources> https://widget.gobistories.com/;
connect-src 'self': <your other sources> https://api.gobistories.com/;
media-src 'self' blob: <your other sources> https://res.cloudinary.com/gobi-technologies-as/;
img-src 'self' blob: <your other sources> https://res.cloudinary.com/gobi-technologies-as/;</code></pre>
<h4 id="my-page-scrolls-when-opening-a-story">My page scrolls when opening a story</h4>
<p>If your page scrolls to the top when opening a story, this is usually caused by the height styling for the HTML tag of
your page. Removing or replaceing this with <code>min-height</code> usally solves the problem.</p>
<h2 id="technical-documentation">Technical Documentation</h2>
<h3 id="story-bubbles">Story Bubbles</h3>
<p>Adding bubbles to your pages and content requires three steps:</p>
<ol>
<li>Load our script</li>
<li>Add a placeholder element where you want the bubbles</li>
<li>Call our code to create the bubbles</li>
</ol>
<p>You can generate the required code within our <a href="https://studio.gobistories.com/">Story Manager</a>, or refer to the
documentation below.</p>
<h4 id="adding-bubbles-with-gobidiscover"><strong>Adding bubbles with Gobi.discover()</strong></h4>
<p>This is the recommended way to add story bubbles to your page. Add your placeholder where you want the bubble to
appear, add the <code>gobi-stories</code> class and specify options using data attributes:</p>
<pre><code class="html language-html"><div
class="gobi-stories"
data-gobi-stories="story-id another-story-id"
data-gobi-kebab-cased-option="value"
data-gobi-some-other-kebab-cased-option="value"
></div></code></pre>
<p>If you would like to configure titles or thumbnail urls per story, then you can add them as child elements:</p>
<pre><code class="html language-html"><div class="gobi-stories" data-gobi-kebab-cased-option="value" data-gobi-some-other-kebab-cased-option="value">
<div data-gobi-story="story-id" data-gobi-title="About Us"></div>
<div data-gobi-story="another-story-id" data-gobi-title="Our Product" data-gobi-thumbnail-url="..."></div>
</div></code></pre>
<p>Note that you can add new lines to title by using a new line in the HTML, or by adding <code>\n</code> with the title itself.</p>
<p>See the <strong>Bubble Options</strong> section for available options. Note that options should be converted to <em>kebab case</em> and
prefixed with <code>data-gobi-</code>.</p>
<p>You can then load our script and run <code>gobi.discover()</code>:</p>
<pre><code class="html language-html"><head>
<script src="https://widget.gobistories.com/gwi/6" async onload="gobi.discover()"></script>
</head></code></pre>
<p>You can pass global options to discover() that will be used for all bubbles on the page as defaults.
See <strong>Bubble Options</strong> for more information:</p>
<pre><code class="js language-js">gobi.discover({
bubbleSize: '120px',
color: 'blue',
});</code></pre>
<p>The global options will be used when they are not overridden by individual embed options.</p>
<h4 id="adding-bubbles-with-an-inline-script"><strong>Adding bubbles with an inline script</strong></h4>
<p>Another way to add Gobi stories to your page is by using inline javascript.</p>
<pre><code class="html language-html"><head>
<script src="https://widget.gobistories.com/gwi/6"></script>
</head>
<body>
<div id="container"></div>
<script>
new gobi.Bubbles({
container: '#container',
stories: [
{
id: 'story-key',
title: 'Some Title',
},
{
id: 'another-story-key',
title: 'Some Another Title',
},
],
});
</script>
</body></code></pre>
<h3 id="creating-a-standalone-player">Creating a standalone player</h3>
<p>You can also show story player directly in the page without using bubbles.</p>
<pre><code class="html language-html"><head>
<script src="https://widget.gobistories.com/gwi/6"></script>
</head>
<body>
<div id="container"></div>
<script>
new gobi.Player({
container: '#player-container',
storyId: 'story-key',
on: {
videoPlay: function() {
console.log('played the video!');
},
},
});
</script>
</body></code></pre>
<p>See <strong>Player Options</strong> for details.</p>
<h4 id="installing-as-a-package">Installing as a Package</h4>
<p><a href="https://badge.fury.io/js/%40gobistories%2Fgobi-web-integration"><img src="https://badge.fury.io/js/%40gobistories%2Fgobi-web-integration.svg" alt="npm version" /></a></p>
<p>Developers may prefer to install Gobi Web Integration as a package dependency:</p>
<pre><code class="sh language-sh">npm install --save @gobistories/gobi-web-integration</code></pre>
<pre><code class="js language-js">import { Bubbles } from '@gobistories/gobi-web-integration';
// Create bubbles
new Bubbles({
container: '#container',
bubbleSize: '200px',
});
// Create a Player
new Player({
container: '#container',
storyName: 'story-id',
playerOptions: {
on: {
videoPlay: function() {
console.log('played the video!');
},
},
},
});</code></pre>
<h3 id="browser-support">Browser Support</h3>
<p>The library will work well in Chrome, Firefox, Safari, and Opera. The library lets users in IE view the story, but UX
and functionality might be a bit limited compared to modern browsers.</p>
<h3 id="embed-options">Embed Options</h3>
<table>
<thead>
<tr>
<th>option</th>
<th>default</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>container</td>
<td><code>#gobi-here</code></td>
<td><strong>Required for inline javascript.</strong> String. Query Selector for HTMLElement. Container where the module will be embed.</td>
</tr>
<tr>
<td>color</td>
<td><code>#15d6ea</code></td>
<td>Any valid css color value (#000, rgb(…), rgba(…)). The color of the border around the story bubble.</td>
</tr>
<tr>
<td>bubbleSize</td>
<td><code>96px</code></td>
<td>Valid css size value, except % (10px, 10vw…). The size of the avatar aka bubble.</td>
</tr>
<tr>
<td>hideTitle</td>
<td><code>false</code></td>
<td>Boolean. Hides the bubble title if true (default false)</td>
</tr>
<tr>
<td>animatedBubble</td>
<td><code>false</code></td>
<td>Boolean. Makes the bubbles as gif animation.</td>
</tr>
<tr>
<td>wrap</td>
<td><code>false</code></td>
<td>Boolean. Add styles which allow a horizontal series of bubbles to wrap to new lines, when the screen is narrow.</td>
</tr>
<tr>
<td>scroll</td>
<td><code>true</code></td>
<td>Boolean. Show a scroll bar when stories do not fit in the page or parent container.</td>
</tr>
<tr>
<td>isFullHeightMobile</td>
<td><code>true</code></td>
<td>Boolean. Add styles which allow making a full-screen popup. It's work only on mobile phone</td>
</tr>
<tr>
<td>showPlayIcon</td>
<td><code>false</code></td>
<td>Boolean. Add Play icon inside the bubbles</td>
</tr>
<tr>
<td>playIconUrl</td>
<td>undefined</td>
<td>Optional string, will show the given icon in the play bubble.</td>
</tr>
<tr>
<td>align</td>
<td><code>center</code></td>
<td>String. Valid values 'left', 'right', 'end', 'start', 'center' . It sets alignment for bubbles horizontally</td>
</tr>
<tr>
<td>autoSegue</td>
<td><code>false</code></td>
<td>Boolean. Enable or disable the transition to next story in the end</td>
</tr>
<tr>
<td>fullscreenPlayer</td>
<td><code>false</code></td>
<td>Boolean. Set to true to remove all margins from the player when opened in popup mode</td>
</tr>
<tr>
<td>noShade</td>
<td><code>false</code></td>
<td>Boolean. Set to true to not apply a page background shade when the player is opened in popup mode</td>
</tr>
<tr>
<td>titleFontSize</td>
<td><code>12px</code></td>
<td>Valid css size value. By default, a size is selected based on bubbleSize between 12px and 36px.</td>
</tr>
<tr>
<td>titleFontColor</td>
<td><code>black</code></td>
<td>Any valid css color value (#000, rgb(…), rgba(…)). The color of the bubble title text.</td>
</tr>
<tr>
<td>titleFontFamily</td>
<td>undefined</td>
<td>Valid css font family name. Inherited from the document by default.</td>
</tr>
<tr>
<td>titleFontWeight</td>
<td>undefined</td>
<td>Valid css font weight. Inherited from the document by default.</td>
</tr>
<tr>
<td>inheritTextFontFamily</td>
<td><code>false</code></td>
<td>Boolean. Whether to inherit the font family from the page for bubble titles.</td>
</tr>
<tr>
<td>inheritTextStyles</td>
<td><code>false</code></td>
<td>Boolean. Whether to inherit font family, font size, font weight and color from the page for bubble titles.</td>
</tr>
<tr>
<td>zIndex</td>
<td><code>2000000</code></td>
<td>Number. Sets the priority of the player above other content when open.</td>
</tr>
<tr>
<td>on.loaded</td>
<td><code>function</code></td>
<td>Function. Called when all Bubbles have loaded.</td>
</tr>
<tr>
<td>on.close</td>
<td><code>function</code></td>
<td>Function. Called when all popups are closed.</td>
</tr>
<tr>
<td><strong>stories</strong></td>
<td><code>[]</code></td>
<td><strong>Required for inline javascript.</strong> Array. Data of stories.</td>
</tr>
<tr>
<td>stories[0…n].id</td>
<td></td>
<td><strong>Required.</strong> String. Identifire of story.</td>
</tr>
<tr>
<td>stories[0…n].title</td>
<td></td>
<td>String. Change title text of specific story.</td>
</tr>
<tr>
<td>stories[0…n].thumbnailUrl</td>
<td></td>
<td>String. Overrides the image used for the bubble.</td>
</tr>
<tr>
<td>stories[0…n].bubbleSrc</td>
<td></td>
<td><strong>Deprecated.</strong> Alias of <code>thumbnailUrl</code>.</td>
</tr>
<tr>
<td>playerOptions</td>
<td><code>{}</code></td>
<td>Object. Provides options to the player when opening. See <strong>Player Options</strong> for details.</td>
</tr>
</tbody>
</table>
<h2 id="events">Events</h2>
<p><code>on.loaded</code> is called with a controller as it's first parameter. See <strong>Opening Stories Programmatically</strong> for more information.</p>
<h2 id="embedded-player">Embedded player</h2>
<p>Creates a Player and returns an interface for managing it, and for listening to its events.</p>
<h3 id="player-options">Player Options</h3>
<table>
<thead>
<tr>
<th>option</th>
<th>default</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>container</td>
<td></td>
<td>Query Selector for HTMLElement. Container where the player will be inserted.</td>
</tr>
<tr>
<td>storyId</td>
<td></td>
<td><strong>Required.</strong> String. The key of the story.</td>
</tr>
<tr>
<td>autoStart</td>
<td><code>false</code></td>
<td>Boolean. Add <code>autoplay</code> attributes to the video.</td>
</tr>
<tr>
<td>autoStartWithSound</td>
<td><code>false</code></td>
<td>Boolean. Add <code>autoplay</code> attributes to the video, and don't mute the video at the same time.</td>
</tr>
<tr>
<td>loop</td>
<td><code>false</code></td>
<td>Boolean. Add <code>loop</code> function to video.</td>
</tr>
<tr>
<td>roundedCorners</td>
<td><code>true</code></td>
<td>Boolean. Enable or disable rounded corners to player element.</td>
</tr>
<tr>
<td>shadow</td>
<td><code>true</code></td>
<td>Boolean. Enable or disable shadow on the player element.</td>
</tr>
<tr>
<td>width</td>
<td><code>undefined</code></td>
<td>Number. Set player width. If height is not defined it will calculate automaticaly using an aspect ratio of 16:9.</td>
</tr>
<tr>
<td>height</td>
<td><code>undefined</code></td>
<td>Number. Set player height. If width is not defined it will calculate automaticaly using an aspect ratio of 16:9.</td>
</tr>
<tr>
<td>checkViewPort</td>
<td><code>true</code></td>
<td>Boolean. Enable functionality which pause player if it outside of screen view area.</td>
</tr>
<tr>
<td>playButton</td>
<td><code>true</code></td>
<td>Boolean. Enable or disable play button.</td>
</tr>
<tr>
<td>transcriptButton</td>
<td><code>false</code></td>
<td>Boolean. Enable or disable button to download a transcript. Only shown if applicable.</td>
</tr>
<tr>
<td>savePosition</td>
<td><code>true</code></td>
<td>Boolean. Enable or disable save last watched chapter. It needs to confirm policy by user</td>
</tr>
<tr>
<td>useMediaProxy</td>
<td><code>false</code></td>
<td>Boolean. Enable the use of a reverse proxy hosted by Gobi for media content.</td>
</tr>
<tr>
<td><strong>on</strong></td>
<td><code>[]</code></td>
<td>Array. Data of event listener</td>
</tr>
<tr>
<td>on.videoPlay</td>
<td><code>function</code></td>
<td>Called when the video plays.</td>
</tr>
<tr>
<td>on.videoPause</td>
<td><code>function</code></td>
<td>Called when the video pauses.</td>
</tr>
<tr>
<td>on.videoComplete</td>
<td><code>function</code></td>
<td>Called when the video completes.</td>
</tr>
<tr>
<td>on.clickPrevious</td>
<td><code>function</code></td>
<td>Called when changing to the previous chapter.</td>
</tr>
<tr>
<td>on.clickNext</td>
<td><code>function</code></td>
<td>Called when changing to the next chapter.</td>
</tr>
<tr>
<td>on.clipChange</td>
<td><code>function</code></td>
<td>Called when a chapter changes.</td>
</tr>
<tr>
<td>on.newIteration</td>
<td><code>function</code></td>
<td>Called when the story loops back to the beginning (requires loop to be <code>true</code>).</td>
</tr>
<tr>
<td>on.error</td>
<td><code>function</code></td>
<td>Called when an error occurs.</td>
</tr>
<tr>
<td>on.loaded</td>
<td><code>function</code></td>
<td>Called when the video is loaded.</td>
</tr>
</tbody>
</table>
<h4 id="events-1">Events</h4>
<p>All events are called with the relevant chapter index as the first parameter.</p>
<h3 id="methods">Methods</h3>
<p>You can destroy the Gobi Player to free up resources:</p>
<pre><code class="js language-js">var player = new gobi.Player({
container: '#player-container',
storyId: 'story-key',
});
player.destroy();</code></pre>
<h2 id="opening-gobi-stories-programmatically">Opening Gobi Stories Programmatically</h2>
<p>Several functions allow you to open story popups programmatically, either immediately or using a controller passed to a
callback:</p>
<table>
<thead>
<tr>
<th>Function</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>openPopup(id, options)</code></td>
<td>Opens a story immediately without preloading</td>
</tr>
<tr>
<td><code>renderPopups(options, callback)</code></td>
<td>Preloads stories for opening later</td>
</tr>
<tr>
<td><code>renderBubbles(options, callback)</code></td>
<td>Displays bubbles that can be opened later</td>
</tr>
<tr>
<td><code>discover(options, callback)</code></td>
<td>Finds and renders gobi-stories embeds</td>
</tr>
</tbody>
</table>
<p>Options are the same as <strong>Bubble Options</strong>.</p>
<p>The functions <code>renderPopups()</code> and <code>renderBubbles()</code> require a container to be specified in <code>options</code>.
The <code>discover()</code> function required elements in the dom with the class <code>gobi-stories</code> to create bubbles
or <code>gobi-popups</code> to create popups.</p>
<p>The function <code>openPopup()</code> does not require an element to be provided.</p>
<p>The callback's only argument is a controller with the properties:</p>
<table>
<thead>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>storyIds</code></td>
<td><code>string[]</code></td>
<td>An array of loaded story ids</td>
</tr>
<tr>
<td><code>openPopup(id)</code></td>
<td><code>function</code></td>
<td>Opens a popup story player for the given story id</td>
</tr>
</tbody>
</table>
<p>Note: The <code>on.loaded</code> bubble option is also passed a controller as it's first argument.</p>
<p>You can open a popup story player at any time with <code>openPopup()</code>:</p>
<pre><code class="js language-js">gobi.openPopup('story-id');</code></pre>
<blockquote>
<p><strong>Important</strong>: In many browsers playing a video with sound requires at least one user interaction that starts a video
with sound. Therefore <code>openPopup()</code> must either be called by a user interaction event (such as click), or after
this requirement has been met some other way, otherwise the video may fail to start.</p>
</blockquote>
<p>To preload story data and poster images before opening a popup, call <code>renderPopups()</code> and use the controller passed to
the callback to open the story. This may provide a smoother experience, particularly on slower internet connections.</p>
<pre><code class="js language-js">gobi.renderPopups({ stories: [{ id: 'story-id' }] }, controller => {
controller.openPopup('story-id');
});</code></pre>
<p>If you want to show bubbles on your page and want to open them programmatically, you can use renderBubbles to create
the bubbles and get the controller with a callback:</p>
<pre><code class="js language-js">gobi.renderBubbles({ container: '#gobi-container', stories: [{ id: 'story-id' }] }, controller => {
controller.openPopup('story-id');
});</code></pre>
<p>If you are using <code>gobi.discover()</code> to create your bubbles, you can get a controller using the second parameter, and
use it later:</p>
<pre><code class="js language-js">let gobiController;
gobi.discover({}, controller => {
gobiController = controller;
});
// You can now use gobiController to open stories, for example with onClick handlers.</code></pre>
</div>
</body>
</html>