Opening a Canvas Apps from Ribbon Button in Dynamics 365

Currently there is no straight forward way to open a canvas apps from the ribbon button unlike the custom page that can be opened using the Xrm.Navigation.navigateTo(pageInput,navigationOptions).then(successCallback,errorCallback);
Refer : navigateTo (Client API reference)

However the navigateTo client api allows us to call a HTML webresource, which is exactly how we can open/launch the canvas apps from the ribbon button.

Creating the JavaScript webresource to call the HTML webresource*.*
In the below code, we are passing the primaryControl, canvas apps AppId and the HTML webresource name as parameters from the ribbon work bench.

function openCanvasApp(executionContext, appId, webresource) {

    var recordId = executionContext.data.entity.getId();
    var iframeSrc = encodeURIComponent(`https://apps.powerapps.com/play/${appId}?source=iframe&recordId=${recordId}`);

    var pageInput = {
        pageType: "webresource",
        webresourceName: webresource,
        data: iframeSrc // Passing iframeSrc as data parameter
    };

    var navigationOptions = {
        target: 2,
        position: 2,//open as a side pane
        width: { value: 500, unit: "px" }
    };

    // Using navigateTo Client API
    Xrm.Navigation.navigateTo(pageInput, navigationOptions).then(
        function success() {
            // Run code on success
        },
        function error() {
            // Handle errors
        }
    );
}

Steps to configure the parameters in Ribbon Workbench :
1. Use the ribbon workbench and create a button, add the label, icon etc. and create a command and associate it to the ribbon button, in the command set the below properties for the custom JavaScript action

  1. Primary control : Is the recordId of the entity where the ribbon button is added

  2. The first string parameter is the canvas apps AppId can be found in the details page of the canvas apps.

  3. The second string parameter is the HTML webresource name

HTML Webresource

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title></title> <!-- Empty title to remove the header -->
        <style>
            body, html {
                margin: 0;
                padding: 0;
                overflow: hidden;
            }
            iframe {
                width: 100%;
                height: 100%;
                border: none;
            }
        </style>
    </head>
    <body>
        <script>
            // Extract the iframeSrc parameter from the Xrm navigation data
            function getDataParameter(name) {
                const urlParams = new URLSearchParams(window.location.search);
                return urlParams.get(name);
            }

            const iframeSrc = getDataParameter('data');
            if (iframeSrc) {
                const recordId = decodeURIComponent(iframeSrc).split('&recordId=')[1];
                const fullUrlWithRecordId = decodeURIComponent(window.location.href);
                console.log('Full URL with Record ID:', fullUrlWithRecordId);
                document.write('<iframe src="' + decodeURIComponent(iframeSrc) + '" allow="geolocation; microphone; camera"></iframe>');
            } else {
                console.error('iframeSrc data parameter is missing');
            }
        </script>
    </body>
    </html>
  1. getDataParameter() is the function that is used to extract the value of parameter from the URL query string, it parses the query string part of the url using the window.location.search

  2. decodeURIComponent() decodes the value in the Iframesrc which is the URL

  3. Splits the decoded string using the '&' as a separator and extracts the recordId=. this is basically the recordId parameter.

  4. This way we do not have to hardcode the canvas apps url in the iframe, rather pass them as parameter from the ribbon workbench and access them.

    This above code will remain same for opening canvas apps, except the first string parameter (AppId)passed from the ribbon workbench can change from one canvas apps to other.