npm install @thoughtspot/react-native-embed-sdk
Embed using React Native mobile SDK
ThoughtSpotβs React Native Mobile Embed SDK Beta enables developers to embed ThoughtSpot Analytics in their mobile apps. This SDK is designed for the React Native framework to allow developers to build their mobile apps that operate on iOS and Android platforms, using native resources and a single codebase.
In its initial release, the React Native Embed SDK supports embedding a Liveboard component and customizing the embed view within the mobile app.
Before you beginπ
Before you get started, check the following:
-
You have access to a ThoughtSpot instance with the necessary credentials.
-
NPM and Node.js are installed on your system.
-
Your React Native environment is set up.
-
If you are using Expo to build your application:
-
Ensure that the Expo project is created and imported into your development environment.
-
Install the Expo Go app on your mobile device (iOS or Android) to preview the app.
-
Get started with embeddingπ
This section provides a set of steps to quickly embed a ThoughtSpot Liveboard in a mobile app.
Install the SDKπ
The latest version of the Mobile Embed SDK for React Native is available at https://www.npmjs.com/package/@thoughtspot/react-native-embed-sdk.
Import the SDK into your projectπ
// NPM
import { LiveboardEmbed, AuthType, init } from '@thoughtspot/react-native-embed-sdk';
After you import, you can define the ThoughtSpot host URL from which you want to embed a Liveboard, authentication type and attributes, and Liveboard ID.
File structure in the Expo go sandboxπ
In the Expo code sandbox, youβll notice that your mobile embed project has the following files:
-
Auth.ts
- Includes the code required to get authentication token from ThoughtSpot via REST API SDK. -
App.tsx
- Includes the code for expo app setup. -
Home.tsx
- Includes the code for the main screen and the form to populate embed view configuration, theinit
function with thetsHost
andusername
, Liveboard ID, and custom style specification. -
LiveboardView.tsx
- Defines the interface configuration properties and event interaction settings for the Liveboard embed view.
You can use similar files in your project setup or an index file for the ThoughtSpot mobile embed code.
Initialize the SDK and set up authenticationπ
To initialize the SDK, the following information is required:
-
thoughtSpotHost
The hostname of your ThoughtSpot application instance. For example,team2.thoughtspot.cloud
. See FAQs to know how to find the hostname of your application instance. -
authType
Authentication type. In the current version, mobile embedding supports only the Cookieless Trusted authentication method (AuthType.TrustedAuthTokenCookieless
).
init({
thoughtSpotHost: 'ts-host-url', // Replace with your ThoughtSpot host URL
authType: AuthType.TrustedAuthTokenCookieless,
getAuthToken: async () => "full-auth-token"
});
Add the Liveboard componentπ
const TsApp = () => {
return (
<View style={styles.container}>
<LiveboardEmbed
liveboardId="liveboard-id" // Replace it with your Liveboard ID
/>
</View>
);
};
Build your app and preview the embedded contentπ
-
Build your app:
$ npm run build
-
If you are using an Expo project:
-
Build your project locally
expo start
-
Scan the QR code with the Expo Go app to see the app with the embedded content.
-
Customize your embedπ
Just like the Visual Embed SDK for web application embed, the Mobile Embed SDK provides the following customization options:
-
Control the visibility of menu actions in the embedded view
-
Customize app interactions and workflows using events.
-
Customize the styles and UI layout of the embedded view
Customize menu actionsπ
By default, the SDK includes a set of menu actions in the embedded view.
Default menu actions
-
Add filter (
Action.AddFilter
)
Allows adding filters to the embedded Liveboard -
Filter (
Action.CrossFilter
)
Allows applying filters across all visualizations in a Liveboard. -
Drill down (
Action.DrillDown
)
Allows drilling down on a data point in the visualization to get granular details. -
Personalized view (
Action.PersonalisedViewsDropdown
)
The Liveboard personalized views drop-down. -
Filter action (
Action.AxisMenuFilter
) in the chart axis or table column customization menu
Allows adding, editing, or removing filters on a visualization. -
Edit action (
Action.AxisMenuEdit
) in the axis customization menu.
Allows editing the axis name, position, minimum and maximum values of a column. -
Position action (
Action.AxisMenuPosition
) in the axis customization menu.
Allows changing the position of the axis to the left or right side of the chart. -
Sort action (
Action.AxisMenuSort
) - Sorts the data in ascending or descending order on a chart or table. -
Aggregate (
Action.AxisMenuAggregate
) option in the chart axis or the table column customization menu.
Provides aggregation options to analyze the data on a chart or table. -
Conditional formatting menu option (
Action.AxisMenuConditionalFormat
)
Allows adding rules for conditional formatting of data points on a chart or table. -
The Group option (
Action.AxisMenuGroup
) in the chart axis or table column customization menu.
Allows grouping data points if the axes use the same unit of measurement and a similar scale. -
The Remove option (
Action.AxisMenuRemove
) in the chart axis or table column customization menu.
Removes the data labels from a chart or the column of a table visualization. -
The Rename option (
Action.AxisMenuRename
) in the chart axis or table column customization menu.
Renames the axis label on a chart or the column header on a table -
Time bucket option (
Action.AxisMenuTimeBucket
) in the chart axis or table column customization menu.
Allows defining time metric for date comparison.
To disable or hide a menu action, you must specify the action ID in the disabledActions
, visibleActions
, or hiddenActions
array. To show or hide menu actions, use either visibleActions
or hiddenActions
.
//Add the menu actions to show in the embed view. Removes all actions if the array is empty
visibleActions: [Action.AddFilter,Action.Share,Action.DrillDown,Action.AxisMenuFilter,Action.AxisMenuTimeBucket],
//disable actions
disabledActions: [Action.DrillDown, Action.Edit],
//specify the reason for disabling menu actions
disabledActionReason: "Contact your administrator to enable this feature",
//hiddenActions: [], /* Do not use if `visibleActions` is enabled */
//hide specific actions
hiddenActions: [Action.AddFilters],
//disable actions
disabledActions: [Action.DrillDown],
//specify the reason for disabling menu action
disabledActionReason: "Contact your administrator to enable this feature",
//visibleActions: [], /* Do not use if `hiddenActions` is enabled */
Customize app interactionsπ
To customize app interactions and enable custom workflows with Embed and Host events.
The following code adds an event listener for the authInit
embed event and specifies how to handle the default load when it emits.
// Define a component that embeds a Liveboard and handles initial authentication state
const LiveboardEmbedView = () => {
// Declare a loading state to control the loading UI
const [loading, setLoading] = useState(true);
// Create a ref to interact with the LiveboardEmbed component programmatically
const webViewRef = useRef<any>(null);
// Function to handle the AuthInit event from the LiveboardEmbed
const handleAuthInit = () => {
alert("Auth Init EmbedEvent"); // Show a simple alert when auth is initialized
setLoading(false); // Set loading to false once authentication is complete
}
return (
<>
{loading && <Text>Loading...</Text>}
<LiveboardEmbed
ref={webViewRef}
liveboardId={liveboardId} // Pass the Liveboard ID
onAuthInit={() => {handleAuthInit()}} // Callback when the AuthInit event is fired by the embed
/>
</>
);
};
Similarly, you can also add a host event to trigger an action or add custom workflow. The following example shows the host events registered to trigger reload and Liveboard Share actions.
// Define a component for embedding and interacting with a Liveboard
const LiveboardEmbedView = () => {
// Create a reference to the LiveboardEmbed instance
const webViewRef = useRef<any>(null);
// Function to reload the embedded Liveboard
const reloadView = () => {
Alert.alert("Reloading") // Show an alert to inform the user
if(webViewRef?.current) {
// Trigger the Reload event on the Liveboard
webViewRef?.current?.trigger(HostEvent.Reload)
}
}
// Function to open the Share dialog for the Liveboard
const shareView = () => {
if(webViewRef?.current) {
// Trigger the Share event on the Liveboard
webViewRef.current.trigger(HostEvent.Share)
}
}
// Render buttons for "Reload" and "Share", and the LiveboardEmbed component
return (
<>
<View>
<TouchableOpacity onPress={reloadView}>
<Text>Reload</Text>
</TouchableOpacity>
<TouchableOpacity onPress={shareView}>
<Text>Share</Text>
</TouchableOpacity>
</View>
<LiveboardEmbed
ref={webViewRef} // Assign the ref to control this component
liveboardId={liveboardId} // Pass the Liveboard ID
/>
</>
);
};
Customize stylesπ
You can use ThoughtSpotβs CSS customization framework to customize the text strings, icons, styles and the UI layout of the embedded view.
init({
// Other attributes such as the host URL, authentication type and so on.
customizations: {
content: {
strings: {
// Custom label for the Filter menu action
"Filter": "Select column",
}
},
style: {
customCSS: {
variables: {
// Background color of the application
"--ts-var-root-background": "#fef4dd",
// Text color
"--ts-var-root-color": "#4a4a4a",
// Visualization title color
"--ts-var-viz-title-color": "#8e6b23",
// Font family for visualization title
"--ts-var-viz-title-font-family": "'Roboto', 'Helvetica', sans-serif",
// Title text capitalization
"--ts-var-viz-title-text-transform": "capitalize",
// Visualization description text color
"--ts-var-viz-description-color": "#6b705c",
// Font family for description text
"--ts-var-viz-description-font-family": "'Roboto', 'Helvetica', sans-serif",
}
}
}
}
});
Code samplesπ
The following example shows the minimum code required to embed a Liveboard successfully in a mobile app:
import React from 'react';
import { View, StyleSheet } from 'react-native';
// Import necessary ThoughtSpot SDK modules
import { AuthType, init, LiveboardEmbed } from '@thoughtspot/react-native-embed-sdk';
// Initialize the ThoughtSpot SDK
init({
thoughtSpotHost: 'ts-host-url', // Replace with your ThoughtSpot host URL
authType: AuthType.TrustedAuthTokenCookieless, //Using cookieless trusted token authentication
getAuthToken: async () => "full-auth-token", //fetch a valid authentication token
});
// Add Liveboard component
const TsApp = () => {
return (
<View style={styles.container}>
<LiveboardEmbed
liveboardId="liveboard-id" // Pass the Liveboard ID
onError={(error) => console.error('Embed error:', error)} // Log any embed errors
/>
</View>
);
};
// Define layout styles
const styles = StyleSheet.create({
container: {
flex: 1, // Takes up full screen height
marginTop: 50, // Add some space from the top
marginBottom: 30, // Add some space at the bottom
},
});
export default TsApp; // Export the Liveboard component
In the following code sample, the embedded view is customized to show only Drill down (Action.DrillDown
), Add filter (Action.AddFilter
), and Share actions. This code also includes embed events that register event listeners or host events to trigger a response from the app.
import React, { useRef, useState } from 'react';
import { StyleSheet, View, Text, Alert, TouchableOpacity } from 'react-native';
// Import ThoughtSpot SDK components and helpers
import { Action, HostEvent, LiveboardEmbed, init, AuthType } from '@thoughtspot/react-native-embed-sdk';
// Initialize the ThoughtSpot SDK
init({
thoughtSpotHost: 'ts-host-url', // Replace with your ThoughtSpot host URL
authType: AuthType.TrustedAuthTokenCookieless, // Using cookieless trusted token authentication
getAuthToken: async () => "full-auth-token", // Fetch authentication token
});
// Custom components to display and interact with the ThoughtSpot Liveboard
const LiveboardView = ({ liveboardId }) => {
const [loading, setLoading] = useState(true); // State to track loading (optional)
const webViewRef = useRef(null); // Ref to access the LiveboardEmbed instance
// Reloads the liveboard when called
const reloadView = () => {
Alert.alert("Reloading")
if (webViewRef?.current) {
webViewRef.current.trigger(HostEvent.Reload);
}
};
// Triggers the Liveboard sharing action
const shareView = () => {
if(webViewRef?.current) {
webViewRef.current.trigger(HostEvent.Share)
}
};
return (
<View style={styles.embedContainer}>
{/* The embedded ThoughtSpot Liveboard view */}
<LiveboardEmbed
ref={webViewRef}
liveboardId={liveboardId}
onAuthInit={() => setLoading(false)} // If authentication is successful
onError={(error) => Alert.alert("Error", `Error: ${JSON.stringify(error)}`)} // Handle embed errors
onLiveboardRendered={() => Alert.alert("Success", "Liveboard Rendered")} // Notify when Liveboard is rendered
visibleActions={[Action.DrillDown, Action.AddFilter, Action.Share]} // Showm menu actions
fullHeight={true}
/>
{/* Optional control buttons */}
<TouchableOpacity onPress={reloadView} style={styles.button}>
<Text style={styles.buttonText}>Reload View</Text>
</TouchableOpacity>
<TouchableOpacity onPress={shareView}>
<Text>Share</Text>
</TouchableOpacity>
</View>
);
};
// Component that renders the LiveboardView
const TsApp = () => {
return (
<View style={styles.container}>
<LiveboardView liveboardId="liveboard-id" /> // Pass the Liveboard ID
</View>
);
};
// Define layout styles
const styles = StyleSheet.create({
container: {
flex: 1, // Takes up full screen height
marginTop: 50,
marginBottom: 30,
},
});
// Export the component
export default TsApp;
Test your appπ
-
Connect your device to the app, authenticate, and load the Liveboard in your mobile app.
-
Select a data point to drill down on a visualization or apply filters.
-
Verify the event interactions and workflows.
Known limitationsπ
The following Liveboard view configuration parameters are not supported in mobile embeds: