Skip to content

Configuring Storyteller#

Prerequisites#

Important: The initialize() method must be called before using any other Storyteller SDK methods or components. Call this method as early as possible in your app lifecycle (typically in your root component or App.tsx).

Core SDK Methods#

Initialization#

initialize(apiKey: string, externalId?: string): Promise<void>#

Initializes the Storyteller SDK with your API key and optional user identifier.

Parameters:

  • apiKey - API key provided by the Storyteller team
  • externalId - (Optional) External ID of the user for personalization and analytics

Example:

try {
  await StorytellerSdk.initialize('YOUR_API_KEY', 'user-123');
  console.log('SDK ready');
} catch (error) {
  console.error('Initialization failed:', error);
}

Status & Information#

isInitialized(): boolean#

Checks if Storyteller has been successfully initialized.

isPresentingContent(): boolean#

Returns whether any Storyteller content (stories, pages, clips, sheets) is currently being presented. Useful to avoid opening new content while something else is on screen.

Example:

if (!StorytellerSdk.isPresentingContent()) {
  await StorytellerSdk.openStory('story-id-123');
}

currentApiKey(): string#

Returns the current API key.

version(): string#

Returns the current SDK version.

Theming#

setTheme(theme: Theme): void#

Customizes the appearance of the SDK. Pass a Theme object of shape { light: Partial<ThemeType>, dark: Partial<ThemeType> }. Each mode accepts partial overrides. This sets the default fallback theming style used to render Story items in lists and activities launched from a list. For more information, see Themes.

Localization#

setLocale(locale: string): void#

Sets the SDK locale for localized content. Provide a locale string in BCP 47 format (e.g., "en-US", "es-ES", "fr-FR").

Example:

StorytellerSdk.setLocale('en-US');

Deep links allow you to open specific Storyteller content programmatically. These methods open Stories or Clip Collections independently from list components rendered in your app. For more information, see Deep Links.

openStory(id: string): Promise<void>#

Opens a Story by its Storyteller ID (internal ID from Storyteller CMS).

Parameters:

  • id - Story ID from Storyteller

Example:

try {
  await StorytellerSdk.openStory('story-id-123');
} catch (error) {
  console.error('Failed to open story:', error);
}

openStoryByExternalId(externalId: string): Promise<void>#

Opens a Story by its external ID (custom ID set by your organization). Use this when you want to reference stories using your own ID system.

Parameters:

  • externalId - Your custom external ID for the story

Example:

try {
  await StorytellerSdk.openStoryByExternalId('my-story-123');
} catch (error) {
  console.error('Failed to open story by external ID:', error);
}

openPage(id: string): Promise<void>#

Opens a Story Page (multi-story experience) by its ID.

Parameters:

  • id - Page ID from Storyteller

openCategory(category: string): Promise<void>#

Opens all Stories in a specific category.

Parameters:

  • category - Category name/tag

openCollection(id: string, clipId?: string): Promise<void>#

Opens a Clip Collection, optionally starting from a specific clip.

Parameters:

  • id - Collection ID
  • clipId - (Optional) Specific clip ID to start from

Example:

// Open collection from the beginning
await StorytellerSdk.openCollection('collection-123');

// Open collection starting from a specific clip
await StorytellerSdk.openCollection('collection-123', 'clip-456');

openClipByExternalId(collectionId: string, externalId: string): Promise<void>#

Opens a specific clip within a collection using external IDs.

Parameters:

  • collectionId - Collection external ID
  • externalId - Clip external ID

openSearch(): void#

Opens the Storyteller search interface, allowing users to search through available content.

isSearchEnabled(): boolean#

Checks if search is available for the current API key and configuration. Use this to conditionally show a Search button.

Example:

if (StorytellerSdk.isSearchEnabled()) {
  StorytellerSdk.openSearch();
}

openSheet(id: string): Promise<void>#

Opens a Sheet by its ID. Sheets are bottom or full-screen surfaces used to show additional content and actions.

