# Storyteller Web SDK Public Docs (AI bundle) Base URL: https://docs.getstoryteller.com/web/ Each block below summarizes one docs page, in navigation order. A block opens with a PAGE marker that names the page slug and closes with a matching end marker. The page is at the block's `URL:` path under the base URL. The full page with code samples is at https://docs.getstoryteller.com/web/ai/llms-SLUG.txt (for example, the `themes` block links to https://docs.getstoryteller.com/web/ai/llms-themes.txt). Release notes are not in this bundle: https://docs.getstoryteller.com/web/ai/llms-changelog.txt. Search index: https://docs.getstoryteller.com/web/search/search_index.json ## Core integration facts (Web SDK 11.0.0) - Script tag: https://content.usestoryteller.com/javascript-sdk/11.0.0/dist/storyteller.min.js exposes the `Storyteller` global and adds its own styles. Use a fixed version, not `latest`. It loads player, Poll, Quiz, and caption code from the same directory; self-hosters deploy all of `dist` with the original file names, and a Content Security Policy must allow that directory. - npm: `import * as Storyteller from '@getstoryteller/storyteller-sdk-javascript'` plus `@getstoryteller/storyteller-sdk-javascript/dist/storyteller.min.css`. Peer dependencies: `@types/react` `>=17 <20`, `@types/react-router-dom` `^5.1.7`. - Await `Storyteller.sharedInstance.initialize(apiKey, { externalId })` before creating views. It rejects with an `Error` whose `message` starts with `InvalidApiKeyError`, `NetworkTimeoutError`, or `NetworkError`; the classes are not exported. With the default privacy options, `initialize` also loads the user's viewing history from Storyteller. - Set `Storyteller.sharedInstance.delegate` before `initialize` to receive `sdkInitialized`. Assigning it replaces all four global callbacks; spread the current delegate to add one. - Assigning `eventTrackingOptions` replaces every option; omitted options return to their defaults. - Each `initialize` call resets `Storyteller.sharedInstance.theme`; set it after `initialize` resolves. - Views render into an existing element by ID and take a plain `configuration` object (TypeScript: `IListConfiguration<'StorytellerStoriesRowView'>`, `Storyteller.UiStyle.dark`). Give row containers a height. Call `destroy()` before removing a container. - `getAdConfig` runs only for Google Ad Manager tenants; Clips ad requests have no `story`. - Showcase code links point to the private repository https://github.com/getstoryteller/storyteller-showcase-web; customers need GitHub access from Storyteller. # Storyteller Web SDK URL: / ## Task Choose the shortest route to a common Storyteller Web SDK task. ## Metadata - Slug: index - Source: public-docs/index.md - Audience: Engineers integrating Storyteller on the web - Platforms: Web - Related: Before You Start, Show Your First Story Row, Choose a View, Troubleshoot an Integration, Migrate from Version 10 to 11, API Reference ## Overview - Leads with the three installation guides: script tag, npm, and React or Next.js. - Links to the Before you start requirements and to access for the private Storyteller Web Showcase source. - Ranks showing the first Story row as the step directly after installing. - Links Story rows and grids, Clips rows, and the Clips player under "Choose what to show". - Groups the other guides under "Appearance and content", "Analytics, callbacks, and ads", and "Help and reference". The last group includes Open a Player Programmatically and the API reference. ## When To Use - Start here when you know the task but do not know which guide owns it. - Share this page with engineers who are new to the Web SDK. ## Cross-References - Before You Start covers requirements, placeholders, installation choices, and Showcase access. - Show Your First Story Row provides the first working integration. - Choose a View compares the supported views. # Before you start URL: /getting-started/ ## Task Check the requirements for a Web SDK integration and choose an installation path. ## Metadata - Slug: getting-started-index - Source: public-docs/getting-started/index.md - Audience: Engineers starting a Storyteller Web integration - Platforms: Web - Related: Script installation, npm installation, React and Next.js, Quickstart ## Overview - Lists what you need: an API key for your tenant, published Stories or Clips in that tenant, a page element for the view, and Showcase access for the linked code examples. - Defines the tenant as your organization's Storyteller account and its content. - Lists the example placeholders: `demo-api-key`, `your-user-id`, `category-id`, and `collection-id`. - Maps each installation path to a build setup: script tag (no build step), npm (a bundler), or React or Next.js (a component renders the container). - Explains how to get access to the private Storyteller Web Showcase repository (`getstoryteller/storyteller-showcase-web`). Showcase links return 404 without access. - Links the first Story row and the configuration guides as next steps. ## When To Use - Start here when choosing an installation method. - Use this page to check basic requirements before debugging setup. - Use the Showcase access section when a Showcase link returns 404. ## Cross-References - Script installation covers CDN setup, self-hosting, and Content Security Policy. - npm installation covers package, stylesheet, and TypeScript setup. - React and Next.js covers one-time initialization and view cleanup. # Install with a script tag URL: /getting-started/script/ ## Task Load a fixed Storyteller browser build from the CDN and show a Story row without npm. ## Metadata - Slug: getting-started-script - Source: public-docs/getting-started/script.md - Audience: Engineers working on sites without an npm build step - Platforms: Web - Related: Quickstart, Troubleshooting, Views, Users ## Overview - Loads the version 11.0.0 script from `https://content.usestoryteller.com/javascript-sdk/11.0.0/dist/storyteller.min.js` before ``, after the container. - Initializes the SDK inside an `async` function and creates a `StorytellerStoriesRowView` in a container with a height. - Shows how to filter the row with Story Category IDs. - Notes that the `/javascript-sdk/latest/` path does not serve production releases. - Explains that the script downloads the Story player, Clips player, Poll, Quiz, and caption files on demand from its own directory. Self-hosters copy every file in `dist` and keep the file names. - Lists Content Security Policy needs: allow the SDK directory in `script-src`. A nonce- or hash-only policy also needs `'strict-dynamic'` or the directory. The AMP Story player loads from `https://stories.usestoryteller.com/amp/`. ## When To Use - Use this path when the site loads JavaScript through script tags. - Use a fixed CDN version for a stable production deployment. - Use the hosting and Content Security Policy sections when player files fail to load. ## API Cheat Sheet - `window.Storyteller`: Browser global created by the CDN script. - `sharedInstance.initialize(apiKey)`: Initializes the SDK before view creation. - `StorytellerStoriesRowView(containerId, categories?)`: Creates a Story row. # Install from npm URL: /getting-started/npm/ ## Task Install the Web SDK package, import its stylesheet, and create a Story row. ## Metadata - Slug: getting-started-npm - Source: public-docs/getting-started/npm.md - Audience: Engineers using a JavaScript bundler - Platforms: Web - Related: Quickstart, React and Next.js, Configure Views, API Reference ## Overview - Installs `@getstoryteller/storyteller-sdk-javascript` from npm. - Lists the TypeScript peer dependencies: `@types/react` `>=17 <20` and `@types/react-router-dom` `^5.1.7`. - Uses a namespace import and imports the required `dist/storyteller.min.css` export. - Limits imports to the package root and the stylesheet path. Version 11 no longer ships `index.js`, `types/*.d.ts`, or SDK source files. - Notes that a default import works only in ES module builds. CommonJS builds, including Jest, use `import * as Storyteller`. - Notes that the npm file includes the player, Poll, Quiz, and caption code, and the bundler decides how it loads. - Shows the CommonJS `require` path for browser bundles with a CSS loader. Node.js can load the entry for server rendering, but views work only in the browser. - Initializes the SDK, creates a Story row in a container with a height, and calls `destroy()` before the host application removes the container. ## When To Use - Use this path when the application bundles JavaScript and CSS imports. - Use the TypeScript section when npm reports a peer dependency conflict. - Use the CommonJS example only when the browser bundler handles the stylesheet `require`. ## API Cheat Sheet - `Storyteller.sharedInstance.initialize(apiKey)`: Initializes the SDK. - `new Storyteller.StorytellerStoriesRowView(containerId)`: Creates a Story row. - `storyRow.destroy()`: Releases the view before container removal. # Use React or Next.js URL: /getting-started/react-nextjs/ ## Task Initialize the SDK once and own one Storyteller view in a React or Next.js Client Component. ## Metadata - Slug: getting-started-react-nextjs - Source: public-docs/getting-started/react-nextjs.md - Audience: React and Next.js engineers - Platforms: Web - Related: npm installation, StorytellerRowView, Users, Themes ## Overview - Adds a module-level `startStoryteller()` helper that calls `initialize` once, shares its promise, and clears it when `initialize` rejects. - Explains that each `initialize` call resets the global theme, so the global theme is set after `initialize` resolves. - Creates a Story row after `startStoryteller()` resolves and destroys it during effect cleanup. - Explains why React Strict Mode's double effects still create one view and initialize the SDK once. - Places the npm stylesheet in the Next.js root layout. - Keeps the Next.js view in a Client Component marked `'use client'`. ## When To Use - Use this guide when React owns the Storyteller container lifecycle. - Use the Next.js section for an App Router project. ## Pitfalls / Notes - Give each view that is on the page at the same time a unique container ID. - Set the global theme after `initialize` resolves, and again after a user change. - Call `initialize` again when the signed-in user changes. # Show your first Story row URL: /Quickstart/ ## Task Initialize the Web SDK, create the first Story row, and confirm that Stories loaded. ## Metadata - Slug: quickstart - Source: public-docs/Quickstart.md - Audience: Engineers completing their first Web SDK integration - Platforms: Web - Related: Before You Start, Script installation, npm installation, React and Next.js, Users, Troubleshooting ## Overview - Routes the customer to a separate installation guide. The samples use `await`, which needs a JavaScript module or an `async` function. - Adds a unique container with a height. Without a height, the SDK uses a default tile height. Container IDs use ASCII letters, numbers, dashes, and underscores. - Initializes the SDK with an API key and an optional `externalId`. - Creates a `StorytellerStoriesRowView` with optional Category IDs. - Shows the `async` function and promise forms of initialization error handling. - Lists initialization errors by message prefix: `InvalidApiKeyError`, `NetworkTimeoutError`, and `NetworkError`. The classes are not exported. Errors can come from the settings or viewing-history request. A missing API key rejects with a text message. - Confirms the result with an `onDataLoadComplete` delegate and a table of results and checks. ## When To Use - Follow this page after the SDK is available in the application. - Use it as the smallest check that initialization and Story content work. ## API Cheat Sheet - `sharedInstance.initialize(apiKey, { externalId }?)`: Initializes the SDK. - `StorytellerStoriesRowView(containerId, categories?)`: Creates a Story row. - `storyRow.delegate = { onDataLoadComplete }`: Reports `success`, `error`, and `dataCount` for the row's load. # Troubleshoot an integration URL: /getting-started/troubleshooting/ ## Task Find the earliest failed step in a Web SDK integration. ## Metadata - Slug: getting-started-troubleshooting - Source: public-docs/getting-started/troubleshooting.md - Audience: Engineers diagnosing Web SDK setup or playback - Platforms: Web - Related: Script installation, npm installation, Quickstart, Delegates, Themes, Ads ## Overview - Starts with a symptom table that maps each symptom to a numbered step. - Checks SDK loading before initialization or view behavior. - Maps initialization errors to checks by the start of `error.message`, because the error classes are not exported. Includes the viewing-history request (`GET /api/UserActivity/{userId}`) and the text rejection for a missing API key. - Lists common causes of an empty row or grid. An omitted Story category selects the default Home list; check publication there. `EmptyResponseError` means the request returned no content. - Covers script-build player files, self-hosting, Content Security Policy, and single-page application cleanup. - Covers global delegate replacement, view delegate timing, and tracking options for callbacks and analytics. - Covers theme precedence, the global theme reset on each `initialize` call, and remote theme values. - Covers Google Ad Manager `getAdConfig` requirements, including Clip ad requests that have no `story` field. - Defines the safe evidence to send to Storyteller Support. ## When To Use - Use this guide when setup, content loading, playback, callbacks, themes, or ads fail. ## Pitfalls / Notes - Remove API keys, user IDs, tenant data, and targeting values from evidence. - Record the first failed request instead of a later secondary error. - Match initialization errors by the `error.message` prefix, not `instanceof` or `error.name`. # Migrate from version 10 to 11 URL: /getting-started/migrate-to-11/ ## Task Update a Web SDK 10.13.x integration to version 11.0.0 and apply its breaking changes. ## Metadata - Slug: getting-started-migrate-to-11 - Source: public-docs/getting-started/migrate-to-11.md - Audience: Engineers upgrading an existing Web SDK integration - Platforms: Web - Related: npm installation, script installation, Privacy and Tracking, Troubleshooting, Changelog ## Overview - Records the current installation, hosting, views, configuration, and any proxy, allowlist, or Content Security Policy before the update. - Lists the 10.13 entry points that version 11 keeps. - Breaking changes: `initialize` loads viewing history from Storyteller (`GET /api/UserActivity/*`) and rejects when that request fails; read state recorded by 10.13 carries over with default privacy options, and turning off personalization does not stop the history request; Clips requests use `/api/app/clips/{collection}/clips/paged/fresh` and the `x-storyteller-recent-viewed-clip-ids` header. - Breaking changes: five renamed local storage keys that the SDK does not read or remove; history saved by 10.13 does not carry over with `enableRemoteViewingStore: false`. - Breaking changes: the script build loads player, Poll, Quiz, and caption files from its own directory, so self-hosted SDK files and Content Security Policies need updates. - Breaking changes: npm peer dependencies (`@types/react` `>=17 <20`, `@types/react-router-dom` `^5.1.7`), new entry points, removed package files, and the default-import note for CommonJS and Jest. - Breaking changes: no `reflect-metadata` polyfill, the new `ActivityType.sdkInitialized` member, new `Story` chip properties, and the removed `QuizRenderer.clearQuizData()`. - Behavior changes: on-demand loading (script tag only), AMP player preload, Story ordering, Clips paging and `dataCount`, Clip details, Story chips, compact Clip action buttons, like and share counts, caption defaults, Stories with no Pages, and the `sdkInitialized` event. - Gives npm and script update steps, the `latest` URL replacement, a test list, a rollback path, and where to get help. ## When To Use - Use this page when moving a 10.13.x application to 11.0.0. ## Pitfalls / Notes - Keep a `catch` on every `initialize` call; a failed viewing-history request now rejects it. - Self-hosted script integrations must deploy every file in the version's `dist` directory and keep the file names. - The `/javascript-sdk/latest/` CDN path does not serve production releases; use a fixed version URL. - Keep the previous fixed version available until the version 11 checks pass. # Choose a view URL: /views/ ## Task Choose the Storyteller view that matches the content and layout, then open its guide. ## Metadata - Slug: views-index - Source: public-docs/views/index.md - Audience: Engineers selecting a Storyteller view - Platforms: Web - Related: Add a Story or Clips Row, Add a Story or Clips Grid, Add a Clips Player to a Page, Open a Player Programmatically, Show Polls and Quizzes, Configure Views ## Overview - Defines a view as an SDK object that renders Storyteller content into a page element. - Compares the six views: Stories and Clips rows and grids, `StorytellerClipsPlayerView`, and `StorytellerEmbeddedClipsPlayerView`, with the content source each one takes. - Lists the constructor arguments: `elementId`, optional Stories `categories`, a Clips `collectionId`, or a Clips player `source` (collection ID, `{ clipId }`, or `{ externalId }`); a Clips player constructor throws an `Error` for no source or more than one. - Explains that rows can use round or square tiles through `cellType`, and grids don't use `cellType`. - Separates the two Clips player views: the embedded view shows one Clip, lets the page scroll, and ignores `dismissPlayer`; `StorytellerClipsPlayerView` uses the full layout and locks page scrolling. - Routes custom buttons and links to the `Storyteller.sharedInstance` open methods and the Open a Player Programmatically guide. - Describes Polls and Quizzes as Story Pages shown through a Stories row or grid. ## When To Use - Use this page before choosing a view constructor. - Use it when moving content from a row to a grid or a Clips player view, or when opening a player from your own control. # Add a Story or Clips row URL: /StorytellerRowView/ ## Task Document how to create and configure Story and Clips rows, size the row container, and set the tile shape with `cellType`. ## Metadata - Slug: storyteller-row-view - Source: public-docs/StorytellerRowView.md - Audience: Engineers adding horizontal Storyteller rows - Platforms: Web - Related: Configure Views, Add a Story or Clips Grid, Themes ## Overview - A row shows Story or Clip tiles in one horizontal line; use `StorytellerStoriesRowView` for Stories and `StorytellerClipsRowView` for Clips. - Check `getStoriesCount` or `getClipsCount` first to show a row only when it has content. - The row sizes its tiles to its container's height. Without a container height, the SDK uses a default tile height (160 px square, 120 px or 140 px round) and logs a warning. - JavaScript and TypeScript `configuration` samples show Stories-only fields (`categories`, `cellType`, `preload`) and shared fields (`displayLimit`, `theme`, `uiStyle` with `Storyteller.UiStyle.dark`). - `cellType` is `Storyteller.CellType.square` (default) or `.round`: set it in `configuration` on a Stories row, with `clipsRow.cellType` on a Clips row, or with `data-cell-type="round"` on either container. ## When To Use - Use this page when you add a horizontal row or need round tiles. - Consult it while troubleshooting row height or Clips row tile shape. ## Integration Steps 1. Create a container `
` with a height so tiles have room. 2. Create a `StorytellerStoriesRowView` (optionally with Category IDs) or a `StorytellerClipsRowView` (with a collection ID). 3. Assign a `configuration` object that fits the row type. 4. Set the tile shape with `configuration.cellType` (Stories rows), `clipsRow.cellType` (Clips rows), or `data-cell-type`. ## API Cheat Sheet - `new Storyteller.StorytellerStoriesRowView(containerId: string, categories?: string[])`: Creates a Stories row; accepts Category IDs. - `new Storyteller.StorytellerClipsRowView(containerId: string, collectionId: string)`: Creates a Clips row for one collection. - `row.configuration = { ... }`: Plain object typed `IListConfiguration<'StorytellerStoriesRowView'>` or `IListConfiguration<'StorytellerClipsRowView'>`; Stories rows add `categories`, `cellType`, and `preload`. - `clipsRow.cellType = Storyteller.CellType.round`: The way to make Clips row tiles round in code. ## Examples - JavaScript and TypeScript samples define `customTheme`, use `Storyteller.UiStyle.dark`, and set `cellType` for Stories and Clips rows. - Storyteller Web Showcase links show React components that apply these options. ## Pitfalls / Notes - A container without a height gets the default tile height and a console warning. - `configuration` doesn't accept `cellType` for Clips rows; set it on the view or the container. - There is no `ListConfiguration` class. ## Cross-References - Configure Views covers the settings rows share with every view. - Add a Story or Clips Grid covers grid layouts. - Themes explains the `theme` objects used in the samples. # Add a Story or Clips grid URL: /StorytellerGridView/ ## Task Explain how to create and configure Story and Clips grids, which use the settings shared by every view. ## Metadata - Slug: storyteller-grid-view - Source: public-docs/StorytellerGridView.md - Audience: Engineers building grid-based Storyteller layouts - Platforms: Web - Related: Configure Views, Add a Story or Clips Row, Themes ## Overview - A grid shows Story or Clip tiles in columns; use `StorytellerStoriesGridView` for Stories and `StorytellerClipsGridView` for Clips. - The `lists.grid.columns` theme property sets the number of columns. - Check `getStoriesCount` or `getClipsCount` first to show a grid only when it has content. - Grids accept every setting in Configure Views and don't use `cellType`. - JavaScript and TypeScript samples show Stories-only fields (`categories`, `preload`) and shared fields (`displayLimit`, `theme`, `uiStyle` with `Storyteller.UiStyle.dark`). ## When To Use - Use this page when you need a grid instead of a row. - Use it while setting up Clips grids for a collection or adjusting grid display limits and styling. ## Integration Steps 1. Create a Stories or Clips grid with a container ID and Category IDs (Stories) or a collection ID (Clips). 2. Assign a `configuration` object that fits the grid type. 3. Set `displayLimit`, `theme`, and `uiStyle`, and use Configure Views for the other shared settings. ## API Cheat Sheet - `new Storyteller.StorytellerStoriesGridView(containerId: string, categories?: string[])`: Stories grid constructor. - `new Storyteller.StorytellerClipsGridView(containerId: string, collectionId: string)`: Clips grid constructor. - `grid.configuration = { categories?, displayLimit, preload?, theme, uiStyle }`: Plain object typed `IListConfiguration<'StorytellerStoriesGridView'>` or `IListConfiguration<'StorytellerClipsGridView'>`; Stories grids add `categories` and `preload`. ## Examples - JavaScript and TypeScript samples use `storyGrid` and `clipsGrid` variables, define `customTheme`, and use `Storyteller.UiStyle.dark`. - Storyteller Web Showcase links show grid components that set `basename`, `displayLimit`, themes, and the collection ID. ## Cross-References - Configure Views lists the shared configuration properties. - Add a Story or Clips Row covers horizontal layouts. - Themes covers the theme objects used in these examples. # Add a Clips player to a page URL: /StorytellerEmbeddedClipsPlayerView/ ## Task Add a Clips player view to a page, choose between the two Clips player views, and configure the source, size, and back button. ## Metadata - Slug: storyteller-embedded-clips-player-view - Source: public-docs/StorytellerEmbeddedClipsPlayerView.md - Audience: Engineers placing Clips playback inside a page layout - Platforms: Web - Related: Configure Views, Handle View Callbacks, Themes ## Overview - Compares `StorytellerEmbeddedClipsPlayerView` (one Clip at a time, the page keeps scrolling, `dismissPlayer` doesn't close it) with `StorytellerClipsPlayerView` (full Clips player layout, can show neighboring Clips on wide screens, locks page scrolling, `dismissPlayer` dismisses it). - Both views render into and fill your container, and take a collection ID, `{ clipId }`, or `{ externalId }`; the constructor throws an `Error` for no source or more than one. - A collection ID keeps collection navigation; `{ clipId }` or `{ externalId }` shows one Clip. - The host page sets the player size with CSS, including a `9 / 16` aspect ratio for portrait Clips. - `configuration` can change the source; an invalid source logs an error and keeps the current source. - The Clips player delegate (`IStorytellerClipsPlayerDelegate`) handles the top-level back button with `onTopLevelBackTapped`, or the SDK calls `window.history.back()`; the back button doesn't call `onPlayerDismissed`. ## When To Use - Use this page when Clips should play inside page content, such as a live blog, or in an area set aside for Clips. - Read the source and sizing guidance before mounting or changing a Clip. # Open a player programmatically URL: /OpenPlayer/ ## Task Open a Story or Clips player from your own button, link, or route, close it, and handle content that can't be opened. ## Metadata - Slug: open-player - Source: public-docs/OpenPlayer.md - Audience: Engineers opening Storyteller content from their own controls - Platforms: Web - Related: Use Additional SDK Methods, Configure Views, Integrate Analytics ## Overview - The open methods are on `Storyteller.sharedInstance`, return promises, and should be called after `initialize` resolves. - The SDK opens content in a matching view on the page when that view has player URLs turned on; otherwise it loads the content and opens a default player. It sets the page's hash URL, such as `#stories/story-id`. - Stories open with `openStory`, `openStoryByExternalId`, `openPage`, or `openCategory` (optionally at a Story). - Clips open with `openCollection` (optionally at a `clipId` or Clip `categoryId`, with `Storyteller.OpenedReason.deepLink` as the only accepted reason) or `openClipByExternalId`. - `dismissPlayer(true)` closes the open player but not a `StorytellerEmbeddedClipsPlayerView`. - Rejections can be an `Error` or a string. When `openCategory`'s `storyId` or `openCollection`'s `destination` isn't found, the first Story or Clip opens and the SDK logs a message when logging is on. ## When To Use - Use this page when a custom control, deep link, or route should open Storyteller content. - Use it to plan error handling for IDs that might not exist. ## Cross-References - Use Additional SDK Methods has the full signature of each method. - Configure Views explains `basename` and the hash URL format. - Integrate Analytics covers the events players send when they open. # Show Polls and Quizzes URL: /views/engagement/ ## Task Explain how Poll and Quiz Pages behave inside Stories in the Web SDK. ## Metadata - Slug: views-engagement - Source: public-docs/views/engagement.md - Audience: Engineers checking Story engagement pages - Platforms: Web - Related: Views, Themes, Analytics, Poll Events, Quiz Events ## Overview - Polls and Quizzes are Story Pages that appear inside Stories shown through a Stories row or grid; the Story player handles them with no extra code. - After a user votes, the Poll shows the percentage for each answer, and the results stay visible after the first vote. - Poll and Quiz answers show up to two lines, and longer text is cut off. - Theme settings style the answers, and activity events report votes and Quiz answers. ## When To Use - Use this page when preparing a Story with Poll or Quiz Pages. - Include long answer text in your checks while moving an integration to version 11. ## Cross-References - Themes covers Poll and Quiz appearance. - Analytics, Poll Events, and Quiz Events cover callback data. # Configure views URL: /StorytellerListView/ ## Task Describe the settings and methods shared by every Storyteller view: how to create rows, grids, and both Clips player views, configure them through `configuration`, and use behaviors such as Story ordering, Clips paging, Clip details, RTL, hash URLs, reloads, and `destroy`. ## Metadata - Slug: storyteller-list-view - Source: public-docs/StorytellerListView.md - Audience: Engineers wiring Storyteller views inside web layouts - Platforms: Web - Related: Add a Story or Clips Row, Add a Story or Clips Grid, Add a Clips Player to a Page, Open a Player Programmatically, Use Additional SDK Methods ## Overview - Stories rows and grids accept optional Category IDs. Clips rows and grids require a collection ID. - `StorytellerClipsPlayerView` and `StorytellerEmbeddedClipsPlayerView` accept a collection ID, `{ clipId }`, or `{ externalId }`; the constructor throws an `Error` for no source or more than one. - `configuration` is a plain object (typed `IListConfiguration<'ViewClassName'>`, `IStorytellerClipsPlayerConfiguration`, or `IStorytellerEmbeddedClipsPlayerConfiguration`); a partial assignment updates only the fields it contains. - TypeScript samples assume `import * as Storyteller from '@getstoryteller/storyteller-sdk-javascript'` and use `Storyteller.UiStyle.dark`. - Storyteller sets Story ordering in the Stories API response: unread before read, or started-aware groups (not opened, started, finished), with pinned Stories first and Live Stories next. - Collection-backed Clips views load more Clips as the user reaches the end; `reloadData` restarts at the first page, `onDataLoadComplete` reports the first page only, and single-Clip players don't page. - The Clips player shows a Clip's long description in expandable details. - A host `dir="rtl"` applies to Stories rows, Clips rows, and Story players opened from Stories views. - `topLevelBackButtonEnabled` is a direct Clips player property that defaults to `false`. - A view's `context` reaches its activity callbacks, follows child actions, and never enters activity API requests. - `destroy()` (new in 11.0.0) removes the view and its unused player container and stops its callbacks and theme updates. ## When To Use - Use this page whenever you create or reconfigure Storyteller rows, grids, or Clips players. - Reference it when debugging hash routing, RTL rendering, Category or collection updates, per-view theming, refresh behavior, or cleanup on route changes. ## Integration Steps 1. Create a Stories or Clips row or grid with the container ID and `categories` or a collection ID, or create `StorytellerClipsPlayerView` / `StorytellerEmbeddedClipsPlayerView` with a collection ID, `{ clipId }`, or `{ externalId }`. 2. If the host page is RTL, set `dir="rtl"` on the page or the nearest container that wraps the view before rendering it. 3. Assign `view.configuration = { ... }` with only the fields that apply to that view type, typed with `IListConfiguration<'ViewClassName'>`, `IStorytellerClipsPlayerConfiguration`, or `IStorytellerEmbeddedClipsPlayerConfiguration` in TypeScript. 4. Set a custom `basename` when several views on the same page would otherwise derive the same value from their Categories or collection. 5. For Clips players, set exactly one source (`collection`, `clipId`, or `externalId`); if your app should own back navigation, set `topLevelBackButtonEnabled = true` and implement `delegate.onTopLevelBackTapped`. 6. Use `context`, `displayLimit`, `preload`, `theme`, and `uiStyle` to set analytics context, tile counts, loading behavior, and appearance. Keep credentials and personal data out of `context`. 7. Call `reloadData()` when you need fresh Stories or Clips from the API. 8. Call `destroy()` before removing or replacing the view's container. ## API Cheat Sheet - `new Storyteller.StorytellerStoriesRowView(containerId: string, categories?: string[])` / `new Storyteller.StorytellerStoriesGridView(containerId: string, categories?: string[])`: Stories view constructors; `categories` is optional and can be updated through `configuration`. - `new Storyteller.StorytellerClipsRowView(containerId: string, collectionId: string)` / `new Storyteller.StorytellerClipsGridView(containerId: string, collectionId: string)`: Clips view constructors; `collectionId` is required and can later change through `configuration.collection`. - `new Storyteller.StorytellerClipsPlayerView(containerId: string, source: string | { clipId: string } | { externalId: string })`: Clips player in your container; plays a collection or one Clip. - `new Storyteller.StorytellerEmbeddedClipsPlayerView(containerId: string, source: string | { clipId: string } | { externalId: string })`: Clips player for use inside other page content; same sources as `StorytellerClipsPlayerView`. - `IListConfiguration<'...'>` / `IStorytellerClipsPlayerConfiguration` / `IStorytellerEmbeddedClipsPlayerConfiguration`: TypeScript types for `configuration` objects. - `basename`: First hash URL segment; defaults to `stories` or `clips`; optional when only one view is on a page; the SDK keeps only ASCII letters, numbers, dashes (`-`), and underscores (`_`). - `collection` / `clipId` / `externalId`: Clips player sources; set exactly one; an invalid update logs an error and keeps the current source. - `topLevelBackButtonEnabled`: Direct property on both Clips player views; shows the top back button, which calls `delegate.onTopLevelBackTapped` or `window.history.back()`. - `context`: Value returned in `UserActivityData.context` for the view's `onUserActivityOccurred` events while `enableUserActivityTracking` is on. `undefined` omits the field; explicit falsy values stay. - `displayLimit`: Maximum number of tiles the view shows. - `preload`: Stories only; defaults to `false`. Every Stories view starts a low-priority AMP player script download; `true` also prepares the Story player in advance. - `theme`: Per-view `UiTheme` merged over `Storyteller.sharedInstance.theme`; kept when `initialize` runs again. - `uiStyle`: `Storyteller.UiStyle.auto` (default), `.light`, or `.dark` (JavaScript also accepts the strings); can also be set with `data-ui-style` on the container. - `reloadData(): Promise`: Reloads Stories or Clips from the API and calls `onDataLoadStarted` and `onDataLoadComplete`. - `destroy(): void`: Unmounts the view, removes its player container when unused, stops callbacks and theme updates; a second call does nothing. ## Examples - JavaScript and TypeScript `configuration` samples cover Stories rows, Clips rows, `StorytellerClipsPlayerView`, and `StorytellerEmbeddedClipsPlayerView`, each defining `customTheme` and using `Storyteller.UiStyle.dark`. - Context examples show placement fields and replacement through `configuration`. - Hash URL examples use `#basename/story-id` for Stories and `#basename/collection-id/clip-id` for Clips. - Runtime examples update `categories`, `collection`, `clipId`, and `externalId` by reassigning `configuration`, and set `topLevelBackButtonEnabled` directly on the player. - The RTL section shows `dir="rtl"` on a wrapping container before creating a row. ## Pitfalls / Notes - When several views on the same page share the same Categories or collection, set a unique `basename` on each. - `topLevelBackButtonEnabled` is not part of `configuration`; set it on the player instance. - `configuration.cellType` works on `StorytellerStoriesRowView` only; see the row guide for Clips rows. - There is no `ListConfiguration` class; `configuration` takes a plain object. - `openStory`, `openStoryByExternalId`, `openPage`, `openCategory`, `openCollection`, and `openClipByExternalId` live on `Storyteller.sharedInstance`, not on views. ## Cross-References - Add a Story or Clips Row and Add a Story or Clips Grid cover row-specific and grid-specific settings. - Add a Clips Player to a Page compares the two Clips player views. - Handle View Callbacks explains `onDataLoadStarted`, `onDataLoadComplete`, `onPlayerDismissed`, and `onTopLevelBackTapped`. - Open a Player Programmatically and Use Additional SDK Methods document the `open*` methods. - Customize Themes covers the `UiTheme` objects referenced here. # Identify and personalize users URL: /Users/ ## Task Explain how the Storyteller Web SDK assigns user IDs, accepts your own `externalId`, loads viewing history, changes users, and manages user attributes and the Clips locale. ## Metadata - Slug: users - Source: public-docs/Users.md - Audience: Engineers managing authentication, personalization, or consent flows - Platforms: Web - Related: Show your first Story row, Control privacy and tracking, Customize themes ## Overview - By default, the SDK creates an anonymous user ID, stores it in local storage, and uses it to track read Pages, Poll votes, Quiz answers, and Clip likes and views. - `initialize('demo-api-key', { externalId: 'your-user-id' })` supplies your own ID. With the default privacy options, `initialize` loads the viewing history Storyteller saved for that ID, so it follows the user across browsers and devices. - The `externalId` should be unique and stable (not an email address). The SDK hashes it for Video Privacy Protection Act (VPPA) compliance. - To change users, call `initialize` again with the new `externalId`, or `null` for an anonymous user. A call without `externalId` keeps the current ID. - A user ID change clears stored user attributes and the previous user's read status, likes, and answers, then loads the new user's history (empty for `null`). Every `initialize` call also resets `Storyteller.sharedInstance.theme`. - `Storyteller.User.setUserAttribute`, `removeUserAttribute`, and `setLocale` manage personalization and targeting attributes. ## When To Use - Reference this page when connecting Storyteller to an account system or audience targeting strategy. - Follow it whenever your site supports sign-in, sign-out, attribute changes, or language changes that must reach the SDK. ## Integration Steps 1. Initialize with `demo-api-key` only if anonymous tracking is enough; the SDK creates and stores an ID. 2. Pass `{ externalId: 'your-user-id' }` as soon as you know the ID, for example on page load or sign-in. 3. On sign-out or user switch, call `initialize` again with the new `externalId` or `null`, then set the global theme again after it resolves. 4. Call `Storyteller.User.setUserAttribute(key, value)` after `initialize` resolves; use `removeUserAttribute(key)` to clear attributes when a user signs out without a new `initialize` call. 5. Call `Storyteller.User.setLocale('es')` (or another code) to set the Clips language. ## API Cheat Sheet - `Storyteller.sharedInstance.initialize(apiKey, { externalId })`: Sets your user ID; call again to change users, or pass `null` for an anonymous user. - `Storyteller.User.setUserAttribute(key: string, value: string)`: Adds or updates an attribute; throws on an empty key or value; not stored when `enablePersonalization` is `false`. - `Storyteller.User.removeUserAttribute(key: string)`: Removes an attribute. - `Storyteller.User.setLocale(languageCode: string)`: Stores the Clips language as the `stLocale` user attribute. ## Examples - Initialization snippets show the default anonymous ID and `{ externalId: 'your-user-id' }`. - `onSignIn` and `onSignOut` helpers call `initialize` with a user ID and with `null`. - Attribute helpers show `setUserAttribute('location', 'New York')` and `removeUserAttribute('location')`. - The locale example sets Clips to Spanish with `setLocale('es')`. - The Storyteller Web Showcase `persistUserIdAndReload` and `persistAndApplyAttributeValues` helpers show user ID and attribute handling. ## Pitfalls / Notes - A user ID change clears stored attributes, so set attributes after `initialize` resolves. - Omitting `externalId` on a later call does not sign the user out; pass `null`. - Each `initialize` call resets the global theme; a theme set in a view's `configuration` is kept. - Attribute keys and values must be non-empty strings. ## Cross-References - Control privacy and tracking lists the local storage items and the options that control viewing history and personalization. - Show your first Story row shows where to place the initialization call. # Control privacy and tracking URL: /PrivacyAndTracking/ ## Task Document how `eventTrackingOptions` controls Storyteller analytics, ad tracking, local storage, personalization, remote viewing history, and VPPA-friendly modes, so a site can apply its users' consent choices. ## Metadata - Slug: privacy-and-tracking - Source: public-docs/PrivacyAndTracking.md - Audience: Privacy/compliance engineers configuring Storyteller behavior - Platforms: Web - Related: Identify and personalize users, Integrate analytics, Migrate from version 10 to 11 ## Overview - `Storyteller.sharedInstance.eventTrackingOptions` controls which analytics, storage, personalization, and ad-related features stay enabled. Set it before `initialize` so startup follows the options; it can be reassigned at any time. - The JavaScript tab passes string values (`disabledFunctionalFeatures: ['all']`). The TypeScript tab imports `StorytellerTrackedFunctionalFeature` and the `StorytellerEventTrackingOptions` type from the npm package; the enum is not on the CDN `Storyteller` global. - Defaults: `disabledFunctionalFeatures` is `[]` and every other option is `true`. Each assignment replaces all options, so an omitted option returns to its default. - `disabledFunctionalFeatures` can disable `clipLikes`, `clipShares`, `clipViewedStatus`, `pageReadStatus`, `pollVotes`, `triviaQuizAnswers`, or everything with `all`. - The page documents `enableAdTracking`, `enableFullVideoAnalytics`, `enableFunctionalCookies`, `enablePersonalization`, `enableRemoteViewingStore`, `enableStorytellerTracking`, and `enableUserActivityTracking`. - A local storage table lists every item the SDK writes, whether it is user data, and whether it is always stored. A second table lists the five items renamed in 11.0. - With `enableRemoteViewingStore` on (the default), `initialize` loads the user's viewing history from Storyteller and the SDK keeps it out of local storage. - The `sdkInitialized` startup event sends page, viewport, device, operating system, and tracking-option data to Storyteller when Storyteller analytics are on. - The Storyteller Web Showcase `persistAndApplyAttributeValues` helper shows user attributes feeding personalization. ## When To Use - Use this page when implementing consent flows, privacy defaults, or VPPA-related behavior. - Reference it whenever you need to know which SDK features or local storage items a privacy option affects. ## Integration Steps 1. Build a complete `eventTrackingOptions` object with the privacy choices you want to apply, and set it before `initialize`. 2. Set `disabledFunctionalFeatures` to disable specific functional tracking such as likes, shares, read status, Poll votes, or Quiz answers. Use string values in script-tag code. 3. Pass every option on each assignment; omitted options return to `true` (or `[]`). 4. Reassign `Storyteller.sharedInstance.eventTrackingOptions` whenever consent changes. 5. Review the local storage table and the 11.0 key renames before finalizing privacy disclosures or consent-manager cookie lists. ## API Cheat Sheet - `Storyteller.sharedInstance.eventTrackingOptions = { ... }`: Central privacy and tracking configuration; each assignment replaces all options. - `disabledFunctionalFeatures`: Array of `StorytellerTrackedFunctionalFeature` values: `all`, `clipLikes`, `clipShares`, `clipViewedStatus`, `pageReadStatus`, `pollVotes`, `triviaQuizAnswers`. `clipViewedStatus` also stops sending recently viewed Clip IDs with Clips requests. - `enableAdTracking = false`: Stops ad events to Storyteller analytics and `onUserActivityOccurred`, and leaves current Story or Clip information and the `getAdConfig` `publisherProvidedId` out of ad requests. `customTargeting` returned by `getAdConfig` is still sent. - `enableFullVideoAnalytics = false`: Sets `storyId`, `storyTitle`, `storyDisplayTitle`, `clipId`, `clipTitle`, `pageId`, and `pageTitle` to `null` in `onUserActivityOccurred` data. - `enableFunctionalCookies = false`: Turns off read status tracking, user ID storage, Storyteller analytics (except required events), and non-essential local storage; removes stored non-essential items. - `enablePersonalization = false`: Stops sending user IDs and attributes for personalization and removes stored attributes; viewing history still loads through the remote viewing store; always off when `enableFunctionalCookies` is `false`. - `enableRemoteViewingStore = true` (default): `initialize` loads read Pages, Clip likes and views, and Poll and Quiz answers from Storyteller; this also needs functional cookies and personalization, otherwise viewing state lasts only until reload. - `enableRemoteViewingStore = false`: Never stores or sends user IDs; keeps viewing activity in local storage. - `enableStorytellerTracking = false`: Stops Storyteller analytics except `openedPage`, `votedPoll`, `triviaQuizQuestionAnswered`, `openedClip`, `likedClip`, and `unlikedClip`, which are still sent (without a user ID when functional cookies are off) unless their functional feature is disabled. - `enableUserActivityTracking = false`: Stops calls to `onUserActivityOccurred`. - Local storage items: `Storyteller.apiKey`, `Storyteller.captionsEnabled`, `Storyteller.clipShares`, `Storyteller.customInstanceHost`, `Storyteller.environment`, `Storyteller.forceShowShareButton`, `Storyteller.hasShownInstructions`, `Storyteller.likes`, `Storyteller.pollAnswers`, `Storyteller.polls`, `Storyteller.quizAnsweredCorrectlyMap`, `Storyteller.quizzes`, `Storyteller.readPages`, `Storyteller.recentStoryPlaybackMode`, `Storyteller.settings`, `Storyteller.triviaQuizAnswers`, `Storyteller.user`, `Storyteller.userAttributesStorage`, `Storyteller.viewedClips`. Always stored: `apiKey`, `customInstanceHost`, `polls`, `quizAnsweredCorrectlyMap`, `quizzes`, `settings`. - 11.0 renames: `Storyteller.clipLikes` → `Storyteller.likes`, `Storyteller.clipsViewed` → `Storyteller.viewedClips`, `Storyteller.pollAnswerMap` → `Storyteller.pollAnswers`, `Storyteller.quizAnswerMap` → `Storyteller.triviaQuizAnswers`, `Storyteller.storiesReadMap` → `Storyteller.readPages`. Old items are not read or removed. ## Examples - JavaScript and TypeScript examples show the full `eventTrackingOptions` object with every option turned off. - The Storyteller Web Showcase `persistAndApplyAttributeValues` helper shows how user attributes are stored and applied before personalization. ## Pitfalls / Notes - Assigning a partial object resets every omitted option to its default. - `StorytellerTrackedFunctionalFeature` is a type-only export in the CDN build; script-tag code must pass strings. - Disabling functional features affects persistence as well as analytics; users may see likes, shares, votes, answers, or viewed state reset when they revisit content. - `enableFunctionalCookies = false` is the broadest switch because it also turns off personalization, Storyteller analytics, and user ID storage. - The SDK does not remove the 10.13 local storage items; remove them yourself if your consent policy requires it. ## Cross-References - Identify and personalize users explains user IDs, viewing history, and attributes. - Integrate analytics documents `onUserActivityOccurred`, `sdkInitialized`, and `context`. - Migrate from version 10 to 11 covers the renamed local storage keys. # Customize themes URL: /Themes/ ## Task Describe how to build and apply `UiTheme` and `Theme` objects to customize Storyteller colors, typography, layout primitives, player chrome, and Poll and Quiz styling, and how the global, view, and remote themes combine. ## Metadata - Slug: themes - Source: public-docs/Themes.md - Audience: Frontend engineers and designers responsible for Storyteller branding - Platforms: Web - Related: StorytellerListView, StorytellerRowView, StorytellerGridView, PrivacyAndTracking ## Overview - Defines the global theme (`Storyteller.sharedInstance.theme`), a view's theme (`theme` in the view's `configuration`), and the remote theme that Storyteller configures for a tenant or feed. - Shows setting the global theme after `initialize` resolves and setting a view theme with `view.configuration = { theme }`. - Explains precedence: the view theme value, then the global theme value, then the default. The view theme merges over the global theme, and a view value equal to the default does not override the global value. - Explains that every `initialize` call resets the global theme to defaults; a theme in a view's `configuration` is kept. - Explains that the view's `uiStyle` (`light`, `dark`, `auto`) selects the `light` or `dark` `Theme`; `auto` follows `prefers-color-scheme`. - Catalogs theme sections (`colors`, `font`, `primitives`, `lists`, `storyTiles`, `player`, `clipPlayer`, `buttons`, `instructions`, `engagementUnits`) with defaults and data types, and marks `player.icons.share`, `engagementUnits.poll.selectedAnswerBorderImage`, and `engagementUnits.poll.showPercentBarBackground` as not used by the Web SDK. - Documents settings that only the remote theme controls: captions, compact Clip action buttons, and Clip like and share counts, including the version 11.0 caption merge and default changes. ## When To Use - Consult this guide when aligning Storyteller views with brand guidelines or customizing one view. - Refer to it when auditing which theme property controls a UI element (for example Poll answer colors or scroll indicators). - Refer to it when a theme change does not appear: check the `initialize` reset, precedence, and whether the setting belongs to the remote theme. ## Integration Steps 1. Call `initialize` and wait for it to resolve. 2. Create `const theme = new Storyteller.UiTheme({ light: { ... }, dark: { ... } })` or set properties on `theme.light` and `theme.dark`. 3. Assign it with `Storyteller.sharedInstance.theme = theme`. Assign it again after you change a property and after any later `initialize` call. 4. For one view, set `view.configuration = { theme: viewTheme }`. Values that differ from the defaults override the global theme for that view and the player it opens. 5. Adjust base sections (`colors`, `font`, `primitives`) first so dependent properties inherit the values, then fine-tune lists, tiles, players, buttons, instructions, and Polls and Quizzes. 6. Provide custom image URLs for icons or indicators when needed (20 × 20 px action button icons, 48 × 48 px PNG instruction icons). 7. Ask Storyteller to change captions, compact Clip action buttons, or like and share counts in the remote theme. ## API Cheat Sheet - `new Storyteller.UiTheme({ light, dark })`: Creates a theme object with light and dark `Theme` values. - `Storyteller.sharedInstance.theme = myTheme`: Applies the global theme and updates existing views. A later property change has no effect until you assign the theme again. Each `initialize` call resets it to defaults. - `view.configuration = { theme: viewTheme }`: Merges `viewTheme` over the global theme for that view only. - `uiStyle`: `light`, `dark`, or `auto` (follows `prefers-color-scheme`) selects `theme.light` or `theme.dark`. - Enums: `Storyteller.Alignment.start|center|end` (tile title and chip alignment), `Storyteller.ButtonAlignment.left|center|right` (`player.actionButton.alignment`), `Storyteller.TextCase.upper|lower|default` (`buttons.textCase`). - `lists.grid.startInset` and `lists.grid.endInset` (default 16) set the space on the left and right of a grid. `storyTiles.title.fontWeight` (default 700) sets the tile title weight. - `circularTile.liveChip` and `rectangularTile.liveChip` accept `unreadBackgroundGradient` (replaces `unreadBackgroundColor` on unread chips), `readBorderColor`, and `unreadBorderColor` (one-pixel inner border), all default `null`, for Live and pinned chips. Story content supplies `customLiveChipText` and `pinnedChipText`. - `instructions.icons`: object with optional `forward`, `back`, `swipe`, `pause` image URLs (default `{}`). Set it on `theme.light.instructions` and `theme.dark.instructions`. - `clipPlayer.showClipTitle: false`: Hides the Clip title while a supplied long description remains available in expandable details. - Remote `behavior.player.clipsActionButtonCompactSize`: `true` shows compact action buttons in the Clip details area. The default is `false`. Storyteller sets it for the feed. Versions before 11.0 ignored it. - Remote `showLikeCount` and `showShareCount`: a feed value overrides the tenant value, then the default `true`. Versions before 11.0 ignored them. - Captions use the remote `theme.behavior.player.captions` fields. Each valid feed field overrides its tenant field; each padding axis follows the same rule. Defaults: system font stack, 16 px text, natural line height, `#FFFFFF` text, `#171A25` background at 0.65 opacity, 10 px horizontal and 4 px vertical padding, and 8 px corner radius. Zero padding and radius are supported. Each rendered line has its own background with a 2 px gap, and alignment follows LTR or RTL. Versions before 11.0 used the feed caption settings as one object, with 18 px text, a 22 px line height, and a `#000000` background. - With captions enabled for the content type, the CC button stays available on Clips and supported Story Pages regardless of track presence, loading, or failure. A missing or unavailable track does not interrupt playback. Ads and Poll or Quiz Pages hide the control. Live Clips show the CC button but no caption text. The user's choice applies to Clips and Stories and is stored in the browser only when functional cookies are allowed. - Clip captions appear after the Clip starts playing and stay visible while paused. Preloaded Clips and Clips not in view hide their captions. Caption text changes as soon as the next cue starts. The Story CC button sits 16 px from the lower-right corner and moves up to 72 px from the bottom on a Page with an action button. - Major theme sections: `colors`, `font`, `primitives`, `lists`, `storyTiles`, `player`, `clipPlayer`, `buttons`, `instructions`, `engagementUnits`. ## Examples - Sets the global theme inside `initialize(...).then(...)`. - Sets a view theme with `configuration = { theme }` to change row tile spacing. - Recolors built-in instruction icons, and replaces them with custom images on both the light and dark themes. - Creates a `UiTheme` with constructor values, changes nested properties, and assigns it globally. ## Pitfalls / Notes - Set the global theme after `initialize` resolves; each `initialize` call, including a user change, resets it. - Assign the theme again after changing its properties. - A view theme value equal to the SDK default does not override the global value. - `UiTheme` can't change remote theme settings (captions, compact Clip action buttons, like and share counts). - Some properties derive defaults from others; changing a base color may also change chips, indicators, or other elements. - Image-based overrides expect direct URLs or data strings; HTML strings are not supported. - `player.icons.share`, `engagementUnits.poll.selectedAnswerBorderImage`, and `engagementUnits.poll.showPercentBarBackground` are not used by the Web SDK. - Future SDK versions may use a property for more elements. ## Cross-References - StorytellerListView (Configure views) documents the `theme` and `uiStyle` configuration options. - StorytellerRowView and StorytellerGridView show where these theme options appear in rows and grids. - Privacy and Tracking explains `enableFunctionalCookies`, which controls whether the caption choice is stored. - The Storyteller Web Showcase builds a static theme in `buildBasicTheme`. # Integrate analytics URL: /Analytics/ ## Task Explain how to receive Storyteller Web SDK activity events through `onUserActivityOccurred`, forward them to an analytics tool, interpret the `sdkInitialized` startup event, add placement `context`, and decode the shared reason enums. ## Metadata - Slug: analytics - Source: public-docs/Analytics.md - Audience: Engineers consuming Storyteller analytics via delegates - Platforms: Web - Related: StorytellerDelegate, Control privacy and tracking, analytics/StoryEvents, analytics/PollEvents, analytics/QuizEvents, analytics/ClipEvents, analytics/AdEvents ## Overview - Set `onUserActivityOccurred` on `Storyteller.sharedInstance.delegate` before `initialize`; the callback receives the event type and data, which you can forward with a generic call such as `analytics.track(type, data)`. - Assigning `delegate` replaces all four global callbacks; define them in one object or spread the current delegate. - The callback runs only when `enableUserActivityTracking` is on; ad events also need `enableAdTracking`; `enableFullVideoAnalytics: false` sets content IDs and titles to `null`. - The Storyteller Web Showcase handles these events in its `onUserActivityOccurred` handler. - Dedicated Story, Poll, Quiz, Clip, and Ad event pages list event names, triggers, and payload fields. - `sdkInitialized` is sent when an `initialize` call gets the settings result: `initializationSucceeded` is `true` on the first success and `false` when the settings request fails. It is not sent for a missing API key, a user ID storage failure, or a failed viewing-history request, and not again after a success. - A field table documents the `sdkInitialized` payload: the effective tracking options, `appId`, `deviceType`, `deviceBrand`, `deviceModel`, `operatingSystem`, `osVersion`, and `screenResolution` (the viewport). - Six Web SDK views accept placement `context`; child actions keep the source placement context. Context stays in the client callback and outside Storyteller analytics API requests. - `OpenedReason` and `DismissedReason` explain why a Story or Clip opened or closed. ## When To Use - Use this page to set up analytics forwarding, handle the startup event, or decode `openedReason` and `dismissedReason` values. - Keep it handy when mapping Storyteller analytics into your own schema. ## Integration Steps 1. Implement `onUserActivityOccurred` on `Storyteller.sharedInstance.delegate` in the same object as your other global callbacks. 2. Set the delegate before `initialize` so the `sdkInitialized` event arrives. 3. Handle startup failures in the `initialize` `catch` block; do not rely on `sdkInitialized` for them. 4. Route each incoming event to the matching detailed event page when mapping fields or troubleshooting. 5. Add optional `context` to a supported view configuration when you need placement attribution, and reassign `configuration` to replace it. 6. Use the `OpenedReason` and `DismissedReason` tables as the shared enum reference across Stories and Clips. ## API Cheat Sheet - `Storyteller.sharedInstance.delegate = { onUserActivityOccurred: (type, data) => { ... } }`: Receives every activity event; the TypeScript type is `IStorytellerDelegate`. - `{ ...Storyteller.sharedInstance.delegate, onUserActivityOccurred }`: Keeps the other global callbacks when you replace the delegate. - `Storyteller.ActivityType`: Enum for comparing `type`, for example `Storyteller.ActivityType.sdkInitialized`. - Event categories: `Story Events`, `Poll Events`, `Quiz Events`, `Clip Events`, `Ad Events`. - `sdkInitialized` fields: `initializationSucceeded`, `enableAdTracking`, `enableFullVideoAnalytics`, `enablePersonalization`, `enableRemoteViewingStore`, `enableStorytellerTracking`, `enableUserActivityTracking`, `appId`, `deviceType` (`Phone`, `Tablet`, `TV`, `Desktop`), `deviceBrand`, `deviceModel`, `operatingSystem`, `osVersion` (`'none'` when unknown), `screenResolution` (`x` viewport; `null` during server rendering). - `UserActivityData.context?: unknown`: Client placement value returned to `onUserActivityOccurred`. - Supported context views: Stories Row, Stories Grid, Clips Row, Clips Grid, Clips Player, and Embedded Clips Player. - `context: undefined`: Callback field omitted. `null`, `false`, `0`, and an empty string remain present. - `OpenedReason` Story values: `storyListTap`, `deepLink`, `swipe`, `automaticPlayback`, `tap`. - `OpenedReason` Clip values: `clipListTap`, `categoryListTap`, `categoryBackTap`, `deepLink`, `swipe`. - `DismissedReason` values: `backgroundTapped`, `closeButtonTapped`, `swipedDown`, `swipedFinalStory`, `swipedFirstStory`, `skippedFinalPage`, `backTapped`, `backButtonTapped`, `completedFinalPage`, `instanceMethod`, `escapeKeyPressed`, `windowUnload`. ## Cross-References - StorytellerDelegate explains the other global callbacks on the delegate. - Control privacy and tracking explains the options that gate the callback and Storyteller analytics. - StorytellerListView explains how to configure and replace a view's `context` value. - The per-event pages provide the event names, trigger conditions, and field tables referenced here. # Story Events URL: /analytics/StoryEvents/ ## Task Detail every analytics event emitted while users interact with Stories, including trigger conditions and field-level payloads. ## Metadata - Slug: analytics-story-events - Source: public-docs/analytics/StoryEvents.md - Audience: Analytics engineers consuming Storyteller Story events - Platforms: Web - Related: Integrate analytics, analytics/ClipEvents, analytics/AdEvents ## Overview - The Storyteller Web Showcase `onUserActivityOccurred` handler is the reference for forwarding Story events. - Enumerates `openedStory`, `dismissedStory`, `skippedStory`, `completedStory`, `openedPage`, `actionButtonTapped`, `shareButtonTapped`, `shareSuccess`, `previousPage`, `previousStory`, and the deprecated but still sent `completedPage` and `skippedPage`. - Explains `captionsEnabled` on Story and Page callbacks and the `enabledStoryCaptions` and `disabledStoryCaptions` toggle events, including their `categories` field. - Every Story event table includes `captionsEnabled`, `categories`, `categoryDetails`, `currentCategory`, Page action fields, `pageId`, `pageIndex`, `pageTitle`, `pageType`, `storyId`, `storyIndex`, `storyPageCount`, `storyPlaybackMode`, `storyTitle`, and `storyDisplayTitle`. - Event-specific fields: `openedReason` and `storyReadStatus` (`openedStory`); `dismissedReason`, `durationViewed`, and `pagesViewed` (`dismissedStory`); `contentLength` and `openedReason` (`openedPage`); `contentLength` (`completedPage`); `shareMethod` (`shareSuccess`). - `currentCategory` holds the category name in `title` and its external ID in `id`. `pageType` values are `image`, `video`, `poll`, and `triviaQuiz`. ## When To Use - Use this file when mapping Story analytics into your data warehouse and validating trigger conditions for each Story event. - Reference it when debugging missing Story, Page, CTA, or share events. ## Integration Steps 1. Capture Story events via `onUserActivityOccurred` and filter for the event names listed here. 2. Map the documented fields into your analytics schema, especially nested objects such as `currentCategory` and `categoryDetails`. 3. Use the trigger descriptions to confirm that each event fires at the correct user action. ## API Cheat Sheet - `openedStory`: Story becomes active; adds `openedReason` and `storyReadStatus` (`read`, `unread`). - `dismissedStory`: Story view closes; adds `dismissedReason`, `durationViewed` (milliseconds), and `pagesViewed`. - `skippedStory` / `completedStory`: Story-level transitions; `completedStory` fires when the final Page opens, together with `openedPage`. - `openedPage`: Page becomes active; adds `contentLength` (seconds) and `openedReason`. - `actionButtonTapped` / `shareButtonTapped`: CTA and share button taps for the current Page. - `shareSuccess`: Sharing finished (your `onShareButtonTapped` promise resolved, the browser share sheet completed, or the Page media downloaded); adds `shareMethod` (`shareLink`, `shareMedia`, `share`). - `previousPage` / `previousStory`: Backward navigation within a Story or to a prior Story. - `completedPage` / `skippedPage`: Deprecated in `ActivityType` but still sent when a Page finishes automatically or the user leaves it early; `completedPage` adds `contentLength`. - `enabledStoryCaptions` / `disabledStoryCaptions`: Caption choice changes with `captionsEnabled`, active Story and Page fields, and category fields. ## Pitfalls / Notes - `pageIndex` and `storyIndex` are 1-based, and ads do not affect `pageIndex`. - `durationViewed` and `pagesViewed` count from the most recent `openedStory` with `storyListTap` or `deepLink` and reset after each `dismissedStory`. - `dismissedStory` does not include `storyReadStatus`. ## Cross-References - Integrate analytics defines the `OpenedReason` and `DismissedReason` enums referenced in these tables. - analytics/ClipEvents covers the analogous Clip lifecycle events. # Poll Events URL: /analytics/PollEvents/ ## Task Describe the analytics payload generated when users vote in Polls embedded within Stories. ## Metadata - Slug: analytics-poll-events - Source: public-docs/analytics/PollEvents.md - Audience: Analytics engineers capturing Poll engagement - Platforms: Web - Related: Integrate analytics, analytics/StoryEvents ## Overview - The Storyteller Web Showcase `onUserActivityOccurred` handler is the reference for forwarding Poll events. - The page documents the single `votedPoll` event fired when a user votes in a Poll. - The payload combines Story and Page context with the selected `pollAnswerId`. - The field list includes `captionsEnabled`, `categories`, `categoryDetails`, `currentCategory`, `pageActionText`, `pageActionUrl`, `pageHasAction`, `pageId`, `pageIndex`, `pageTitle`, `pageType`, `pollAnswerId`, `storyId`, `storyIndex`, `storyPageCount`, `storyPlaybackMode`, `storyTitle`, and `storyDisplayTitle`. ## When To Use - Reference this file when parsing Poll responses from `onUserActivityOccurred` or validating that Poll answers reach your analytics pipeline. - Use it to understand which identifiers you can join back to CMS data. ## Integration Steps 1. Listen for `votedPoll` events via the global delegate. 2. Map the documented Story and Page fields, category context, and `pollAnswerId` into your analytics schema. 3. Use the Page action fields if you need to correlate Poll participation with Story CTAs. ## API Cheat Sheet - `votedPoll`: Fired when a user votes in a Poll; includes `captionsEnabled`, `categories`, `categoryDetails`, `currentCategory`, `pageActionText`, `pageActionUrl`, `pageHasAction`, `pageId`, `pageIndex`, `pageTitle`, `pageType`, `pollAnswerId`, `storyId`, `storyIndex`, `storyPageCount`, `storyPlaybackMode`, `storyTitle`, and `storyDisplayTitle` (the Story's long display title). ## Pitfalls / Notes - The display title field is `storyDisplayTitle`; there is no `displayTitle` field. - `pageIndex` and `storyIndex` are 1-based, matching the Story event conventions. ## Cross-References - Integrate analytics explains where Poll events are emitted from. - StoryEvents provides context for the shared Story and Page fields. # Quiz Events URL: /analytics/QuizEvents/ ## Task Outline the analytics events emitted for Trivia Quizzes, covering per-question answers and Quiz completion payloads. ## Metadata - Slug: analytics-quiz-events - Source: public-docs/analytics/QuizEvents.md - Audience: Analytics engineers tracking Quiz engagement - Platforms: Web - Related: Integrate analytics, analytics/StoryEvents ## Overview - The Storyteller Web Showcase `onUserActivityOccurred` handler is the reference for forwarding Quiz events. - Documents `triviaQuizQuestionAnswered`, which fires when a user answers a Quiz question or times out. - Documents `triviaQuizCompleted`, which fires once per user per Quiz at the same time as the final `triviaQuizQuestionAnswered` event. - Both payloads include the shared Story and Page fields (`captionsEnabled`, category fields, Page action fields, `pageId`, `pageIndex`, `pageTitle`, `pageType`, `storyId`, `storyIndex`, `storyPageCount`, `storyPlaybackMode`, `storyTitle`, `storyDisplayTitle`). - Quiz-specific fields include `triviaQuizAnswerId`, `triviaQuizId`, `triviaQuizQuestionId`, `triviaQuizTitle`, and `triviaQuizScore`. ## When To Use - Reference this document when ingesting Quiz analytics or validating completion behavior. - Use it to confirm the exact Quiz-specific fields emitted with answer and completion events. ## Integration Steps 1. Capture `triviaQuizQuestionAnswered` and `triviaQuizCompleted` from `onUserActivityOccurred`. 2. Map the Quiz fields (`triviaQuizAnswerId`, `triviaQuizId`, `triviaQuizQuestionId`, `triviaQuizTitle`, `triviaQuizScore`) alongside the shared Story and Page fields and category context. 3. Expect the completion event to arrive with the final answer event for a completed Quiz. ## API Cheat Sheet - `triviaQuizQuestionAnswered`: Fires on an answer or timeout; includes the shared Story and Page fields plus `triviaQuizAnswerId`, `triviaQuizId`, `triviaQuizQuestionId`, and `triviaQuizTitle`. - `triviaQuizCompleted`: Fires once per user per Quiz at completion; includes the shared Story and Page fields plus `triviaQuizId`, `triviaQuizScore`, and `triviaQuizTitle`. ## Pitfalls / Notes - The display title field is `storyDisplayTitle`; there is no `displayTitle` field. - `triviaQuizQuestionId` is an ID, not the question text. - When a user times out or exits, `triviaQuizAnswerId` should be an empty GUID. ## Cross-References - StoryEvents provides context for the shared Story and Page fields. - Integrate analytics explains where Quiz events are emitted from. # Clip Events URL: /analytics/ClipEvents/ ## Task Capture all analytics events emitted while users browse Clips collections, including playback, category navigation, likes, sharing, and caption changes. ## Metadata - Slug: analytics-clip-events - Source: public-docs/analytics/ClipEvents.md - Audience: Analytics teams instrumenting Clip engagement - Platforms: Web - Related: Integrate analytics, analytics/StoryEvents, analytics/AdEvents ## Overview - The Storyteller Web Showcase `onUserActivityOccurred` handler is the reference for forwarding Clip events. - Enumerates `openedClip`, `dismissedClip`, `finishedClip`, `nextClip`, `previousClip`, `completedLoop`, `actionButtonTapped`, `shareButtonTapped`, `shareSuccess`, `pausedClip`, `resumedClip`, `likedClip`, `unlikedClip`, `openedCategory`, and `dismissedCategory`. - Explains `captionsEnabled` on Clip callbacks and documents the `enabledClipCaptions` and `disabledClipCaptions` toggle events in a full property table. - Every Clip table includes `captionsEnabled`, `categories`, `categoryDetails`, `collection`, `clipId`, `clipIndex`, `clipTitle`, `clipHasAction`, `clipActionText`, and `clipActionUrl`. - `categories` holds category names in `openedClip`, `dismissedClip`, and `finishedClip`, and category external IDs in the other Clip events. - `contentLength` is sent only with `openedClip` and `finishedClip`. `shareSuccess` adds `shareMethod`, which is always an empty string for Clips. - `completedLoop`, `pausedClip`, and `resumedClip` never fire for live Clips. ## When To Use - Use this page to map Clip analytics to your BI pipelines and validate playback, share, like, and category-navigation events. - Reference it while troubleshooting missing events for Clips-specific actions. ## Integration Steps 1. Capture Clip events via `onUserActivityOccurred`. 2. Map the exact event names and fields you need, especially `collection`, `clipId`, `clipIndex`, and category fields. 3. Use `openedCategory` and `dismissedCategory` to understand Category drill-down inside the Clips player. ## API Cheat Sheet - `openedClip` / `dismissedClip`: Clip player enters or exits; include `openedReason` or `dismissedReason`; `openedClip` adds `contentLength` and `dismissedClip` adds `clipsViewed`, `durationViewed`, and `loopsViewed`. - `finishedClip`: Fires with `openedCategory`, `dismissedClip`, `nextClip`, or `previousClip`; adds `contentLength`, `durationViewed`, and `loopsViewed`. - `nextClip`, `previousClip`, `completedLoop`: Playback progression events. - `actionButtonTapped`, `shareButtonTapped`, `shareSuccess`: CTA and share events for the active Clip. - `pausedClip` / `resumedClip`: User pause and resume; not sent for automatic pauses. - `likedClip` / `unlikedClip`: Like state change events. - `openedCategory` / `dismissedCategory`: Category navigation inside the player; include `categoryId`, `categoryName`, and a one-item `categoryDetails` list. `openCollection(collectionId, { categoryId })` does not send `openedCategory`. - `enabledClipCaptions` / `disabledClipCaptions`: Caption choice changes with `captionsEnabled` and the active Clip fields. ## Pitfalls / Notes - Use `categoryDetails` when you need both category names and IDs, because `categories` differs between events. - Category events include both category and collection context; store both if you need drill-down reporting. ## Cross-References - Integrate analytics provides the enum definitions reused in these tables. - StoryEvents describes the analogous Story playback events. # Ad Events URL: /analytics/AdEvents/ ## Task Document analytics events generated for Storyteller ads in Stories and Clips, covering playback lifecycle, quartile tracking, and CTA interactions. ## Metadata - Slug: analytics-ad-events - Source: public-docs/analytics/AdEvents.md - Audience: Monetization and analytics engineers integrating Storyteller ad reporting - Platforms: Web - Related: Integrate analytics, Ads, analytics/StoryEvents ## Overview - The Storyteller Web Showcase `onUserActivityOccurred` handler is the reference for forwarding ad events. - Enumerates lifecycle events `openedAd`, `dismissedAd`, `pausedAdPage`, `resumedAdPage`, `finishedAd`, and `skippedAd`. - Covers engagement events `adActionButtonTapped`, `viewedAdPageFirstQuartile`, `viewedAdPageMidpoint`, `viewedAdPageThirdQuartile`, and `viewedAdPageComplete`. - Tables list Story ad properties: `adId`, `adPlacement`, `adStrategy`, `adType`, `advertiserName`, `categories`, `categoryDetails`, `currentCategory`, `pageType`, and Page action fields. `contentLength` is sent only with `openedAd` and `dismissedAd`. - Clips ads send `collection`, `clipHasAction`, `clipActionText`, and `clipActionUrl` instead of the category and Page action fields, with `adType` `clips` and `adPlacement` `betweenClips`. - `adPlacement` values: `betweenClips`, `betweenPages`, `betweenStories`, `betweenStoriesAndPages`. `adType` values: `stories`, `clips`. ## When To Use - Reference this document when building ad reporting dashboards or reconciling Storyteller ad events with ad delivery data. - Use it to understand which fields drive completion and CTA reporting. ## Integration Steps 1. Capture ad events via `onUserActivityOccurred` (requires `enableAdTracking`), filtering for the event names documented here. 2. Map ad metadata (`adId`, `adPlacement`, `adStrategy`, `adType`, `advertiserName`) and the Story or Clip context fields into your analytics system. 3. Use the quartile events and `finishedAd` to reason about ad completion. ## API Cheat Sheet - `openedAd` / `dismissedAd`: Bracket an ad view; include `contentLength` and `openedReason` or `dismissedReason`. `dismissedAd` also fires when the browser back button closes the Story player, when the page unloads, or when the Clips player closes on an ad. - `pausedAdPage` / `resumedAdPage`: Pause and resume within an ad Page. - `finishedAd`: Fires with `dismissedAd`, `skippedAd`, or `viewedAdPageComplete`, and in Clips when the user swipes away from an ad. - `skippedAd`: User leaves the ad early. - `adActionButtonTapped`: CTA event inside the ad. - `viewedAdPageFirstQuartile`, `viewedAdPageMidpoint`, `viewedAdPageThirdQuartile`, `viewedAdPageComplete`: Playback progress milestones. ## Pitfalls / Notes - Ad events reuse many Story fields, so keep field names consistent across schemas. - Quartile events and `finishedAd` can coexist; deduplicate only if your reporting model needs a single completion signal. ## Cross-References - Ads explains how ad configuration and ad requests relate to the activity captured here. - Integrate analytics provides the reason enums referenced in this file. # Integrate ads URL: /Ads/ ## Task Guide integrators through configuring Storyteller ads (First Party Ads or Google Ad Manager), covering the `getAdConfig` callback, its return value, default targeting, and `AdRequestInfo` payloads. ## Metadata - Slug: ads - Source: public-docs/Ads.md - Audience: Engineers responsible for monetization setups in Storyteller - Platforms: Web - Related: StorytellerDelegate, Callbacks reference, Analytics, Privacy and Tracking ## Overview - Storyteller shows ads in Stories and Clips from two sources: First Party Ads created in the Storyteller CMS, which need no code, and Google Ad Manager (GAM) ads. - Storyteller sets which ad source a tenant uses; the Storyteller Delivery Team changes it and handles questions about other ad servers. - GAM integration uses the `getAdConfig` callback on `Storyteller.sharedInstance.delegate`. The SDK calls it each time it needs an ad, and only when the tenant uses GAM ads. - Assigning `Storyteller.sharedInstance.delegate` replaces every global callback, so the samples spread the current delegate. - The JavaScript and TypeScript samples check for `story` before reading it, because Clips ad requests have `clip` and an optional `nextClip` instead. They return `slot`, `publisherProvidedId`, and `customTargeting`. The TypeScript sample imports the request types with `import type`. The Storyteller Web Showcase builds the `getAdConfig` result in `buildAdConfig`. - The return value section lists the returned fields, `null` for no ad, and that the SDK doesn't wait for a promise. - Default `customTargeting` keys are documented separately for Stories and Clips, including array-valued category fields. - `StorytellerAdRequestInfo` is documented as Story-specific or Clip-specific metadata so you can pass the right context to your ad server. ## When To Use - Use this page when you need to connect Storyteller to Google Ad Manager. - Reference it when you need the exact `slot` format, the return value, default targeting keys, or the Story and Clip fields in `adRequestInfo`. ## Integration Steps 1. Confirm whether your tenant uses Storyteller First Party Ads or Google Ad Manager. 2. For GAM, implement `getAdConfig` on `Storyteller.sharedInstance.delegate`, and spread the current delegate so your other callbacks stay set. 3. Check whether `adRequestInfo` has `story` (Story ad) or `clip` (Clips ad) before you read category details. 4. Return `slot` in the form `/[NETWORK_CODE]/[UNIT_CODE]`, an optional `publisherProvidedId` for GAM PPID, and a `customTargeting` object. Return `null` for no ad. Return the object directly, not a promise. 5. Add any tenant-specific KVPs yourself, because the SDK does not copy KVPs set elsewhere on your page. ## API Cheat Sheet - `getAdConfig(adRequestInfo)`: Returns `{ slot, customTargeting?, publisherProvidedId? }` or `null`. `null` or a missing `slot` requests no ad. The SDK uses the return value directly and doesn't wait for a promise. Called only for GAM tenants. - `slot`: Required GAM ad unit ID in the form `/[NETWORK_CODE]/[UNIT_CODE]`; the ad unit must serve 1x1 ads. - `publisherProvidedId`: Optional GAM PPID. It is sent as GAM's PPID field, not as a custom targeting KVP; the SDK trims whitespace, omits empty values, and omits PPID when ad tracking is disabled. - `customTargeting`: Optional KVP map with string or string-array values. The SDK merges it over the default targeting, so a returned key replaces the default key with the same name. The SDK does not reuse KVPs from the rest of the page. - With `enableAdTracking: false`, the SDK omits the default targeting and `publisherProvidedId` but still sends the returned `customTargeting`. - Default Stories `customTargeting`: `stCurrentCategory` (`string` current Story category external ID), `stPlacement` (`string` placement code), `stCategories` (`string[]` current Story category external IDs). - Default Clips `customTargeting`: `stCollection` (`string` collection ID), `stClipCategories` (`string[]` current Clip category external IDs), `stNextClipCategories` (`string[]` next Clip category external IDs). - `StorytellerStoriesAdRequestInfo`: `{ placement, categories, story: { categories: CategoryDetail[] } }`; `placement` identifies the placement, `categories` are the list's Category IDs, and `CategoryDetail` exposes `name` plus `externalId`. - `StorytellerClipsAdRequestInfo`: `{ collection, clip: { categories: ClipCategory[] }, nextClip?: { categories: ClipCategory[] } }`; `nextClip` describes the Clip after the ad, and `ClipCategory` exposes `name` plus `externalId`. ## Examples - JavaScript and TypeScript examples keep the existing delegate callbacks, branch on Story vs Clip ad requests, map category objects to arrays of names, and return `slot`, `publisherProvidedId`, and `customTargeting`. - The default targeting and `AdRequestInfo` tables list the fields you can pass through to your ad server. ## Pitfalls / Notes - First Party Ads don't require code changes; `getAdConfig` is only for Google Ad Manager. - Clips ad requests have no `story`; reading `adRequestInfo.story.categories` without a check throws on Clips ads. - Assigning a new delegate object replaces all global callbacks. - PPID belongs in `publisherProvidedId`, not in `customTargeting`. - The SDK does not wait for a promise returned from `getAdConfig`. - `slot` must point to a 1x1 GAM ad unit. ## Cross-References - StorytellerDelegate shows where `getAdConfig` is attached; the callbacks reference documents the full `getAdConfig` type. - Analytics and Ad Events help interpret the ad-related activity that follows from these requests. - Privacy and Tracking explains what happens when ad tracking is disabled. # API reference URL: /reference/ ## Task Find the exact public API of Web SDK 11.0.0: package entry points, exports, and the reference page for each surface. ## Metadata - Slug: reference-index - Source: public-docs/reference/index.md - Audience: Engineers who need exact Web SDK names, signatures, and types - Platforms: Web - Related: Storyteller instance, Views and configuration, Callbacks, Types and enums, Install from npm, Install with a script tag ## Overview - Links four reference pages: Storyteller instance, Views and configuration, Callbacks, and Types and enums. - Lists the npm import forms: namespace, named, default (ESM entry), and CommonJS `require`. - Maps the package `exports` paths, including the required `dist/storyteller.min.css` stylesheet. - Describes the CDN script: the `Storyteller` global, injected styles, and chunk files loaded from the script directory. - Names the type-only exports and shows how to derive unexported types such as `UserInput` and `AdConfig`. - Lists every export with its kind and reference link. ## When To Use - Use this page to check an export name, an import form, or the page that documents a symbol. - Use the task guides to learn a workflow. ## API Cheat Sheet - `import * as Storyteller from '@getstoryteller/storyteller-sdk-javascript'`: Namespace import used by the guides. - `import Storyteller from '@getstoryteller/storyteller-sdk-javascript'`: Default export from the ESM entry (`index.mjs`); the same namespace object. - `require('@getstoryteller/storyteller-sdk-javascript')`: Returns the namespace object, which has no `default` property. - `import '@getstoryteller/storyteller-sdk-javascript/dist/storyteller.min.css'`: Required stylesheet for npm integrations. - `https://content.usestoryteller.com/javascript-sdk/11.0.0/dist/storyteller.min.js`: CDN script that defines the `Storyteller` global and adds its own styles. - Type-only exports: `IListConfiguration`, `IStorytellerClipsPlayerConfiguration`, `IStorytellerEmbeddedClipsPlayerConfiguration`, `IStorytellerDelegate`, `IListViewDelegate`, `IStorytellerClipsPlayerDelegate`, `StorytellerEventTrackingOptions`, `StorytellerAdRequestInfo`, `StorytellerStoriesAdRequestInfo`, `StorytellerClipsAdRequestInfo`, `ServerRenderedStory`, `Subset`. ## Pitfalls / Notes - The CDN build does not define `Storyteller.StorytellerTrackedFunctionalFeature`. Pass string values such as `'all'`. - The declarations import React and React Router types. The package lists `@types/react` and `@types/react-router-dom` as peer dependencies. - Importing the package in Node.js needs no browser globals. Create views only in the browser. ## Cross-References - Install from npm and Use React or Next.js cover the import and stylesheet setup. - Install with a script tag covers the CDN setup. - Storyteller instance, Views and configuration, Callbacks, and Types and enums document each export. # Storyteller instance URL: /reference/storyteller/ ## Task Look up every property and method of `Storyteller.sharedInstance` and `Storyteller.User`, with signatures, parameters, defaults, and errors. ## Metadata - Slug: reference-storyteller - Source: public-docs/reference/storyteller.md - Audience: Engineers calling the Web SDK singleton from application code - Platforms: Web - Related: Additional Methods, Quickstart, Users, Privacy and Tracking, Themes, StorytellerDelegate ## Overview - Lists the `sharedInstance` properties: `version`, `isInitialized`, `isPlayerVisible`, `delegate`, `theme`, `currentTheme`, `uiStyle`, `eventTrackingOptions`, `customInstanceHost`, and `currentApiKey`. - Documents `initialize(apiKey, userInput?)`, including `externalId` values, concurrent calls, repeat calls, and each rejection value. - Documents `getStoriesCount` and `getClipsCount`, which wait for a successful initialization. - Explains the shared behavior of the open methods and documents `openStory`, `openStoryByExternalId`, `openPage`, `openCategory`, `openCollection`, and `openClipByExternalId`. - Documents `dismissPlayer`, `disablePlayback`, `enablePlayback`, and `enableLogging`. - Lists the deprecated members `openClip`, `enableEventTracking`, `disableEventTracking`, and `currentUserId`, and the internal `requestUserActivityHistory_`. - Documents the `Storyteller.User` attribute and locale methods. ## When To Use - Use this page to check a singleton signature, default, or rejection value. - Use it when an integration must handle initialization errors, open content from host UI, or change privacy options. ## API Cheat Sheet - `initialize(apiKey: string, userInput?: UserInput): Promise`: Starts the SDK. `userInput.externalId` sets (string), clears (`null`), or keeps (omitted) the user ID. - `delegate: IStorytellerDelegate`: Global callbacks. Assigning replaces all four callbacks. - `theme: Subset`: Global theme. Each `initialize` call resets it to a default `UiTheme`. - `eventTrackingOptions: StorytellerEventTrackingOptions`: Assigning replaces every option; omitted fields return to their defaults. - `getStoriesCount(categoryIds: string[]): Promise` / `getClipsCount(collectionId: string): Promise`: Content counts after a successful initialization. - `openStory(id)`, `openStoryByExternalId(externalId)`, `openPage(pageId)`, `openCategory(categoryId, storyId?)`, `openCollection(collectionId, destination?, openedReason?)`, `openClipByExternalId(collectionId, externalId)`: Set `location.hash` to open a player; reject with an `Error` or a string when content cannot be loaded. - `dismissPlayer(animated: boolean): void`: Closes the open player; `StorytellerEmbeddedClipsPlayerView` ignores it. - `disablePlayback(): void` / `enablePlayback(): void`: Pause and allow Story and Clip playback. - `enableLogging(): void`: Adds info, warning, and log console messages. Errors always log. - `Storyteller.User.setUserAttribute(key, value)`, `getUserAttribute(key)`, `getUserAttributes()`, `removeUserAttribute(key)`, `setLocale(locale)`, `locale`: User attribute storage. ## Pitfalls / Notes - Set `theme` after `initialize` resolves, and again after a later `initialize` call. - Spread the current `eventTrackingOptions` to change one option. - `initialize` error classes are not exported. Check the message prefix: `InvalidApiKeyError`, `NetworkTimeoutError`, or `NetworkError`. - An empty API key rejects with a string, not an `Error`. - `setUserAttribute` and `setLocale` throw for an empty value. ## Cross-References - Additional Methods and Users are the task guides for these members. - Callbacks documents `IStorytellerDelegate`. - Types and enums documents `StorytellerEventTrackingOptions`, `UiTheme`, and `Theme`. # Views and configuration URL: /reference/views/ ## Task Look up the constructor, members, and configuration fields of each Web SDK view class. ## Metadata - Slug: reference-views - Source: public-docs/reference/views.md - Audience: Engineers creating and configuring Storyteller views - Platforms: Web - Related: Views, StorytellerListView, StorytellerRowView, StorytellerGridView, Embedded Clips Player, StorytellerListViewDelegate ## Overview - Summarizes six view classes and their content argument, configuration input, and delegate type. - Gives each constructor signature with parameter defaults, including `useGoogleWebStoryUrls`. - Documents the Clips player source object and the errors that the constructor throws. - Lists the differences of `StorytellerEmbeddedClipsPlayerView` and the deprecated `RowView` and `GridView` aliases. - Documents container requirements and the `data-ui-style`, `data-cell-type`, and `data-base-url` attributes. - Documents the shared members `configuration`, `delegate`, `reloadData`, and `destroy`, plus deprecated view members. - Documents `cellType` on `StorytellerClipsRowView` and `topLevelBackButtonEnabled` on the Clips players. - Lists every `IListConfiguration` field with its type, views, and default, plus the Clips player configuration types. ## When To Use - Use this page to check a constructor argument order, a configuration field, or a view member. - Use it when a view renders nothing, a configuration change has no effect, or a Clips player source throws. ## API Cheat Sheet - `new StorytellerStoriesRowView(elementId: string, listCategories?: string[], useGoogleWebStoryUrls?: boolean)`: Stories row. `StorytellerStoriesGridView` takes the same arguments. - `new StorytellerClipsRowView(elementId: string, collectionName: string, useGoogleWebStoryUrls?: boolean)`: Clips row. `StorytellerClipsGridView` takes the same arguments. - `new StorytellerClipsPlayerView(elementId: string, source: string | StorytellerClipsPlayerSource, useGoogleWebStoryUrls?: boolean)`: Clips player. `StorytellerEmbeddedClipsPlayerView` takes the same arguments. - `StorytellerClipsPlayerSource`: `{ collection?: string; clipId?: string; externalId?: string }` with exactly one non-empty field. - `view.configuration`: Assigning updates only the included fields; source changes reload content. - `view.delegate`: `IListViewDelegate`, or `IStorytellerClipsPlayerDelegate` for the Clips players. - `view.reloadData(): Promise`: Reloads content and resolves after success or failure. - `view.destroy(): void`: Releases the view; a second call does nothing. - `clipsRow.cellType`: Tile shape setter for `StorytellerClipsRowView`, which has no `cellType` configuration field. - `player.topLevelBackButtonEnabled: boolean`: Shows the top-level back button; defaults to `false`. - `IListConfiguration`: `basename`, `context`, `displayLimit`, `theme`, `uiStyle`, plus `categories`, `preload`, `cellType`, `collection`, `clipId`, or `externalId` by view. ## Pitfalls / Notes - A missing container logs a console error and the view renders nothing. - A Clips player object source with zero or several non-empty fields throws an `Error`. - `preload: false` does not undo an earlier `preload: true`. - The deprecated `categories` setter does not reload the view. - `useGoogleWebStoryUrls` has no effect on Clips views. - Leave out the fourth constructor argument of Clips rows and grids. ## Cross-References - Configuring a StorytellerListView is the task guide for configuration. - Callbacks documents the view delegates. - Types and enums documents `CellType`, `UiStyle`, `UiTheme`, and `Subset`. # Callbacks URL: /reference/callbacks/ ## Task Look up every Web SDK delegate callback: its signature, when it runs, and how the SDK uses its return value. ## Metadata - Slug: reference-callbacks - Source: public-docs/reference/callbacks.md - Audience: Engineers handling Web SDK events, sharing, ads, and navigation - Platforms: Web - Related: Delegate Callbacks, StorytellerDelegate, StorytellerListViewDelegate, Analytics, Ads, Privacy and Tracking ## Overview - Summarizes `IStorytellerDelegate`, `IListViewDelegate`, and `IStorytellerClipsPlayerDelegate` and where each is set. - Documents `onUserActivityOccurred`, including the privacy options that gate it and the fields nulled for video privacy. - Documents `onShareButtonTapped` and how its promise result affects `shareSuccess` and the `navigator.share` fallback. - Documents `getAdConfig`, its return shape, default targeting, and ad tracking behavior. - Documents `userNavigatedToApp` for in-app actions. - Documents `onDataLoadStarted`, `onDataLoadComplete`, `onPlayerDismissed`, and `onTopLevelBackTapped`. ## When To Use - Use this page to check a callback signature or its timing. - Use it when analytics events are missing, a share does not complete, or ad targeting differs from the returned configuration. ## API Cheat Sheet - `onUserActivityOccurred?: (type: ActivityType, data: UserActivityData) => void`: Runs for each analytics event while `enableUserActivityTracking` is `true`. - `onShareButtonTapped?: (text: string, title: string, url: string) => Promise`: Replaces the browser share sheet for link shares. Resolve to record `shareSuccess`. - `getAdConfig?: (adRequestInfo: StorytellerAdRequestInfo) => AdConfig | null`: Returns `{ slot, customTargeting?, publisherProvidedId?, type? }` for third-party ads, or `null` for no ad request. - `userNavigatedToApp?: (url: string) => void`: Routes in-app action URLs. - `onDataLoadStarted?: () => void`: Runs when a view starts loading content. - `onDataLoadComplete?: (success: boolean, error: Error | null, dataCount: number) => void`: Runs when the content request finishes. Clips views report the first page count. - `onPlayerDismissed?: () => void`: Runs when the view's player is dismissed. - `onTopLevelBackTapped?: () => void`: Runs on a top-level back tap in a Clips player. Without it, the SDK calls `window.history.back()`. ## Pitfalls / Notes - Assigning a delegate object replaces the previous delegate, including callbacks that you leave out. - Ad events reach `onUserActivityOccurred` only when `enableAdTracking` is `true`. - With `enableFullVideoAnalytics: false`, Story, Page, and Clip IDs and titles arrive as `null`. - Assign the global delegate before `initialize` to receive `sdkInitialized`. - With `enableAdTracking: false`, the SDK drops its default ad targeting and `publisherProvidedId`, and still sends your `customTargeting`. - Later Clips pages do not call `onDataLoadComplete`. ## Cross-References - StorytellerDelegate and StorytellerListViewDelegate are the task guides for delegates. - Analytics and the event pages document the event data. - Ads documents ad configuration and default targeting. # Types and enums URL: /reference/types/ ## Task Look up the enums, event data, ad request data, theme classes, and server rendering exports of the Web SDK. ## Metadata - Slug: reference-types - Source: public-docs/reference/types.md - Audience: Engineers typing Web SDK callbacks, configuration, and themes - Platforms: Web - Related: Analytics, Privacy and Tracking, Ads, Themes, Callbacks ## Overview - Lists the values of `UiStyle`, `CellType`, `ActivityType`, `OpenedReason`, `DismissedReason`, `StorytellerTrackedFunctionalFeature`, `Alignment`, `ButtonAlignment`, and `TextCase`. - Maps each `ActivityType` value to its analytics event page and lists values that the source marks as unused or deprecated. - Documents `StorytellerEventTrackingOptions` fields and defaults. - Summarizes `UserActivityData` fields by area, plus `CategoryDetail`, `CurrentCategory`, and `ActivityEventDetail`. - Documents `StorytellerAdRequestInfo`, its Stories and Clips variants, and `ClipCategory`. - Documents `UiTheme`, `Theme`, and `Subset`, with links to the theme property tables. - Documents `ServerRenderer` and `ServerRenderedStory`, and lists `Story`, `QuizRenderer`, and `QuizApiService` as exports that integrations do not need. ## When To Use - Use this page to check an enum value or the shape of callback data. - Use it to type ad request handling or theme inputs in TypeScript. ## API Cheat Sheet - `UiStyle`: `auto`, `light`, `dark`. - `CellType`: `round`, `square`. - `StorytellerTrackedFunctionalFeature`: `all`, `clipLikes`, `clipShares`, `clipViewedStatus`, `pageReadStatus`, `pollVotes`, `triviaQuizAnswers`. - `StorytellerEventTrackingOptions`: `disabledFunctionalFeatures` (default `[]`) plus seven `enable*` booleans (default `true`). - `StorytellerAdRequestInfo`: `StorytellerStoriesAdRequestInfo | StorytellerClipsAdRequestInfo`; check `'story' in info` to tell them apart. - `new UiTheme(baseTheme?: Subset | null)`: Light and dark themes built over defaults. - `new Theme(theme?: Subset)`: One color scheme of a theme. - `Subset`: Recursive `Partial` used for theme inputs. - `ServerRenderer.getStories(categories?)` / `ServerRenderer.render(stories)`: Story markup for server-side rendering. ## Pitfalls / Notes - The CDN script does not define `Storyteller.StorytellerTrackedFunctionalFeature`. Pass string values there. - `completedPage` and `skippedPage` are grouped as deprecated in the source, but the Story player still records them. - `story.id` and `clip.id` in ad request data are always empty strings. - No SDK callback receives `ActivityEventDetail` in 11.0.0. ## Cross-References - Analytics and the event pages document each event. - Privacy and Tracking documents each tracking option. - Themes documents each theme property. - Ads documents ad request data and default targeting. # Handle delegates and callbacks URL: /delegates/ ## Task Choose the delegate that handles an SDK event and find where to set it. ## Metadata - Slug: delegates-index - Source: public-docs/delegates/index.md - Audience: Engineers handling SDK and view events - Platforms: Web - Related: Handle Global Callbacks, Handle View Callbacks, Integrate Analytics, Integrate Ads ## Overview - A delegate is an object of optional callback functions. Storyteller has one global delegate, and each view has its own. - The global delegate (`IStorytellerDelegate`, set on `Storyteller.sharedInstance.delegate`) handles analytics events, share taps, ad requests, and in-app action links. - The list view delegate (`IListViewDelegate`, set on a row or grid's `delegate`) reports loading and player dismissal. - The Clips player delegate (`IStorytellerClipsPlayerDelegate`, set on a Clips player view's `delegate`) adds the back button callback. - Set the global delegate before `initialize` to receive `sdkInitialized`; assigning a delegate replaces the previous one. ## When To Use - Choose the global delegate when the application handles events from every player. - Choose a view delegate when one row, grid, or Clips player needs its own callbacks. # Handle global callbacks URL: /StorytellerDelegate/ ## Task Summarize the global delegate that captures analytics, sharing, ad configuration, and in-app navigation callbacks from every Storyteller player. ## Metadata - Slug: storyteller-delegate - Source: public-docs/StorytellerDelegate.md - Audience: Engineers handling Storyteller events and routing - Platforms: Web - Related: Handle View Callbacks, Integrate Analytics, Integrate Ads ## Overview - The global delegate is an object typed `IStorytellerDelegate`, assigned to `Storyteller.sharedInstance.delegate`, for Stories and Clips players. - Set it before `initialize` to receive the `sdkInitialized` event. - Assigning `delegate` replaces all four callbacks; define them in one object or spread `Storyteller.sharedInstance.delegate` into the new one. - `onUserActivityOccurred` receives analytics events and `data.context` while `enableUserActivityTracking` is on; ad events also need `enableAdTracking`. - `onShareButtonTapped` replaces sharing for Stories and Clips; without it the SDK uses `navigator.share`. The share button appears only where `navigator.share` exists, and Story Pages that share media download the file instead. - `getAdConfig` runs only for tenants that use Google Ad Manager ads and returns `{ slot, customTargeting?, publisherProvidedId? }` or `null`; Clips requests have no `story` field. - `userNavigatedToApp` handles `inApp` action links; without it those links open like regular URLs. ## When To Use - Use this delegate for global analytics capture, custom share UI, ad integration, or in-app routing. - Set it before `initialize` and before rendering Storyteller views. ## Integration Steps 1. Create one object with the callbacks you need. 2. Assign it to `Storyteller.sharedInstance.delegate` before calling `initialize`. 3. Forward `onUserActivityOccurred(type, data)` to your analytics pipeline. 4. Return a `Promise` from `onShareButtonTapped(text, title, url)` to replace the default share flow; the SDK resumes playback when it settles and records `shareSuccess` when it resolves. 5. Implement `getAdConfig(adRequestInfo)` and follow the Ads guide for the returned object. 6. Implement `userNavigatedToApp(url)` if `inApp` actions should route inside your app. 7. To add a callback later, spread the current delegate: `{ ...Storyteller.sharedInstance.delegate, getAdConfig }`. ## API Cheat Sheet - `Storyteller.sharedInstance.delegate`: Global delegate; each assignment replaces every callback. - `onUserActivityOccurred?: (type: ActivityType, data: UserActivityData) => void`: Receives Storyteller analytics events and optional `data.context`. - `onShareButtonTapped?: (text: string, title: string, url: string) => Promise`: Replaces sharing in the Story and Clips players. - `getAdConfig?: (adRequestInfo: StorytellerAdRequestInfo) => AdConfig | null`: Supplies Google Ad Manager ad configuration for Stories or Clips; `AdConfig` isn't exported. - `userNavigatedToApp?: (url: string) => void`: Handles `inApp` actions inside your app. ## Examples - The assignment snippet shows `Storyteller.sharedInstance.delegate = { ... }`. - The spread snippet adds `getAdConfig` without dropping other callbacks. - The TypeScript interface lists every optional callback. - Storyteller Web Showcase links show each callback and the full delegate in `attachStorytellerDelegate`. ## Cross-References - Integrate Analytics documents the events delivered through `onUserActivityOccurred`. - Integrate Ads documents the ad configuration returned by `getAdConfig()`. - Handle View Callbacks covers per-view loading, dismissal, and back button callbacks. # Handle view callbacks URL: /StorytellerListViewDelegate/ ## Task Summarize the per-view delegates that report loading, player dismissal, and top-level back button taps for rows, grids, and both Clips player views. ## Metadata - Slug: storyteller-list-view-delegate - Source: public-docs/StorytellerListViewDelegate.md - Audience: Engineers instrumenting individual Storyteller views and Clips players - Platforms: Web - Related: Handle Global Callbacks, Configure Views, Add a Clips Player to a Page ## Overview - Rows and grids use the list view delegate (`IListViewDelegate`); `StorytellerClipsPlayerView` and `StorytellerEmbeddedClipsPlayerView` use the Clips player delegate (`IStorytellerClipsPlayerDelegate`) through the same `delegate` property. - Every callback is optional, and assigning `delegate` replaces the view's previous delegate. - `onDataLoadStarted` fires when the view starts loading Stories or Clips. - `onDataLoadComplete(success, error, dataCount)`: `success` is `false` when the request fails or returns no Stories or Clips; `error` is an `Error` (check `error.message`, the classes aren't exported); `dataCount` is the number of Stories, or the Clips in the first page (later pages fire no callbacks; a single-Clip player reports `1`). - `onPlayerDismissed` fires when a player opened from the view is dismissed. - `onTopLevelBackTapped` fires when the Clips player's top back button is tapped with `topLevelBackButtonEnabled = true`; without it the SDK calls `window.history.back()`, and the back button never calls `onPlayerDismissed`. ## When To Use - Attach these delegates for per-view loading states, empty-state handling, telemetry, or cleanup tied to one row, grid, or Clips player. - Use the Clips player delegate when your app should decide what the back button does. ## Integration Steps 1. Create the row, grid, or Clips player view, then assign `view.delegate = { ... }` with the callbacks you need. 2. Implement `onDataLoadStarted` to show loading indicators. 3. Implement `onDataLoadComplete` to hide loaders, log `error.message`, or hide the view when `success` is `false` or `dataCount` is `0`. 4. Implement `onPlayerDismissed` to restore page state when the player closes. 5. For Clips player views, set `topLevelBackButtonEnabled = true` and implement `onTopLevelBackTapped` when your app owns back navigation. ## API Cheat Sheet - `onDataLoadStarted?: () => void`: Fires when the view starts loading content. - `onDataLoadComplete?: (success: boolean, error: Error | null, dataCount: number) => void`: Fires when loading finishes. - `onPlayerDismissed?: () => void`: Fires when a player opened from this view is dismissed. - `onTopLevelBackTapped?: () => void`: Clips player views only; fires when the top back button is tapped. ## Examples - Code samples show `storyRow.delegate = { onDataLoadComplete }` and `clipPlayer.delegate = { onTopLevelBackTapped }`. - The TypeScript interfaces show every optional callback. - The Storyteller Web Showcase's `handleDataLoadComplete` hides a feed module on failure or no content. ## Cross-References - Configure Views explains the view settings these callbacks report on. - Add a Clips Player to a Page covers Clips player initialization, sizing, and the back button. - Handle Global Callbacks covers analytics, sharing, ads, and in-app links from every player. # Use additional SDK methods URL: /AdditionalMethods/ ## Task Document the `Storyteller.sharedInstance` properties and methods for initialization, SDK state, logging, playback control, content counts, and opening or closing players. ## Metadata - Slug: additional-methods - Source: public-docs/AdditionalMethods.md - Audience: Frontend engineers integrating the Storyteller Web SDK - Platforms: Web - Related: Handle Global Callbacks, Configure Views, Open a Player Programmatically, Control Privacy and Tracking ## Overview - Every member on this page is on `Storyteller.sharedInstance`; view methods such as `reloadData` and `destroy` are in Configure Views. - Signatures appear in separate `typescript` blocks, followed by call examples; `await` examples need an `async` function or a JavaScript module. - `delegate` sets the global delegate. `isInitialized`, `isPlayerVisible`, and `version` report SDK state. Each `eventTrackingOptions` assignment replaces every option. - `initialize(apiKey, { externalId })` shares one promise between matching concurrent calls, loads viewing history with the default privacy options, resets the global theme, and rejects with an `Error` whose message starts with the error type (a string when the API key is missing). - `dismissPlayer(animated)` closes the open Story or Clips player but not a `StorytellerEmbeddedClipsPlayerView`. - `disablePlayback()` pauses the open Story and current Clips until `enablePlayback()` allows playback again and resumes them. - `enableLogging()` turns on info, warning, and log messages; errors always log. - `getStoriesCount(categoryIds)` and `getClipsCount(collectionId)` wait for a successful `initialize`; they stay pending while initialization hasn't succeeded and reject when a count request fails. - The open methods (`openStory`, `openStoryByExternalId`, `openPage`, `openCategory`, `openCollection`, `openClipByExternalId`) reject when content can't be opened; `openCollection` accepts only `Storyteller.OpenedReason.deepLink` as its reason. - Deprecated members: `openClip`, `enableEventTracking`, `disableEventTracking`, and `currentUserId`. ## When To Use - Call `initialize` before other methods, and read `isInitialized`, `isPlayerVisible`, or `version` when gating UI. - Call `dismissPlayer`, `disablePlayback`, `enablePlayback`, or an `open*` method when your page should control Storyteller playback. - Use `enableLogging()` while debugging and `eventTrackingOptions` when consent changes. - Use the count methods before creating an optional Story or Clips view; load a primary view directly to avoid an extra request. ## Integration Steps 1. Assign `Storyteller.sharedInstance.delegate = { ... }` if you need global callbacks. 2. Call `enableLogging()` first when debugging, then await `initialize(apiKey, { externalId })` and handle rejections. 3. Read `isInitialized`, `isPlayerVisible`, and `version` when gating UI. 4. Set `eventTrackingOptions` with every option when consent or privacy requirements change. 5. Await `getStoriesCount` or `getClipsCount` when optional UI depends on available content. 6. Await the `open*` methods and handle rejections for missing content. 7. Call `dismissPlayer(true)` to close the open player, or `disablePlayback()` / `enablePlayback()` when other media covers Storyteller content. ## API Cheat Sheet - `Storyteller.sharedInstance.delegate`: Global delegate; see Handle Global Callbacks. - `isInitialized: boolean` / `isPlayerVisible: boolean` / `version: string`: SDK state. - `eventTrackingOptions`: Privacy and tracking options; see Control Privacy and Tracking. - `initialize(apiKey: string, userInput?: { externalId?: string | null }): Promise`: Initializes the SDK for an API key and user. - `dismissPlayer(animated: boolean): void`: Closes the open Story or Clips player; no effect when nothing is open or on the embedded Clips player. - `disablePlayback(): void` / `enablePlayback(): void`: Pause and allow Story and Clip playback. - `enableLogging(): void`: Turns on console logging. - `getStoriesCount(categoryIds: string[]): Promise`: Combined Story count for the Categories; `[]` returns `0` without a request. - `getClipsCount(collectionId: string): Promise`: Clip count for one collection. - `openStory(id: string)` / `openStoryByExternalId(externalId: string)` / `openPage(pageId: string)`: Open a Story or Page; `Promise`. - `openCategory(categoryId: string, storyId?: string): Promise`: Opens a Category, falling back to the first Story when `storyId` is missing or not found. - `openCollection(collectionId: string, destination?: { categoryId?: string; clipId?: string }, openedReason?: OpenedReason.deepLink): Promise`: Opens a collection, optionally at a Clip or Category; falls back to the first Clip. - `openClipByExternalId(collectionId: string, externalId: string): Promise`: Opens a Clip by external ID inside a collection. ## Examples - The initialize example uses `try`/`catch` with `demo-api-key` and `your-user-id`. - The count example initializes, counts one Category, and creates the row only when the count is above `0`. - Each `open*` example awaits the returned promise. ## Pitfalls / Notes - Wrap every `open*` call in `try`/`catch` or `.catch(...)`; rejections can be an `Error` or a string. - Count promises never settle if `initialize` never succeeds. - `initialize` resets `Storyteller.sharedInstance.theme`; set the global theme after it resolves. ## Cross-References - Handle Global Callbacks explains the global delegate. - Open a Player Programmatically shows the open methods as tasks. - Configure Views documents view methods such as `reloadData` and `destroy`. - Control Privacy and Tracking defines `eventTrackingOptions`.