Customize text strings

Customize text strings

You can customize text strings on the ThoughtSpot application interface using the customizations object in the SDK.

Overview🔗

The customization framework in the Visual Embed SDK provides the following attributes and objects to override the text strings in the UI:

  • stringIDs
    The stringIDs object allows overriding specific occurrences of the UI text. It overrides only the UI text mapped to the string ID specified in your code and can be used for precise, granular, and controlled overrides.

  • stringIDsUrl
    The stringIDsUrl object allows loading string IDs with text overrides from a JSON file hosted on a remote server. Before applying overrides via stringIDsUrl, you must add the domain name of the server that hosts the JSON file to CSP and CORS allowlists in ThoughtSpot.

  • strings
    The strings object overrides the UI text by matching the visible string. It replaces all occurrences of strings and substrings in the UI. If the overrides are not applied carefully, this method might introduce unintended changes to the UI text.

You can use any of these attributes or a combination of all three methods to apply text overrides.

If both strings and stringIDs properties are set to replace the same string, the text defined in the stringIDs override will take precedence.

Important
  • You can customize only the system-generated text in the UI. User-created text such as object names, titles, or description text are not customizable.

  • The strings and substrings in the ThoughtSpot UI are case-sensitive.

  • Before applying the overrides, sanitize the JSON file and your string ID definitions to ensure that there is no malicious script or code that can potentially break your implementation.

  • Ensure that only ThoughtSpot users with administrator or developer privilege are allowed to use the exposeTranslationIDs attribute and access the internal string IDs.

Using string IDs for overrides🔗

The stringIDs object overrides only the UI text mapped to the string ID specified in your code, therefore can be used for precise, granular, and controlled overrides with no unintended changes.

For string ID overrides, the ID of the text string is required. To view the strings, you can use the exposeTranslationIDs attribute in the SDK.

Find the string IDs🔗

To find string IDs for the UI text, use the Visual Embed Playground on your instance:

  1. In the Visual Embed Playground, select the embed type and object.

  2. Set the exposeTranslationIDs attribute to true in the code panel.

    exposeTranslationIDs: true
  3. Click Run.

    When the page is rendered, the UI text is presented in the <string[stringID]> format. For example, the Liveboard button on the Home page appears as <Liveboards[Facet.objectType.pinboards]>.

  4. Note the string IDs of the text that you want to override.

    String IDs

Customize the UI text mapped to string IDs🔗

To customize the text mapped to a string ID, use the stringIDs: { "<stringID>": "<text string value>" } format:

 customizations: {
     content: {
         stringIDs: {
             // Change "Liveboards" on the Home page to "Dashboards"
             "Facet.objectType.pinboards":"Dashboards",
             // Change "Answers" on the Home page to "Reports"
             "Facet.objectType.answers": "Reports",
             // Change `Spotter` on the Spotter page to "dataAnalyzer"
             "convassist.spotter.askSpotter": "dataAnalyzer"
         },
     },
 }

Some string IDs in the ThoughtSpot UI include placeholders for dynamic content such as object names and variables, which will be substituted with actual names during runtime.

For example, in the following strings, {answerName} and {currentRowCount} are placeholders for the Answer object name and row count respectively, which will be replaced with actual values.

<Select measures & attributes for '{answerName}'[a3.selectColumns]{"answerName": "My Answer"}>

<Showing {currentRowCount} of many rows[answer.table.footer.infiniteMsg]{"currentRowCount":"1,000","totalRowCount":"1,000"}>

When overriding strings with placeholders, you may want to retain the placeholder text with dynamic content and only replace a part of the text with a custom string. In such cases, you can define the overrides as shown in this example:

customizations: {
    content: {
    //...
        stringIDs : {
            "a3.selectColumns": "Choose dimensions for '{answerName}'",
            "answer.table.footer.infiniteMsg": "Showing {currentRowCount} of {totalRowCount} rows"
        }
    }
}

The following figures show the string IDs and custom text application:

Customize String ID
Customize String IDs

Override strings using a JSON file🔗

The stringIDsUrl property lets upload a JSON file with string ID overrides.

Before applying overrides via JSON file, you must add the domain name of the site that hosts the JSON to the CSP and CORS allowlists on the Develop > Security Settings page.

To find the string ID of a specific text string, use the exposeTranslationIDs attribute in the SDK.

The following example shows the format of the JSON content with string ID overrides:

