Install Pendo on canvas Power Apps

Last updated:

This article provides guidance for a Power App developer to install Pendo on a canvas Power App, built on the Microsoft Power Apps framework.

Microsoft Power Apps is a low-code application building framework that enables Microsoft customers to build and customize internal business applications. There are two major categories of Microsoft Power Apps: model-driven applications and canvas applications. This guide focuses on canvas. For model-driven applications, see Install Pendo on model-driven Power Apps.

Installation overview

Canvas applications run outside of Microsoft Dynamics 365 CE Framework, so the managed solution doesn't install Pendo in these applications. Instead, Pendo must be added to each application using a custom code component built with the Power Apps Component Framework (PCF). 

For Microsoft's guidance on creating components, see Create your first component.

The Pendo component should be placed on the landing screen of your canvas application so that Pendo is loaded when a user first navigates to the application. If there's no set landing screen, then the component should be added to each potential landing screen so that Pendo is always loaded. If the Pendo component is installed on multiple screens, conditional logic should be implemented so that the Pendo install script is only run once per user session. Pendo can only initialize once per page load, and additional attempts to initialize are ignored.

Prerequisite: Set up a development environment

Download and install the necessary software for creating a Microsoft Power App custom component. These might differ depending on your operating system and IT policies. If your development environment is already set up to create Power App custom components, skip to Step 1: Create a new component in this article.

Step 1. Create a new component

For a canvas Power App installation, the Pendo install script must be in a Power App Component Framework (PCF) custom code component. This step involves creating a place to put your component and then creating the component itself. Create and navigate to a directory for your new code component.

mkdir <your_repo_name>
cd <your_repo_name>

Inside your project directory, create a new component project.

pac pcf init --namespace <your_component_namespace> --name <your_component_name> --template field --run npm-install

Step 2. Add the Pendo install script to your code component

This step results in a template component that you must edit to add Pendo. You must pass visitor and account metadata defined in the install script through the context object passed in to your install script. For example:

  • visitorId: context.userSettings.userId
  • accountId: context.organizationSettings.organizationId

To add the Pendo install script to the component, make the following changes.

  1. Create a new file initPendo.js and add the following:
    export function initPendo(context) {
      (function (apiKey) {
        (function (p, e, n, d, o) {
          var v, w, x, y, z;
          o = p[d] = p[d] || {};
          o._q = o._q || [];
          v = ["initialize", "identify", "updateOptions", "pageLoad", "track"];
          for (w = 0, x = v.length; w < x; ++w)
          (function (m) {
            o[m] =
              o[m] ||
              function () {
                o._q[m === v[0] ? "unshift" : "push"](
                  [m].concat([], 0))
          y = e.createElement(n);
          y.async = !0;
          y.src = "" + apiKey + "/pendo.js";
          z = e.getElementsByTagName(n)[0];
          z.parentNode.insertBefore(y, z);
        })(window, document, "script", "pendo");

          visitor: {
            id: context?.userSettings?.userId || "VISITOR-UNIQUE-ID",
          account: {
            id: context?.orgSettings?.uniqueName || "ACCOUNT-UNIQUE-ID",
  2. Import the function in the index.ts file and call it inside the init function, passing along the context:
    import {IInputs, IOutputs} from "./generated/ManifestTypes";
    import {initPendo} from './initPendo'

    export class PendoOnMSPCF implements ComponentFramework.StandardControl<IInputs, IOutputs> {

      * Empty constructor.


      * Used to initialize the control instance. Controls can kick off remote server calls and other initialization actions here.
      * Data-set values are not initialized here, use updateView.
      * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to property names defined in the manifest, as well as utility functions.
      * @param notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously.
      * @param state A piece of data that persists in one session for a single user. Can be set at any point in a controls life cycle by calling 'setControlState' in the Mode interface.
      * @param container If a control is marked control-type='standard', it will receive an empty div element within which it can render its content.
      public init(context: ComponentFramework.Context<IInputs>, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container:HTMLDivElement): void
        // Add control initialization code
  3. Modify the tsconfig.json file to allow JavaScript files in the project:
        "extends": "./node_modules/pcf-scripts/tsconfig_base.json",
        "compilerOptions": {
        "typeRoots": ["node_modules/@types"],
        "allowJs": true

Step 3. Test the component

You can load the component locally in a test environment using: npm start. You can validate that the component is running on Pendo by opening the browser console and running pendo.validateInstall(). If successfully configured, you then see the following:


User information is not available in the test environment, so placeholder values are expected.

Step 4. Package and deploy the component

Pack the component for deployment by running the following:

mkdir <your_solution_name>
cd <your_solution_name>>
pac solution init --publisher-name <your_publisher_name> --publisher-prefix <your_publisher_prefix>
pac solution add-reference --path ..      
dotnet build

The generated solution zip file is located in <your_solution_name>/bin/debug folder. Follow Microsoft's instructions for importing your newly created solutions: Import solutions. The solution has the following naming structure: <your_publisher_prefix>_<your_publisher_name>.<your_solution_name>.

Next, follow the Microsoft's instructions for adding the new code component to your canvas app: Add components to a canvas app. Pendo runs on your canvas application after you've saved and published it. 

Step 5. Verify the deployment

Open the browser console, navigate to the relevant iframe for the canvas app, and run pendo.validateInstall(). If successfully configured, you then see the visitorID and accountID from the Microsoft application context.

Screenshot 2023-08-09 at 2.41.22 PM.png

Using the Visual Design Studio within canvas Power Apps

The Visual Design Studio is launched differently from within a canvas Power App than in a standard web application. To open the Visual Design Studio in your canvas application with Pendo installed, use the browser console to run the following command:


You can also run this code from a custom code component embedded in the application, or from a Pendo guide using a custom code block. 

Tagging Pages within canvas Power Apps

After launching the Visual Design Studio, you can tag Pages. As with many single-page applications, Canvas applications render different pages at the same URL, so standard Page tagging by URLs doesn't work because there's no human-readable URL to use.

Instead, you can either:

Tagging Features within canvas Power Apps

You also tag Features from the Visual Design Studio.

In canvas Power Apps, Feature rules rely heavily on contains rules and can be fragile. You can use Page location to isolate the Feature tagging rule to a specific Page. To do this, tag Pages first, as described in Tagging Pages within canvas Power Apps. If you plan to exclude inner text collection, you must use allowedText to allow specific strings of text for contains rules. For more information, see Data collection prevention strategies.

Building and using guides within canvas Power Apps

Guides work as expected on web, and might be less responsive on different mobile browser resolutions. Experiment with different sizes.

Was this article helpful?
1 out of 1 found this helpful