Skip to content

Custom Attributes#

One of the features of Storyteller is the ability to set custom attributes for requests. Use attributes agreed with your Storyteller content configuration for audience targeting, personalization and analytics context.

How to Use#

Set custom attribute#

To set a custom attribute, you can use the setCustomAttribute() method of the StorytellerSdk object. This method takes two parameters: the key of the custom attribute and its value. For example, to set a custom attribute for the user's location, you can use the following code:

StorytellerSdk.setCustomAttribute('location', 'New York');

This stores the attribute for SDK requests that use user attributes. Attribute values do not change the app’s device location or system settings.

Custom attribute values must be strings. Convert non-string values to strings before setting them. Use consistent lowercase keys across platforms: iOS normalizes keys to lowercase, while Android preserves their case. Use setLocale() for the reserved locale attribute.

// String values only
StorytellerSdk.setCustomAttribute('location', 'New York');
StorytellerSdk.setCustomAttribute('age', String(25));
StorytellerSdk.setCustomAttribute('isPremium', String(true));

Setting custom attributes should be done after the Storyteller SDK is initialized.

Replace custom attributes#

To replace the full custom attribute map, use setCustomAttributes() with string keys and values:

StorytellerSdk.setCustomAttributes({
  location: 'New York',
  tier: 'premium',
});

Get custom attributes#

To retrieve all custom attributes, you can use the customAttributes() method. This method returns a Promise that resolves to an object containing all custom attributes:

try {
  const attributes = await StorytellerSdk.customAttributes();
  console.log(attributes); // { location: "New York", age: "25", isPremium: "true" }
} catch (error) {
  console.error('Failed to get custom attributes:', error);
}

Remove custom attribute#

To remove a custom attribute, you can use the removeCustomAttribute() method of the StorytellerSdk object. This method takes one parameter: the key of the custom attribute to remove. For example, to remove the custom attribute for the user's location, you can use the following code:

StorytellerSdk.removeCustomAttribute('location');

Best Practices#

  • Timing: Set custom attributes after SDK initialization and before loading any content views
  • Privacy: Ensure custom attributes comply with your privacy policy and relevant regulations (GDPR, CCPA, etc.)
  • Size: Keep values small and relevant to your content configuration

Followable Categories#

Storyteller provides a mechanism for managing followed categories associated with Clips. These are content category identifiers, not arbitrary custom-attribute keys. The tenant must be configured for the integrating app to manage following; app mutation methods have no effect when Storyteller manages following. On Android, setFollowedCategories() also requires personalization to be enabled.

How to Use#

Set followed categories#

To set a followed category, call the addFollowedCategory() function for a singular category or addFollowedCategories() for a collection. Access these methods through the StorytellerSdk object. For instance, to designate a followed category attribute for the user, implement the following code:

StorytellerSdk.addFollowedCategory('team-id');

or

StorytellerSdk.addFollowedCategories(['team-id', 'league-id']);

The native SDK resolves category metadata and updates follow state and personalization attributes. Use identifiers from your followable-category catalog. Unknown category identifiers can be omitted from a replacement.

Manage followed categories after initialization. The add/remove helpers return void while native work runs asynchronously; do not use their return as a completion signal. Use the awaited replacement method when content refresh must follow the completed update.

When your app owns the complete followed-category list, use setFollowedCategories() to replace the current set atomically. The Promise resolves after native category metadata and personalization state have been updated, so it can be awaited before reloading content:

try {
  await StorytellerSdk.setFollowedCategories(['team-id', 'league-id']);
} catch (error) {
  console.error('Failed to replace followed categories', error);
}

Passing an empty array clears the app-managed followed set when the configuration requirements above are met. The Promise can resolve without changing anything when app-managed following is disabled (or Android personalization is disabled). Use the existing add/remove helpers for incremental changes.

Remove followable category#

To remove a followed category, utilize the removeFollowedCategory() method of the StorytellerSdk object. This method requires a single parameter—the key of the followed category to be removed. For example, to remove a followable category for a team, utilize the following code:

StorytellerSdk.removeFollowedCategory('team-id');

This function accepts a singular string parameter, removing the specified category from the locally stored list.

To remove multiple followed categories at once, use removeFollowedCategories():

StorytellerSdk.removeFollowedCategories(['team-id', 'league-id']);

Check if a category is followed#

To check whether a category is currently followed, use isCategoryFollowed():

const isFollowing = StorytellerSdk.isCategoryFollowed('team-id');

Get followed categories#

To get a list of currently followed categories, utilize the followedCategories() method. This method returns a Promise that resolves to an array of followed category strings:

try {
  const categories = await StorytellerSdk.followedCategories();
  console.log(`Followed categories: ${categories}`);
} catch (error) {
  console.error('Failed to get followed categories:', error);
}

Get followable categories#

To fetch the backend-backed category catalog with current follow state, use getFollowableCategories(). This is useful when building your own category management UI:

import type {
  StorytellerFollowableCategories,
  StorytellerFollowableCategory,
  StorytellerFollowableCategoryPlacement,
} from '@getstoryteller/react-native-storyteller-sdk';

try {
  const { categories }: StorytellerFollowableCategories = await StorytellerSdk.getFollowableCategories();
  categories.forEach(category => {
    console.log(category.id, category.displayTitle ?? category.name, category.isFollowed);
  });
} catch (error) {
  console.error('Failed to get followable categories:', error);
}

Each category can include id, name, displayTitle, externalId, type, placement, thumbnailUrl, and isFollowed.

StorytellerFollowableCategory and StorytellerFollowableCategoryPlacement are exported for apps that store or render this metadata. The category string fields are optional because the native iOS and Android models have different nullability guarantees; always use id as the stable required identifier.

Get updates about followed categories#

Followed categories can be updated as a result of user actions from within the Storyteller SDK. You can listen to these event updates through the categoryFollowActionTaken event emitter:

On iOS 11.6.0+, the event's category.description field is included when the backend supplies a category description. The field is optional so existing integrations and categories without descriptions remain unchanged.

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 null; // Render your app UI here.
}

For more details, see Storyteller Event Handlers.