Skip to content

Show your first Story row#

This quickstart shows one row of published Stories on a web page. You add a container, initialize the SDK, create the row, and check that Stories loaded. Before you start lists what you need.

Install the SDK#

Install the SDK with one of these guides, then return to this page:

The steps below use the SDK as Storyteller. The samples use await, which works only in JavaScript modules and inside async functions. In a classic <script>, wrap the code in an async function, as shown in Handle initialization errors.

Add a container#

<div id="storyteller-stories-row" style="height: 200px"></div>

The row sizes its tiles to the container's height, so set a height on the container. If the container has no height, the SDK uses a default tile height (160 px for square tiles, 120 px or 140 px for round tiles). When logging is enabled, it also logs a warning.

Warning

The container ID must be unique on the page and follow best practices for HTML IDs. Use only ASCII letters, numbers, dashes (-), and underscores (_).

Initialize Storyteller#

Call initialize with your API key, and wait for it to resolve before you create a view:

await Storyteller.sharedInstance.initialize('demo-api-key');

Replace demo-api-key with your API key. If the user is signed in, pass your user ID as externalId. With the default privacy options, the user's viewing history then follows them across browsers and devices:

await Storyteller.sharedInstance.initialize('demo-api-key', {
  externalId: 'your-user-id',
});

Identify and personalize users explains user IDs and how to change the user.

Create the row#

const storyRow = new Storyteller.StorytellerStoriesRowView(
  'storyteller-stories-row'
);

The constructor takes the container ID and an optional list of Category IDs: StorytellerStoriesRowView(containerId: string, categories?: string[]). To show Stories from specific Categories only, pass their IDs:

const filteredStoryRow = new Storyteller.StorytellerStoriesRowView(
  'storyteller-stories-row',
  ['category-id']
);

Choose a view lists the grid and Clips views. The Storyteller Web Showcase creates a row with the same StorytellerStoriesRowView constructor.

Handle initialization errors#

initialize returns a promise that rejects when the SDK can't start. Catch the error and show a fallback in your page. Without top-level await, use an async function:

async function initializeStoryteller() {
  try {
    await Storyteller.sharedInstance.initialize('demo-api-key');
    // Create Storyteller views here.
  } catch (error) {
    console.error('Storyteller could not start.', error);
  }
}

initializeStoryteller();

You can also handle the promise directly:

Storyteller.sharedInstance
  .initialize('demo-api-key')
  .then(() => {
    // Create Storyteller views here.
  })
  .catch((error) => {
    console.error('Storyteller could not start.', error);
  });

The promise rejects with an Error whose message starts with the error type, for example InvalidApiKeyError - The API Key provided was invalid. The SDK doesn't export these error classes, and error.name is always "Error", so check the start of the message, for example error.message.startsWith('InvalidApiKeyError'):

  • InvalidApiKeyError: Storyteller rejected the API key (HTTP 401 or 404)
  • NetworkTimeoutError: a request timed out
  • NetworkError: a request failed, or returned an empty or malformed response

These errors come from the settings request. With the default privacy options, initialize also requests the user's viewing history (GET /api/UserActivity/{userId}) and waits for it. If that request fails, initialize rejects with one of the same errors.

If you call initialize without an API key, the promise rejects with a text message instead of an Error.

Earlier guides also listed InitializationError and JsonParseError. The SDK reports those cases as NetworkError.

Check the result#

A horizontal row of Story tiles appears. Selecting a tile opens the Story player.

To see whether the row loaded, set a delegate on the row with an onDataLoadComplete callback:

storyRow.delegate = {
  onDataLoadComplete: (success, error, dataCount) => {
    if (success) {
      console.log(`Loaded ${dataCount} Stories.`);
    } else {
      console.error('Stories could not load.', error?.message);
    }
  },
};

success is false when the request fails or returns no Stories. When no Stories are returned, error.message starts with EmptyResponseError.

What you see What to check
initialize rejects Check the API key and the error message. See Handle initialization errors.
success is false and error.message starts with EmptyResponseError The request worked but returned no Stories. Check the Category IDs, and check that the Stories are published in the same tenant as the API key.
success is false with another error Find the failed request in the browser Network panel, and check its HTTP status.
success is true, but no tiles show Check the container's height and width, and check for page CSS that hides it.

Troubleshoot an integration covers more problems.

Next steps#