Parameters:

  • id - Sheet ID from Storyteller

Example:

try {
  await StorytellerSdk.openSheet('sheet-id-123');
} catch (e) {
  console.warn('Failed to open sheet', e);
}

openCollectionWithCategory(id: string, category?: string): Promise<void>#

Opens a Clip Collection with an optional category context.

Parameters:

  • id - Collection ID
  • category - (Optional) Category identifier to scope the collection

Example:

await StorytellerSdk.openCollectionWithCategory('collection-123', 'sports');

Content Counts#

Methods to query counts for UI badges, tabs, or prefetch logic.

getStoriesCount(categoryIds: string[]): Promise<number>#

Returns the number of available stories for the specified categories.

Parameters:

  • categoryIds - Array of category identifiers

Example:

const count = await StorytellerSdk.getStoriesCount(['news', 'sports']);
setStoriesBadge(count);

getClipsCount(collectionId: string): Promise<number>#

Returns the number of clips available in the specified collection.

Parameters:

  • collectionId - Collection identifier

Example:

const clips = await StorytellerSdk.getClipsCount('collection-123');
console.log('Clips available:', clips);

Player Control#

dismissPlayer(animated: boolean, reason: string): void#

Programmatically closes the currently open Story player.

Parameters:

  • animated - Whether to animate the dismissal
  • reason - Reason for dismissal (for analytics)

Example:

StorytellerSdk.dismissPlayer(true, 'user_action');

resumePlayer(): void#

Resumes playback after the player has been paused due to overlays, app lifecycle changes, or custom logic.

Example:

// When your overlay/modal closes or app regains focus
StorytellerSdk.resumePlayer();

Custom Attributes#

Custom attributes allow you to associate metadata with users for personalization and targeting. For more information, see User Customization.

Followable Categories#

Followable categories allow you to associate metadata with users for personalization and targeting. For more information, see User Customization.

Ads Integration#

For more information on integrating ads, see Ads.

Event Handling#

The Storyteller SDK emits events for user interactions, navigation, and ad requests. With React Native's New Architecture, these events are exposed as callable EventEmitter functions on the StorytellerSdk object.

Important: Always remove event listeners when components unmount to prevent memory leaks.

Available Events#

The SDK provides four event emitters:

  • onUserActivityOccurred - Fires for all user engagement events (views, taps, swipes, completions, etc.)
  • userNavigatedToApp - Fires when user taps an action button that navigates to your app
  • categoryFollowActionTaken - Fires when user follows or unfollows a category
  • getAdsForList - Fires when SDK requests ads for stories or clips

Event Subscription Pattern#

Each event emitter is a function that accepts a callback and returns a subscription object with a remove() method:

const subscription = StorytellerSdk.eventName((event) => {
  // Handle event
});

// Clean up when done
subscription.remove();

Event Examples#

1. User Activity Tracking#

Track all user interactions within the Storyteller experience:

import { useEffect } from 'react';
import StorytellerSdk from '@getstoryteller/react-native-storyteller-sdk';

function MyComponent() {
  useEffect(() => {
    const subscription = StorytellerSdk.onUserActivityOccurred((event) => {
      console.log('Event type:', event.type);
      console.log('Event data:', event.data);

      // Send to your analytics service
      analytics.track(event.type, event.data);
    });

    return () => {
      subscription.remove(); // Cleanup
    };
  }, []);

  return (/* ... */);
}

2. App Navigation Events#

Handle when users tap action buttons that navigate to your app:

import { useEffect } from 'react';
import { Alert } from 'react-native';
import StorytellerSdk from '@getstoryteller/react-native-storyteller-sdk';

function MyComponent() {
  useEffect(() => {
    const subscription = StorytellerSdk.userNavigatedToApp((event) => {
      console.log('Navigation URL:', event.url);

      // Parse the URL and navigate within your app
    });

    return () => {
      subscription.remove();
    };
  }, []);

  return (/* ... */);
}

3. Category Follow/Unfollow Events#