{
  "Facet.objectType.answers": "Reports",
  "Facet.objectType.pinboards": "Dashboards",
  "convassist.spotter.askSpotter": "dataAnalyzer",
  "a3.selectColumns": "Choose dimensions for '{answerName}'",
  "answer.table.footer.infiniteMsg": "Showing {currentRowCount} of {totalRowCount} rows"
}

When the JSON file is ready to use, you can host it on a trusted server and specify the URL in the stringIDsUrl attribute as shown here:

init({
    // ...
    customizations: {
        content: {
            stringIDsUrl: 'https://yourdomain.com/string-ids.json', // Replace with your string ID JSON hosting URL
        },
    },
});

For testing purposes, you can use the following URL:

Override common keywords and substrings🔗

The strings object overrides the UI text by matching the visible string. Use this object for global and substring-based replacement of common text and keywords in the UI.

For example, if you want to replace every occurrence of Liveboard with Dashboard regardless of where it appears in the UI, use the strings object to override all instances. However, you must exercise caution and verify the overrides thoroughly to prevent unintended changes.

Overrides with the strings object are defined in the strings : { "<substring-key>": "<substring-value>" } format.

// Initialize the SDK with custom text string replacements
init({
    // ...
    customizations: {
        content: {
            // Use the strings object to replace the visible UI text with custom labels.
            strings: {
                // Change all instances of "Liveboard" to "Dashboard"
                "Liveboard": "Dashboard",
                // Change all instances of "Answer" to "Reports"
                "Answer": "Reports",
                // Change all instances of "Spotter" to "dataAnlyzer"
                "Spotter": "dataAnlyzer",
                // Change all instances of "Search" to "Analyze"
                "Search": "Analyze",
            }
        }
    }
});

When using the strings object to override text strings in the UI, ensure that the string and substring are defined in the correct order. For example, if the Liveboard text string is defined as Dashboard, all instances of Liveboard will be updated as Dashboard in the UI. If you want to customize Pin to Liveboard, you must specify the next substring as Pin to Dashboard instead of Pin to Liveboard.

customizations: {
        content: {
            strings: {
              "Liveboard": "Dashboard",
              "Pin to Dashboard": "Save",
            }
        }
    }

However, if the Pin to Liveboard string precedes the "Liveboard": "Dashboard" string, specify the substring as Pin to Liveboard as shown in this example.

customizations: {
        content: {
            strings: {
              "Pin to Liveboard": "Save",
              "Liveboard": "Dashboard",
            }
        }
    }

Additionally, check if any part of the text string is already defined for overrides. For example, if you are replacing Search with Analyze your data, the Search data button in the UI will show as "Analyze your data data". In such cases, use the string IDs to replace strings precisely and systematically.

Test your changes🔗

Before making application-wide changes, try out string customization options in the Visual Embed Playground.

To view the code for customization:

  1. In the Playground, select the embed type.

  2. Select the Apply custom styles checkbox in the Playground.
    The customizations code for CSS modifications appears in the code panel.

  3. Add the text string customization code and verify the results.

Code sample🔗

// Initialize the SDK with custom text string replacements
init({
    // ... other init options ...
    customizations: {
        content: {
            // Use the 'strings' object for substring-based replacements (case-sensitive, replaces all instances)
            strings: {
                "Model": "Data Sheet",  // Replaces all occurrences of "Model" with "Data Sheet"
                "Connections": "Data pipeline"  // Replaces all occurrences of "Connections" with "Data pipeline"
            },
            // Use the 'stringIDs' object to override context-specific text with unique string IDs
            stringIDs: {
                // Change "Answers" on the Home page to "Reports"
                "Facet.objectType.answers": "Reports",
                // Change "Liveboards" on the Home page to "Dashboards"
                "Facet.objectType.pinboards": "Dashboards",
                // Change "Spotter" to "dataAnalyzer" on the Spotter page
                "convassist.spotter.askSpotter": "dataAnalyzer",
                // String ID with dynamic content placeholder. Example, "<Select measures & attributes for '{answerName}'[a3.selectColumns]{"answerName": "My Answer"}>'"
                "a3.selectColumns": "Choose dimensions for '{answerName}'",
                // String ID with variable text. Example, "<Showing {currentRowCount} of many rows[answer.table.footer.infiniteMsg]{"currentRowCount":"1,000","totalRowCount":"1,000"}>"
                "answer.table.footer.infiniteMsg": "Showing {currentRowCount} of {totalRowCount} rows"
            },
            // Optionally, load additional stringID overrides from a JSON file hosted on a remote sever
            stringIDsUrl: "https://cdn.jsdelivr.net/gh/thoughtspot/custom-content-demo/string-ids.json"
        }
    }
});