Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion modules/ROOT/pages/onboarding-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ If you want to embed other ThoughtSpot components and explore the additional cap

The latest version of the Visual Embed SDK is available at link:https://www.npmjs.com/package/@thoughtspot/visual-embed-sdk[https://www.npmjs.com/package/@thoughtspot/visual-embed-sdk, window=_blank].

The SDK is written in TypeScript and is also provided both as ES Module (ESM) and Universal Module Definition (UMD) modules, allowing you to use it in a variety of environments.
The Visual Embed SDK is available as both ES Module (ESM) and Universal Module Definition (UMD) modules, allowing you to use it in a variety of environments.

In this example, we'll import the `LiveboardEmbed` SDK package to embed a Liveboard.

Expand Down
30 changes: 22 additions & 8 deletions modules/ROOT/pages/pendo-integration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,25 @@ If you do not have a Pendo account, you can link:https://app.pendo.io/register[s

== Step 1: Sign in to your Pendo Account

To integrate Pendo in your ThoughtSpot embed, you'll require a script. Before creating the script or using the script provided by ThoughtSpot:
To integrate Pendo in your ThoughtSpot embed, you'll require a script. Before creating your integration script:

. Sign in to your Pendo account.
. Identify the information you want to capture.
. Define visitors and accounts, and segment data.
. Review your existing Pendo implementation in your application to understand how you initialize Pendo (for example, using a React hook, vanilla JavaScript, or other methods).

The above information will be used as metadata in the Pendo install script. For more information, refer to the link:https://support.pendo.io/hc/en-us/articles/21326198721563-Choose-IDs-and-metadata[Pendo Documentation, window=_blank].

== Step 2: Create an integration script

The integration requires a script that is designed to install and initialize the Pendo agent within your embed environment. You can either create your own integration script or use the xref:pendo-integration.adoc#_sample_javascript_for_pendo_integration[sample JavaScript] provided by ThoughtSpot.
The integration requires a script that is designed to install and initialize the Pendo agent within your embed environment.

[IMPORTANT]
====
**Create your own integration script**: ThoughtSpot strongly recommends that you replicate your own Pendo initialization logic within your own externally hosted JavaScript file for easier management and maintenance. This approach ensures consistency with your existing Pendo implementation and allows you to adapt it to your specific requirements.

The sample JavaScript provided by ThoughtSpot is an **example only** and may not work for all use cases, particularly in cookieless environments or when using custom authentication flows.
====

The integration script typically includes the following components:

Expand All @@ -54,14 +62,19 @@ For more information about the Pendo configuration metadata, script creation and
* link:https://support.pendo.io/hc/en-us/articles/21326198721563-Choose-IDs-and-metadata[Pendo configuration metadata, window=_blank]

=== Sample JavaScript for Pendo integration
To assist you with the Pendo integration process, ThoughtSpot provides a sample JavaScript, `pendoIntegrationScript.js`. You can find this sample JavaScript in the link:https://github.com/thoughtspot/developer-examples/blob/main/visual-embed/pendo-integration/pendoIntegrationScript.js[ThoughtSpot Developer examples, window=_blank] GitHub repository.
To assist you with the Pendo integration process, ThoughtSpot provides a sample JavaScript, `pendoIntegrationScript.js`, as a **reference example only**. You can find this sample JavaScript in the link:https://github.com/thoughtspot/developer-examples/blob/main/visual-embed/pendo-integration/pendoIntegrationScript.js[ThoughtSpot Developer examples, window=_blank] GitHub repository.

The `pendoIntegrationScript.js` script is designed to perform the following actions:
[NOTE]
====
This sample script is provided for reference purposes. It demonstrates how to:

* Access custom variables defined in the SDK. It waits for the Visual Embed SDK to initialize and load.
* Wait for the user to authenticate successfully and receive information such as user ID, name, email, groups, and account details from the Visual Embed SDK.
* Initialize Pendo with the metadata and key, so that Pendo can track the user and their actions within the embedded app.

However, you should create your own script that replicates your application's Pendo initialization logic. For example, if your application uses a React hook to call `pendo.initialize`, adapt that logic to vanilla JavaScript in your hosted script. This ensures consistency with your existing implementation and better compatibility with your authentication and environment setup.
====

////
* Update Pendo on navigation +
Whenever the user navigates to a new page or context within the embedded ThoughtSpot app, the script updates Pendo with the new context information.
Expand All @@ -71,9 +84,9 @@ It also listens for navigation events within the embedded ThoughtSpot app to cap

== Step 3: Host the script on a public site

When your integration script is ready, host it on a publicly accessible domain, such as AWS S3, Azure Blob, or a trusted CDN.
When your integration script is ready, host it on a publicly accessible domain, such as AWS S3, Azure Blob, GitHub, or a trusted CDN. The script must be accessible to ThoughtSpot so it can fetch and inject it into the embed iframe.

Note the hosting domain.
Note the hosting domain and ensure the script URL is publicly accessible.

[NOTE]
====
Expand All @@ -93,14 +106,15 @@ Wait for ThoughtSpot Support to validate and approve your request. This step is

== Step 5: Add the Script source to the CSP Allowlist

After ThoughtSpot enables the integration for your instance:
After ThoughtSpot enables the integration for your instance, you must add your script's hosting domain to the Content Security Policy (CSP) allowlist to ensure ThoughtSpot can fetch and execute your script:

. Log in to your ThoughtSpot instance as an administrator. +
. Go to the **Develop** page. +
If your instance has Orgs, switch to the *All Orgs* context.
. In the **Customizations** section, click **Security Settings**.
. Check whether the *CSP script-src domains* setting is visible on the *Security Settings* page.
. Add the domain that hosts your script to the **CSP script-src** allowlist.
. Add the domain that hosts your script to the **CSP script-src** allowlist. +
This step is required to allow ThoughtSpot to fetch your script from the hosting domain and inject it into the embed iframe.

== Step 6: Define custom variables in the Visual Embed SDK

Expand Down
Binary file modified src/assets/icons/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/components/VersionIframe/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ const VersionIframe: React.FC<VersionIframeProps> = ({
const mainUrlParams = new URLSearchParams(window.location.search);
if (mainUrlParams.has('pageid')) {
url.searchParams.set('pageid', mainUrlParams.get('pageid'));
const pageId = mainUrlParams.get('pageid');
const pageIdSplit = pageId.split('__');
if (pageIdSplit.length > 1) {
// Tutorials module pages have pageids like {subdirectory}_{real_url_ending}, must be split to generate matching URL
const completePath = `tutorials/${pageIdSplit.join('/')}/`;
url.pathname += completePath;
} else {
// Other pages are not tutorials with subdirectories, so just add the pageid
url.pathname += `${pageId}/`;
}
} else if (mainUrlParams.has('pageId')) {
url.searchParams.set('pageid', mainUrlParams.get('pageId'));
}
Expand Down
Loading