Track when users follow or unfollow categories:

import { useEffect } from 'react';
import StorytellerSdk from '@getstoryteller/react-native-storyteller-sdk';

function MyComponent() {
  useEffect(() => {
    const subscription = StorytellerSdk.categoryFollowActionTaken((event) => {
      console.log('Category:', event.category.name);
      console.log('Is Following:', event.isFollowing);

      // handle the follow/unfollow action
    });

    return () => {
      subscription.remove();
    };
  }, []);

  return (/* ... */);
}

4. Ad Request Events#

Handle ad requests for client-side ad integration

For complete ad integration details, see Ads.

Privacy & Analytics#

Event Tracking Options#

The eventTrackingOptions property customizes Storyteller's analytics and tracking behavior. This is an object of type StorytellerEventTrackingOptions which allows certain features to be disabled based on user privacy choices and regulatory requirements.

Note: By default, all tracking options are enabled.

Methods#

eventTrackingOptions(): Promise<StorytellerEventTrackingOptions>#

Retrieves the current tracking options configuration.

Example:

const options = await StorytellerSdk.eventTrackingOptions();
console.log('Tracking enabled:', options.enableStorytellerTracking);
setEventTrackingOptions(options: StorytellerEventTrackingOptions): void#

Updates the tracking options configuration.

Parameters:

  • options - Partial or complete StorytellerEventTrackingOptions object

Examples:

// Disable all tracking for privacy-focused users
StorytellerSdk.setEventTrackingOptions({
  enablePersonalization: false,
  enableStorytellerTracking: false,
  enableUserActivityTracking: false,
  enableAdTracking: false,
  enableFullVideoAnalytics: false,
  enableRemoteViewingStore: false,
});

// Only disable personalization (GDPR opt-out)
StorytellerSdk.setEventTrackingOptions({
  enablePersonalization: false,
});

// Disable specific functional features (optional)
StorytellerSdk.setEventTrackingOptions({
  disabledFeatures: ['clipLikes', 'pollVotes'],
});

API Reference#

Type Definitions#

Recommended imports to use SDK types directly and avoid drift:

import type {
  Theme,
  StorytellerEventTrackingOptions,
  DataLoadCompletedEvent,
  Category,
  ItemInfo,
  StoriesGridDimensionsState,
} from '@getstoryteller/react-native-storyteller-sdk';
import { EventType } from '@getstoryteller/react-native-storyteller-sdk';
interface StorytellerEventTrackingOptions {
  enablePersonalization?: boolean;
  enableStorytellerTracking?: boolean;
  enableUserActivityTracking?: boolean;
  enableAdTracking?: boolean;
  enableFullVideoAnalytics?: boolean;
  enableRemoteViewingStore?: boolean;
  disabledFeatures?: string[]; // e.g., ['all', 'clipLikes', 'pollVotes']
}

interface CustomAttributesResult {
  [key: string]: string;
}

// Selected exported types (see package exports for the complete definitions)
interface Category {
  name: string;
  externalId: string;
  displayTitle: string;
  type: string;
  placement: string;
}

interface ItemInfo {
  id: string;
  categories: Category[];
}

interface AdRequestInfo {
  stories?: {
    placement: string;
    categories: string[];
    story: ItemInfo;
  };
  clips?: {
    collection: string;
    clip: ItemInfo;
  };
}

// EventType is an enum exported from the SDK (e.g., 'openedStory', 'dismissedStory', ...)
// UserActivityData is a structured object; see Analytics.md for field documentation

Summary of All Methods#

Method Return Type Description
initialize(apiKey, externalId?) Promise<void> Initialize SDK
isInitialized() boolean Check if initialized
isPresentingContent() boolean Check if any content is presenting
currentApiKey() string Get current API key
version() string Get SDK version
setTheme(theme: Theme) void Apply custom theme
setLocale(locale: string) void Set SDK locale
isStorytellerDeeplink(url) boolean Validate deeplink URL
openDeeplink(url) Promise<void> Open deeplink
openStory(id) Promise<void> Open story by ID
openStoryByExternalId(externalId) Promise<void> Open story by external ID
openPage(id) Promise<void> Open story page
openSheet(id) Promise<void> Open sheet by ID
openCategory(category) Promise<void> Open category
openCollection(id, clipId?) Promise<void> Open collection
openCollectionWithCategory(id, category?) Promise<void> Open collection for a category
openClipByExternalId(collectionId, externalId) Promise<void> Open clip by external ID
openSearch() void Open search interface
isSearchEnabled() boolean Check if search is enabled
dismissPlayer(animated, reason) void Close player
resumePlayer() void Resume a paused player
setCustomAttribute(key, value) void Set user attribute
removeCustomAttribute(key) void Remove user attribute
customAttributes() Promise<CustomAttributesResult> Get all attributes
addFollowedCategory(category) void Follow category
addFollowedCategories(categories) void Follow multiple categories
removeFollowedCategory(category) void Unfollow category
followedCategories() Promise<string[]> Get followed categories
getStoriesCount(categoryIds) Promise<number> Get count of stories for categories
getClipsCount(collectionId) Promise<number> Get count of clips in a collection
eventTrackingOptions() Promise<StorytellerEventTrackingOptions> Get tracking options
setEventTrackingOptions(options) void Set tracking options

Legacy Storyteller Methods (<v10.x)#

interface StorytellerSdkInterface
  extends NativeModulesStatic,
    NativeModule,
    EventSubscriptionVendor {
  isInitialized(callback: ({result}: {result: boolean}) => void): void;
  isStorytellerDeeplink(url: string, callback: (result: {result: boolean}) => void): void;
  currentUserId(callback: ({result}: {result: string}) => void): void;
  currentApiKey(callback: ({result}: {result: string}) => void): void;
  version(callback: ({result}: {result: string}) => void): void;

  setTheme(theme: Partial<Theme>): void;

  openDeeplink(url: string, callback: (result: boolean) => void): void;
  openStory(id: string, errorCallback: (error: string) => void): void;
  openPage(id: string, errorCallback: (error: string) => void): void;
  openCategory(category: string, errorCallback: (error: string) => void): void;
  openStoryByExternalId(
    id: string,
    errorCallback: (error: string) => void
  ): void;
  openClipByExternalId(
    collectionId: string,
    externalId: string,
    errorCallback: (error: string) => void
  ): void;
  openCollection(
    id: string,
    clipId?: string,
    errorCallback?: (error: string) => void
  ): void;
  openSearch(): void;

  eventTrackingOptions(callback: (options: StorytellerEventTrackingOptions) => void): void;
  setEventTrackingOptions(options: StorytellerEventTrackingOptions): void;

  dismissPlayer(animated: boolean, reason: string): void;

  setCustomAttribute(key: string, value: string): void;
  removeCustomAttribute(key: string): void;
  customAttributes(
    callback: (result: { [key: string]: string | number | boolean }) => void
  ): void;

  setLocale(locale?: string): void;
  addFollowedCategory(category: string): void;
  addFollowedCategories(categories: string[]): void;
  removeFollowedCategory(category: string): void;
  followedCategories(callback: (categories: string[]) => void): void;

  initialize(
    data: {
      apiKey: string;
      externalId?: string | null;
    },
    callback: (callback: { result: boolean; message: string }) => void
  ): void;
};

Event Handlers#

Event Handler Callback Parameter Description
onUserActivityOccurred(callback) (event: { type: EventType, data: UserActivityData }) => void Subscribe to user activity events
userNavigatedToApp(callback) (event: { url: string }) => void Subscribe to app navigation events
categoryFollowActionTaken(callback) (event: { category: Category, isFollowing: boolean }) => void Subscribe to category follow/unfollow events
getAdsForList(callback) (adRequest: AdRequestInfo) => void Subscribe to ad request events

All event handlers return a subscription object with a remove() method for cleanup.