To get SDK token go to app settings page and copy SDK token:
Installation
NPM
npm install @storysdk/core
Yarn
yarn add @storysdk/core
Basic Usage
React
To integrate StorySDK in a React application:
import { Story } from "@storysdk/core";
import "@storysdk/core/dist/bundle.css";
import { useRef, useEffect } from "react";
function StoryComponent() {
const ref = useRef(null);
useEffect(() => {
const story = new Story("<APP_TOKEN_HERE>");
const element = ref.current;
story.renderGroups(element);
// Cleanup function
return () => {
story.destroy();
};
}, []);
return <div ref={ref} style={{ minHeight: "100px" }}></div>;
}
export default StoryComponent;
Next.js
When using StorySDK with Next.js, you need to load the component dynamically without server-side rendering:
// In your page or component file
import { useRef, useEffect } from 'react';
import dynamic from 'next/dynamic';
// Import CSS statically
import '@storysdk/core/dist/bundle.css';
// Dynamically import the StoryComponent with SSR disabled
const StoryComponent = dynamic(
() => import('../components/StoryComponent'),
{ ssr: false }
);
function HomePage() {
return (
<div>
<h1>My Next.js App</h1>
<StoryComponent token="<APP_TOKEN_HERE>" />
</div>
);
}
export default HomePage;
Then in your component file (components/StoryComponent.js):
import { useRef, useEffect } from 'react';
function StoryComponent({ token, options = {} }) {
const ref = useRef(null);
useEffect(() => {
// Only import and initialize the Story SDK on the client side
const { Story } = require('@storysdk/core');
const story = new Story(token, options);
const element = ref.current;
if (element) {
story.renderGroups(element);
}
return () => {
story.destroy();
};
}, [token, options]);
return <div ref={ref} style={{ minHeight: "100px" }}></div>;
}
export default StoryComponent;
JavaScript (ES6)
For vanilla JavaScript applications:
import { Story } from "@storysdk/core";
import "@storysdk/core/dist/bundle.css";
document.addEventListener("DOMContentLoaded", () => {
const story = new Story("<APP_TOKEN_HERE>");
const element = document.querySelector("<SELECTOR_HERE>");
story.renderGroups(element);
});
Static HTML
For static HTML pages:
<head>
<script src="https://cdn.jsdelivr.net/npm/@storysdk/core@latest/dist/bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@storysdk/core@latest/dist/bundle.css">
</head>
<body>
<div
data-storysdk-token="<APP_TOKEN_HERE>"
style="min-height: 100px;"
id="storysdk"
></div>
<script>
document.addEventListener("DOMContentLoaded", function() {
// The SDK will automatically initialize using the data-storysdk-token attribute
// The SDK instance is automatically created and available globally as window.storysdk
// You can access the story instance methods directly:
console.log(window.storysdk); // Access the Story instance
// Example: Subscribe to events using the global instance
window.storysdk.on('storyOpen', function(event) {
console.log('Story opened:', event);
});
});
</script>
</body>
Available Parameters
By specifying the following data attributes in the HTML tag, you can control the appearance, behavior, and functionality of the SDK directly from HTML without additional JavaScript configuration.
Parameter
Description
data-storysdk-group-image-width
Specifies the width of the group image in pixels, controlling how large the group's main image will appear.
data-storysdk-group-image-height
Sets the height of the group image, allowing you to control the image's vertical display size.
data-storysdk-group-title-size
Adjusts the font size of the group title, so you can set the desired emphasis for the group title text.
data-storysdk-group-class-name
Allows a custom CSS class to be applied to the individual group elements. Use this to apply unique styling to each group.
data-storysdk-groups-class-name
Adds a custom CSS class to the container for multiple groups. This is useful for controlling overall styling for the collection of groups.
data-storysdk-autoplay
Enables autoplay for stories if set to "true". The stories will play automatically without requiring user interaction.
data-storysdk-group-id
Identifies a specific group ID to load within the SDK, allowing targeted display of group content when autoplay is enabled.
data-storysdk-start-story-id
Sets the initial story to display when the SDK opens, letting you direct users to a specific story.
data-storysdk-forbid-close
Prevents users from closing the SDK interface if set to "true". Useful for mandatory viewing scenarios.
data-storysdk-is-show-mockup
Displays the story content within a device mockup if set to "true", providing a preview within a simulated device frame.
data-storysdk-is-status-bar-active
Activates a status bar at the top of the story if set to "true", helping indicate story progress.
data-storysdk-open-in-external-modal
Opens stories within an external modal if set to "true". This is useful if you want to display content in a standalone modal overlay.
data-storysdk-groups-outline-color
Specifies a custom outline color for groups. This is useful for visually highlighting or differentiating specific groups within the interface.
data-storysdk-active-group-outline-color
Specifies a custom outline color for the active group or for the group when hovered over. This helps emphasize the currently selected or focused group in the interface.
⚡️ Please note that in order for stories to be displayed in the SDK, they need to be published.
API Reference
Story Class
The main class for interacting with the StorySDK.
Constructor
const story = new Story(token, options);
Parameters:
token (string, required): Your application token provided by StorySDK
options (object, optional): Configuration options for StorySDK
Options
{
// Appearance options
groupImageWidth?: number; // Width of group thumbnail images
groupImageHeight?: number; // Height of group thumbnail images
groupTitleSize?: number; // Font size for group titles
activeGroupOutlineColor?: string; // Color of the outline for active group
groupsOutlineColor?: string; // Color of the outline for inactive groups
arrowsColor?: string; // Color of navigation arrows
backgroundColor?: string; // Background color
// Layout options
storyWidth?: number; // Width of story viewer (only 360 is supported)
storyHeight?: number; // Height of story viewer (only 640 or 780 are supported)
isShowMockup?: boolean; // Show device mockup around story
isShowLabel?: boolean; // Show labels
isStatusBarActive?: boolean; // Show status bar
// Behavior options
autoplay?: boolean; // Automatically play stories
forbidClose?: boolean; // Prevent user from closing the story
openInExternalModal?: boolean; // Open stories in a modal
// Selection options
groupId?: string; // Initial group ID to display
startStoryId?: string; // Initial story ID to display
// CSS classes
groupClassName?: string; // Custom CSS class for individual groups
groupsClassName?: string; // Custom CSS class for the groups container
// Development options
isDebugMode?: boolean; // Enable debug mode
}
Methods
renderGroups(container)
Renders story groups in the specified element.
Parameters:
container (HTMLElement, optional): The DOM element to render stories in. If not provided, the container specified during initialization will be used.
Returns: void
destroy()
Cleans up resources used by the Story instance, unmounting React components.
Returns: void
on<T = any>(eventName, listener)
Subscribes to a story event.
Parameters:
eventName (StoryEventTypes): Name of the event to subscribe to
listener (function): Callback function to execute when the event occurs
Returns: Function to unsubscribe from the event
off<T = any>(eventName, listener)
Removes a specific event listener.
Parameters:
eventName (StoryEventTypes): Name of the event
listener (function): The listener function to remove
Returns: void
once<T = any>(eventName, listener)
Subscribes to an event for one time only. The listener automatically unsubscribes after being called once.
Parameters:
eventName (StoryEventTypes): Name of the event to subscribe to
listener (function): Callback function to execute when the event occurs
Returns: Function to unsubscribe from the event
Event Handling
StorySDK uses a TypeScript-based event system for handling interactions with stories. You can subscribe to these events using the on method:
import { Story, StoryEventTypes } from "@storysdk/core";
const story = new Story("<APP_TOKEN_HERE>");
// Subscribe to widget click events
story.on(StoryEventTypes.WIDGET_CLICK, (event) => {
console.log("Widget clicked:", event);
});
// Subscribe to story open events - using once for one-time handling
story.once(StoryEventTypes.STORY_OPEN, (event) => {
console.log("Story opened (will only log once):", event);
});
// You can also store the unsubscribe function
const unsubscribe = story.on(StoryEventTypes.STORY_NEXT, (event) => {
console.log("Next story:", event);
});
// Later, you can unsubscribe
unsubscribe();
// Alternatively, use the off method directly
const onPrevHandler = (event) => {
console.log("Previous story:", event);
};
story.on(StoryEventTypes.STORY_PREV, onPrevHandler);
// Later, remove the handler
story.off(StoryEventTypes.STORY_PREV, onPrevHandler);
groupClose: When a story group is closed (provides group ID, user ID, viewing duration in seconds, and language)
groupOpen: When a story group is opened (provides user ID, group ID, start time, and language)
storyClose: When a story is closed (provides group ID, story ID, user ID, viewing duration, and language)
storyOpen: When a specific story is opened (provides group ID, story ID, user ID, and language)
storyNext: When navigating to the next story (provides group ID, story ID, user ID, and language)
storyPrev: When navigating to the previous story (provides group ID, story ID, user ID, and language)
widgetAnswer: When a user responds to an interactive widget (polls, quizzes, etc.)
widgetClick: When a widget within a story is clicked (buttons, links, swipe up actions)
Widget Click Event
The widgetClick event is fired when a user interacts with clickable elements in a story. The event provides detailed information about the interaction through its payload.
Event Structure
interface WidgetClickEvent {
detail: {
widget: 'button' | 'link' | 'swipe_up'; // Type of widget that was clicked
actionType?: string; // Present for button widgets, indicates the action type
userId: string; // Unique user identifier
storyId: string; // ID of the story containing the widget
widgetId: string; // ID of the clicked widget
data: {
url?: string; // URL to navigate to (if applicable)
storyId?: string; // Target story ID (for navigation between stories)
customFields?: Record<string, any>; // Additional custom data (for buttons only)
}
}
}
Example Usage
import { Story, StoryEventTypes } from "@storysdk/core";
const story = new Story("<APP_TOKEN_HERE>");
// Listen for widget click events
story.on(StoryEventTypes.WIDGET_CLICK, (event) => {
console.log("Widget type:", event.detail.widget);
// Handle different widget types
switch(event.detail.widget) {
case 'button':
console.log("Button clicked:", event.detail.widgetId);
console.log("Action type:", event.detail.actionType);
console.log("Custom fields:", event.detail.data.customFields);
break;
case 'link':
console.log("Link clicked:", event.detail.widgetId);
console.log("URL:", event.detail.data.url);
break;
case 'swipe_up':
console.log("Swipe up action triggered");
console.log("URL:", event.detail.data.url);
break;
}
// You can also track these events in your analytics system
trackWidgetInteraction(event.detail);
});
Implementation Notes
Button widgets include an actionType field and may contain customFields for additional context
Link widgets provide the target URL in the data.url field
Swipe up actions are similar to links but represent a different user interaction pattern
All widget events include user, story, and widget identifiers for comprehensive tracking
Widget Answer Event
The widgetAnswer event is fired when a user responds to an interactive widget. This event provides data about the user's response.
Supported Widget Types
The widgetAnswer event is available for the following widget types:
interface WidgetAnswerEvent {
detail: {
widget: WidgetTypes; // Type of interactive widget from the enum above
userId: string; // Unique user identifier
storyId: string; // ID of the story containing the widget
widgetId: string; // ID of the widget that received the answer
data: {
answer: any; // The user's response/selection
}
}
}
Example Usage
import { Story, StoryEventTypes } from "@storysdk/core";
const story = new Story("<APP_TOKEN_HERE>");
// Listen for widget answer events
story.on(StoryEventTypes.WINDGET_ANSWER, (event) => {
console.log("Widget type:", event.detail.widget);
console.log("User's answer:", event.detail.data.answer);
// You can handle different widget types
switch(event.detail.widget) {
case 'slider':
console.log("Slider value selected:", event.detail.data.answer);
break;
case 'quiz_one_answer':
console.log("Quiz answer submitted:", event.detail.data.answer);
// Check if answer is correct and provide feedback
break;
case 'emoji_reaction':
console.log("Emoji reaction:", event.detail.data.answer);
break;
// Handle other interactive widget types
}
// Store user response for analytics or personalization
saveUserResponse(event.detail.userId, event.detail.widgetId, event.detail.data.answer);
});
Implementation Notes
The widget field identifies the specific type of interactive element from the WidgetTypes enum
The answer field can contain various data types depending on the widget (string, number, object, array)
This event is useful for:
Collecting user feedback
Building personalization features
Creating dynamic, interactive story experiences
Analyzing user engagement with interactive elements
Group Open Event
The groupOpen event is fired when a user opens a story group. This event provides information about which group was opened and by whom.
Event Structure
interface GroupOpenEvent {
detail: {
uniqUserId: string; // Unique identifier for the user
groupId: string; // ID of the story group that was opened
startTime: number; // Timestamp when the group was opened
language: string; // Language setting for the content
}
}
Example Usage
import { Story, StoryEventTypes } from "@storysdk/core";
const story = new Story("<APP_TOKEN_HERE>");
// Listen for group open events
story.on(StoryEventTypes.GROUP_OPEN, (event) => {
console.log("Group opened:", event.detail.groupId);
console.log("User:", event.detail.uniqUserId);
console.log("Time:", new Date(event.detail.startTime).toLocaleString());
console.log("Language:", event.detail.language);
// You can use this event to:
// 1. Track user engagement
trackGroupView(event.detail.uniqUserId, event.detail.groupId);
// 2. Calculate viewing session duration (when combined with GROUP_CLOSE)
startViewingSession(event.detail.groupId, event.detail.startTime);
// 3. Adapt content based on language
if (event.detail.language !== userPreferredLanguage) {
// Suggest language change or record language preference
}
});
Implementation Notes
The startTime is provided as a numeric timestamp which can be converted to a Date object
The language field can be used for analytics or to ensure proper localization
This event is typically paired with groupClose to track complete interaction sessions
This event is useful for:
Monitoring which story groups are most popular
Analyzing user behavior patterns
Building recommendation engines based on user preferences
Group Close Event
The groupClose event is fired when a user closes a story group. This event provides information about which group was closed and how long the user interacted with it.
Event Structure
interface GroupCloseEvent {
detail: {
groupId: string; // ID of the story group that was closed
uniqUserId: string; // Unique identifier for the user
duration: number; // Duration in seconds that the group was viewed
language: string; // Language setting for the content
}
}
Example Usage
import { Story, StoryEventTypes } from "@storysdk/core";
const story = new Story("<APP_TOKEN_HERE>");
// Listen for group close events
story.on(StoryEventTypes.GROUP_CLOSE, (event) => {
console.log("Group closed:", event.detail.groupId);
console.log("User:", event.detail.uniqUserId);
console.log("Viewing duration (seconds):", event.detail.duration);
console.log("Language:", event.detail.language);
// You can use this event to:
// 1. Track engagement metrics
updateEngagementMetrics(
event.detail.groupId,
event.detail.uniqUserId,
event.detail.duration
);
// 2. Identify popular content
if (event.detail.duration > 30) {
markAsHighEngagement(event.detail.groupId);
}
// 3. Complete user session tracking (when combined with GROUP_OPEN)
completeViewingSession(
event.detail.groupId,
event.detail.uniqUserId,
event.detail.duration
);
});
Implementation Notes
The duration is provided in seconds, useful for calculating engagement metrics
This event complements the groupOpen event for complete session analysis
Comparing duration across different groups can help identify the most engaging content
This event is useful for:
Measuring content effectiveness
Identifying drop-off points in user flows
Optimizing story sequences based on engagement patterns
Building analytics dashboards for content performance
Story Open Event
The storyOpen event is fired when a user opens an individual story within a group. This event provides information about which specific story was opened.
Event Structure
interface StoryOpenEvent {
detail: {
groupId: string; // ID of the parent story group
storyId: string; // ID of the specific story that was opened
uniqUserId: string; // Unique identifier for the user
language: string; // Language setting for the content
}
}
Example Usage
import { Story, StoryEventTypes } from "@storysdk/core";
const story = new Story("<APP_TOKEN_HERE>");
// Listen for story open events
story.on(StoryEventTypes.STORY_OPEN, (event) => {
console.log("Story opened:", event.detail.storyId);
console.log("In group:", event.detail.groupId);
console.log("User:", event.detail.uniqUserId);
console.log("Language:", event.detail.language);
// You can use this event to:
// 1. Track individual story views
trackStoryView(
event.detail.storyId,
event.detail.groupId,
event.detail.uniqUserId
);
// 2. Record story sequence progression
updateUserProgress(
event.detail.uniqUserId,
event.detail.groupId,
event.detail.storyId
);
// 3. Trigger external integrations based on specific story views
if (isKeyStory(event.detail.storyId)) {
triggerExternalEvent(event.detail.storyId, event.detail.uniqUserId);
}
});
Implementation Notes
This event is fired at the individual story level, as opposed to the group level
It contains both the story ID and its parent group ID for hierarchical tracking
A single user session will typically trigger multiple story open events as the user progresses
This event is useful for:
Analyzing navigation patterns within story groups
Building progression funnels to identify drop-off points
Tracking which individual stories drive user engagement
Creating personalized experiences based on story viewing history
Story Close Event
The storyClose event is fired when a user finishes viewing an individual story. This event provides information about which story was viewed and for how long.
Event Structure
interface StoryCloseEvent {
detail: {
groupId: string; // ID of the parent story group
storyId: string; // ID of the story that was closed
uniqUserId: string; // Unique identifier for the user
duration: number; // Duration in seconds that the story was viewed
language: string; // Language setting for the content
}
}
Example Usage
import { Story, StoryEventTypes } from "@storysdk/core";
const story = new Story("<APP_TOKEN_HERE>");
// Listen for story close events
story.on(StoryEventTypes.STORY_CLOSE, (event) => {
console.log("Story closed:", event.detail.storyId);
console.log("In group:", event.detail.groupId);
console.log("User:", event.detail.uniqUserId);
console.log("Viewing duration (seconds):", event.detail.duration);
console.log("Language:", event.detail.language);
// You can use this event to:
// 1. Track individual story engagement
trackStoryEngagement(
event.detail.storyId,
event.detail.duration,
event.detail.uniqUserId
);
// 2. Identify stories with high completion rates
if (event.detail.duration >= getExpectedDuration(event.detail.storyId)) {
markAsFullyViewed(event.detail.storyId, event.detail.uniqUserId);
}
// 3. Complete story view tracking (when combined with STORY_OPEN)
completeStoryViewSession(
event.detail.storyId,
event.detail.uniqUserId,
event.detail.duration
);
});
Implementation Notes
The duration field indicates how long the user viewed the story in seconds
This event complements the storyOpen event for complete story viewing analysis
Short durations may indicate skipped or unengaging content
This event is useful for:
Determining which stories hold user attention the longest
Calculating completion rates for individual stories
Refining content based on viewing patterns
Building detailed analytics for story-level engagement
Story Next Event
The storyNext event is fired when a user navigates to the next story in a sequence. This event helps track user navigation patterns.
Event Structure
interface StoryNextEvent {
detail: {
groupId: string; // ID of the parent story group
storyId: string; // ID of the story being navigated to
uniqUserId: string; // Unique identifier for the user
language: string; // Language setting for the content
}
}
Example Usage
import { Story, StoryEventTypes } from "@storysdk/core";
const story = new Story("<APP_TOKEN_HERE>");
// Listen for story next navigation events
story.on(StoryEventTypes.STORY_NEXT, (event) => {
console.log("Navigated to next story:", event.detail.storyId);
console.log("In group:", event.detail.groupId);
console.log("User:", event.detail.uniqUserId);
console.log("Language:", event.detail.language);
// You can use this event to:
// 1. Track forward navigation patterns
trackForwardNavigation(
event.detail.groupId,
event.detail.storyId,
event.detail.uniqUserId
);
// 2. Analyze user flow through stories
updateUserFlowAnalytics(
event.detail.uniqUserId,
'next',
event.detail.storyId
);
// 3. Log sequential story viewing behavior
logSequentialProgress(event.detail.uniqUserId, event.detail.storyId);
});
Story Previous Event
The storyPrev event is fired when a user navigates to the previous story in a sequence. This event helps identify when users revisit content.
Event Structure
interface StoryPrevEvent {
detail: {
groupId: string; // ID of the parent story group
storyId: string; // ID of the story being navigated to
uniqUserId: string; // Unique identifier for the user
language: string; // Language setting for the content
}
}
Example Usage
import { Story, StoryEventTypes } from "@storysdk/core";
const story = new Story("<APP_TOKEN_HERE>");
// Listen for story previous navigation events
story.on(StoryEventTypes.STORY_PREV, (event) => {
console.log("Navigated to previous story:", event.detail.storyId);
console.log("In group:", event.detail.groupId);
console.log("User:", event.detail.uniqUserId);
console.log("Language:", event.detail.language);
// You can use this event to:
// 1. Track backward navigation patterns
trackBackwardNavigation(
event.detail.groupId,
event.detail.storyId,
event.detail.uniqUserId
);
// 2. Identify potentially confusing content
if (isHighBackwardNavigationRate(event.detail.storyId)) {
flagForContentReview(event.detail.storyId);
}
// 3. Analyze user review behavior
updateUserFlowAnalytics(
event.detail.uniqUserId,
'previous',
event.detail.storyId
);
});
Implementation Notes for Navigation Events
Both storyNext and storyPrev events have identical structures but represent different navigation actions
The storyId in these events refers to the story being navigated TO (not from)
High rates of backward navigation may indicate confusing content or users reviewing important information
These events are useful for:
Creating flow diagrams of user navigation patterns
Identifying content that users frequently revisit
Optimizing story sequences based on navigation behavior
Understanding how users interact with story sequences
Styling & Customization
HTML Data Attributes
You can configure StorySDK using HTML data attributes in static HTML implementations: