<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic How to embed Qlik App/Sheet on the website in Integration, Extension &amp; APIs</title>
    <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2423034#M20004</link>
    <description>&lt;P&gt;I want to embed Qlik &lt;CODE&gt;app/sheet&lt;/CODE&gt; on my website. There are &lt;CODE&gt;apps&lt;/CODE&gt; on the Qlik, and the &lt;CODE&gt;apps&lt;/CODE&gt; contains the &lt;CODE&gt;sheets&lt;/CODE&gt;, which I want to embed for showing to website visitors/user. But users don't have access of Qlik, so I need to embed with some kind of authentication by code.&lt;/P&gt;
&lt;P&gt;Before going on the code, I have following things created on the Qlik Management Console (QMC):&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;CODE&gt;Tenant&lt;/CODE&gt; host&lt;/LI&gt;
&lt;LI&gt;Added my domain in the &lt;CODE&gt;Content Security Policy&lt;/CODE&gt; section and selected &lt;CODE&gt;frame-ancestors&lt;/CODE&gt; in the &lt;CODE&gt;Directive&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;CODE&gt;Web Integration Id&lt;/CODE&gt; created in &lt;CODE&gt;Web Integration Configuration&lt;/CODE&gt; section&lt;/LI&gt;
&lt;LI&gt;&lt;CODE&gt;Client Id and secret&lt;/CODE&gt; created in &lt;CODE&gt;OAuth&lt;/CODE&gt; section&lt;/LI&gt;
&lt;LI&gt;&lt;CODE&gt;Public key, Private&lt;/CODE&gt; key created by following this article: &lt;A href="https://qlik.dev/authenticate/jwt/create-signed-tokens-for-jwt-authorization/" rel="nofollow noreferrer" target="_blank"&gt;Create Signed Tokens for JWT Authorization&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;After following above article, I also have &lt;CODE&gt;Issuer, Key ID&lt;/CODE&gt; which I setup in the &lt;CODE&gt;Identity Provider&lt;/CODE&gt; section&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Following is my usecase&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;User first select an &lt;CODE&gt;app&lt;/CODE&gt; from the dropdown, this list populated through the following API:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE&gt;GET https://QLIK-TENANT/api/v1/items?resourceType=app
Header: Bearer &amp;lt;token generated with OAuth Client id and secret&amp;gt;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;And it is working.&lt;/P&gt;
&lt;P&gt;After that I need to show another dropdown for all the &lt;CODE&gt;sheets&lt;/CODE&gt; of the selected &lt;CODE&gt;app&lt;/CODE&gt;. But I am unable to fetch the list of sheets. I checked there is no REST API which can give me &lt;CODE&gt;sheets&lt;/CODE&gt; by an &lt;CODE&gt;app&lt;/CODE&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Question 1:&lt;/STRONG&gt; How can I get sheet list of the app? I also plan to list the &lt;CODE&gt;sheets&lt;/CODE&gt; using below JS code, but that is also not working.&lt;/P&gt;
&lt;P&gt;Once user select app and sheet, then click on a button to Render sheet, and it should render that sheet on the webpage.&lt;/P&gt;
&lt;P&gt;I tried using below piece of code (enigma js), referenced from here: &lt;A href="https://qlik.dev/embed/iframe/customize/handle-sheets-in-iframes-with-enigma/" rel="nofollow noreferrer" target="_blank"&gt;Handle sheets in iframes with enigma.js&lt;/A&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;script src="https://unpkg.com/enigma.js/enigma.min.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div id="main"&amp;gt;
        &amp;lt;div id="message"&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;iframe id="qlik_frame" style="border:none;width:100%;height:900px;"&amp;gt;&amp;lt;/iframe&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;script type="text/javascript"&amp;gt;
        // CONFIGURATION
        const TENANT = "xxxxxxxxxxxxx.xx.qlikcloud.com";
        const JWTENDPOINT = "https://example.com/api/v1/qlik/jwtToken"; // this endpoint create a JWT token using passed data and the private key mentioned in point #6 above
        const WEBINTEGRATIONID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // mentioned in point #3 above
        const APPID = "411111e0-36f8-4e6d-b25d-f0xxxxxxxxca"; // got using the REST API mentioned above
        const IDENTITY = "xxxxxxxxxxxxxx"; // An arbitrary string to establish a separate session state.

        // MAIN
        (async function main() {
            const isLoggedIn = await qlikLogin();
            const qcsHeaders = await getQCSHeaders();
            const [session, enigmaApp] = await connectEnigma(qcsHeaders, APPID, IDENTITY);

            handleDisconnect(session);
            const theme = await getTheme(enigmaApp);
            const spaceId = (await getApp(APPID)).spaceId;
            const spaceType = await getSpaceType(spaceId);
            const sheets = await getSheetList(enigmaApp, spaceType);

            renderSingleIframe("qlik_frame", APPID, sheets[0].qInfo.qId, theme, IDENTITY);
        })();

        // LOGIN
        async function qlikLogin() {
            const loggedIn = await checkLoggedIn();
            if (loggedIn.status !== 200) {
                const $jwtPostData = {
                    kid: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // mentioned in point #6 above
                    iss: "xxxxxxxxxxxxx.xx.qlikcloud.com", 
                    name: "?????????" // what it should be????
                };
                const tokenRes = await (await getJWTToken(JWTENDPOINT, $jwtPostData));
                const loginRes = await jwtLogin(tokenRes.body);

                if (loginRes.status != 200) {
                    const message = "Something went wrong while logging in.";
                    throw new Error(message);
                }
                const recheckLoggedIn = await checkLoggedIn();
                if (recheckLoggedIn.status !== 200) {
                    const message = "Third-party cookies are not enabled in your browser settings and/or browser mode.";
                    throw new Error(message);
                }
            }
            return true;
        }

        async function checkLoggedIn() {
            return await fetch(`https://${TENANT}/api/v1/users/me`, {
                mode: "cors",
                credentials: "include",
                headers: {
                    "qlik-web-integration-id": WEBINTEGRATIONID
                },
            })
        }

        // Get Method the JWT and use it to obtain Qlik Cloud session cookie.
        async function getJWTToken(jwtEndpoint, payloadData) {
            try {
                // Define the headers for the request, including the content type
                const headers = new Headers({
                    "Content-Type": "application/json",
                });

                // Create a request object with the specified method, headers, and body
                const requestOptions = {
                    method: "POST",
                    headers: headers,
                    mode: "cors",
                    body: JSON.stringify(payloadData), // Convert payloadData to JSON
                };

                // Use the fetch function to make a POST request to the specified endpoint
                const response = await fetch(jwtEndpoint, requestOptions);

                // Check if the response status code indicates success (e.g., 200 OK)
                if (response.ok) {
                    // Parse the response body as JSON, assuming it contains the JWT
                    const jwtData = await response.json();
                    return jwtData; // Return the JWT data
                } else {
                    // Handle HTTP error responses here if needed
                    throw new Error(`HTTP error! Status: ${response.status}`);
                }
            } catch (error) {
                // Handle any exceptions that may occur during the fetch request
                console.error("Error fetching JWT:", error);
                throw error;
            }
        }

        async function jwtLogin(token) {
            const authHeader = `Bearer ${token}`;
            return await fetch(`https://${TENANT}/login/jwt-session?qlik-web-integration-id=${WEBINTEGRATIONID}`, {
                credentials: "include",
                mode: "cors",
                method: "POST",
                headers: {
                    "Authorization": authHeader,
                    "qlik-web-integration-id": WEBINTEGRATIONID
                },
            })
        }

        async function getQCSHeaders() {
            const response = await fetch(`https://${TENANT}/api/v1/csrf-token`, {
                mode: "cors",
                credentials: "include",
                headers: {
                    "qlik-web-integration-id": WEBINTEGRATIONID
                },
            })

            const csrfToken = new Map(response.headers).get("qlik-csrf-token");
            return {
                "qlik-web-integration-id": WEBINTEGRATIONID,
                "qlik-csrf-token": csrfToken,
            };
        }

        // ENIGMA ENGINE CONNECTION
        async function connectEnigma(qcsHeaders, appId, identity) {
            const [session, app] = await getEnigmaSessionAndApp(appId, qcsHeaders, identity);
            return [session, app];
        }

        async function getEnigmaSessionAndApp(appId, headers, identity) {
            const params = Object.keys(headers)
                .map((key) =&amp;gt; `${key}=${headers[key]}`)
                .join("&amp;amp;");

            return (async () =&amp;gt; {
                const schema = await (await fetch("https://unpkg.com/enigma.js@2.7.0/schemas/12.612.0.json")).json();

                try {
                    return await createEnigmaAppSession(schema, appId, identity, params);
                } catch {
                    // If the socket is closed immediately following the connection this
                    // could be due to an edge-case race condition where the newly created
                    // user does not yet have access to the app due to access control propagation.
                    // This bit of code will make another attempt after a 1.5 seconds.
                    const waitSecond = await new Promise(resolve =&amp;gt; setTimeout(resolve, 1500));
                    try {
                        return await createEnigmaAppSession(schema, appId, identity, params);
                    } catch (e) {
                        throw new Error(e);
                    }
                }
            })();
        }

        async function createEnigmaAppSession(schema, appId, identity, params) {
            const session = enigma.create({
                schema,
                url: `wss://${TENANT}/app/${appId}/identity/${identity}?${params}`,
                createSocket: url =&amp;gt; new WebSocket(`wss://${TENANT}/app/${appId}/identity/${identity}?${params}`),
            });

            const enigmaGlobal = await session.open();
            const enigmaApp = await enigmaGlobal.openDoc(appId);
            return [session, enigmaApp];
        }

        // HANDLE ENGINE SESSION CLOSURE
        function handleDisconnect(session) {
            session.on("closed", () =&amp;gt; {
                console.log("Due to inactivity or loss of connection, this session has ended.");
            });

            session.on("suspended", () =&amp;gt; {
                console.log("Due to loss of connection, this session has been suspended.");
            });

            window.addEventListener("offline", () =&amp;gt; {
                session.close();
            });
        }

        // GET QLIK APP (FOR SPACE ID)
        async function getApp(appId) {
            var url = new URL(`https://${TENANT}/api/v1/items?resourceType=app&amp;amp;resourceId=${appId}`);
            const response = await fetch(url, {
                method: "GET",
                mode: "cors",
                credentials: "include",
                headers: {
                    "Content-Type": "application/json",
                    "qlik-web-integration-id": WEBINTEGRATIONID,
                },
            })
            responseJson = await response.json();
            return responseJson.data[0];
        }

        // GET SPACE (FOR SPACE TYPE)
        async function getSpaceType(spaceId) {
            var url = new URL(`https://${TENANT}/api/v1/spaces/${spaceId}`);
            const response = await fetch(url, {
                method: "GET",
                mode: "cors",
                credentials: "include",
                headers: {
                    "Content-Type": "application/json",
                    "qlik-web-integration-id": WEBINTEGRATIONID,
                },
            })
            responseJson = await response.json();
            return responseJson.type;
        }

        // GET THEME
        async function getTheme(enigmaApp) {
            const createAppProps = await enigmaApp.createSessionObject({
                qInfo: {
                    qId: "AppPropsList",
                    qType: "AppPropsList"
                },
                qAppObjectListDef: {
                    qType: "appprops",
                    qData: {
                        theme: "/theme"
                    }
                }
            });
            const appProps = await enigmaApp.getObject("AppPropsList");
            const appPropsLayout = await appProps.getLayout();
            const theme = appPropsLayout.qAppObjectList.qItems[0].qData.theme;
            return theme;
        }

        // GET SHEETS (WITH TYPE ADDED, E.G., BASE, COMMUNITY, PRIVATE)
        async function getSheetList(app, spaceType) {
            var sheets = await app.getObjects({
                "qOptions": {
                    "qTypes": [
                        "sheet"
                    ],
                    "qIncludeSessionObjects": false,
                    "qData": {}
                }
            })
            sheetsIncludingType = [];
            for await (const sheet of sheets) {
                var pushSheet = true;
                const sheetObject = await app.getObject(sheet.qInfo.qId);
                const sheetLayout = await sheetObject.getLayout();
                var isManaged = spaceType === "managed";
                var sheetTypeEnum = 1;
                var approved = sheet.qMeta.approved;
                var published = sheet.qMeta.published;
                const sheetTypeEnums = {
                    1: "Base",
                    2: "Community",
                    3: "Private"
                };
                if (!approved &amp;amp;&amp;amp; !published) {
                    sheetTypeEnum = 3;
                } else if (!approved &amp;amp;&amp;amp; published) {
                    if (isManaged) {
                        sheetTypeEnum = 2;
                    }
                }
                const sheetTypeObject = {
                    "sheetType": sheetTypeEnums[sheetTypeEnum],
                    "sheetTypeEnum": sheetTypeEnum
                };
                const mergedObject = {
                    ...sheetLayout,
                    ...sheetTypeObject
                };
                sheetsIncludingType.push(mergedObject)
            }
            sheetsIncludingType.sort((a, b) =&amp;gt; (a.sheetTypeEnum - b.sheetTypeEnum || a.rank - b.rank))
            return sheetsIncludingType;
        }

        // HELPER FUNCTION TO GENERATE IFRAME
        function renderSingleIframe(frameId, appId, sheetId, theme, identity) {
            const frameUrl = `https://${TENANT}/single/?appid=${appId}&amp;amp;sheet=${sheetId}&amp;amp;theme=${theme}&amp;amp;identity=${identity}&amp;amp;opt=ctxmenu,currsel`;
            document.getElementById(frameId).setAttribute("src", frameUrl);
        }
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;But when I tried to run, it is not working and returned following &lt;CODE&gt;JS&lt;/CODE&gt; error in console, related to &lt;CODE&gt;Socket&lt;/CODE&gt;:&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="console.log.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/160577i33CFE0400B917466/image-size/medium?v=v2&amp;amp;px=400" role="button" title="console.log.png" alt="console.log.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Following is the network logs when I tried to run this code:&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="network.log.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/160578i27D0E82B71F261AF/image-size/medium?v=v2&amp;amp;px=400" role="button" title="network.log.png" alt="network.log.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Question 2:&lt;/STRONG&gt; How to embed &lt;CODE&gt;sheet/app&lt;/CODE&gt;? In above code, Am I doing something wrong? Or if there are any other way to embed, please suggest me. Because I doubt, that it will need to create a lot of resources on the &lt;CODE&gt;QMC&lt;/CODE&gt;. So there should be some &lt;CODE&gt;API&lt;/CODE&gt;, to authenticate user, get token and use token to get embed code for the &lt;CODE&gt;sheet&lt;/CODE&gt;.&lt;/P&gt;
&lt;P&gt;Please help me. Any suggestion will also be helpful.&lt;/P&gt;
&lt;P&gt;Thank you&lt;/P&gt;</description>
    <pubDate>Fri, 23 Feb 2024 16:42:36 GMT</pubDate>
    <dc:creator>pixlics12</dc:creator>
    <dc:date>2024-02-23T16:42:36Z</dc:date>
    <item>
      <title>How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2423034#M20004</link>
      <description>&lt;P&gt;I want to embed Qlik &lt;CODE&gt;app/sheet&lt;/CODE&gt; on my website. There are &lt;CODE&gt;apps&lt;/CODE&gt; on the Qlik, and the &lt;CODE&gt;apps&lt;/CODE&gt; contains the &lt;CODE&gt;sheets&lt;/CODE&gt;, which I want to embed for showing to website visitors/user. But users don't have access of Qlik, so I need to embed with some kind of authentication by code.&lt;/P&gt;
&lt;P&gt;Before going on the code, I have following things created on the Qlik Management Console (QMC):&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;CODE&gt;Tenant&lt;/CODE&gt; host&lt;/LI&gt;
&lt;LI&gt;Added my domain in the &lt;CODE&gt;Content Security Policy&lt;/CODE&gt; section and selected &lt;CODE&gt;frame-ancestors&lt;/CODE&gt; in the &lt;CODE&gt;Directive&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;CODE&gt;Web Integration Id&lt;/CODE&gt; created in &lt;CODE&gt;Web Integration Configuration&lt;/CODE&gt; section&lt;/LI&gt;
&lt;LI&gt;&lt;CODE&gt;Client Id and secret&lt;/CODE&gt; created in &lt;CODE&gt;OAuth&lt;/CODE&gt; section&lt;/LI&gt;
&lt;LI&gt;&lt;CODE&gt;Public key, Private&lt;/CODE&gt; key created by following this article: &lt;A href="https://qlik.dev/authenticate/jwt/create-signed-tokens-for-jwt-authorization/" rel="nofollow noreferrer" target="_blank"&gt;Create Signed Tokens for JWT Authorization&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;After following above article, I also have &lt;CODE&gt;Issuer, Key ID&lt;/CODE&gt; which I setup in the &lt;CODE&gt;Identity Provider&lt;/CODE&gt; section&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Following is my usecase&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;User first select an &lt;CODE&gt;app&lt;/CODE&gt; from the dropdown, this list populated through the following API:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE&gt;GET https://QLIK-TENANT/api/v1/items?resourceType=app
Header: Bearer &amp;lt;token generated with OAuth Client id and secret&amp;gt;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;And it is working.&lt;/P&gt;
&lt;P&gt;After that I need to show another dropdown for all the &lt;CODE&gt;sheets&lt;/CODE&gt; of the selected &lt;CODE&gt;app&lt;/CODE&gt;. But I am unable to fetch the list of sheets. I checked there is no REST API which can give me &lt;CODE&gt;sheets&lt;/CODE&gt; by an &lt;CODE&gt;app&lt;/CODE&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Question 1:&lt;/STRONG&gt; How can I get sheet list of the app? I also plan to list the &lt;CODE&gt;sheets&lt;/CODE&gt; using below JS code, but that is also not working.&lt;/P&gt;
&lt;P&gt;Once user select app and sheet, then click on a button to Render sheet, and it should render that sheet on the webpage.&lt;/P&gt;
&lt;P&gt;I tried using below piece of code (enigma js), referenced from here: &lt;A href="https://qlik.dev/embed/iframe/customize/handle-sheets-in-iframes-with-enigma/" rel="nofollow noreferrer" target="_blank"&gt;Handle sheets in iframes with enigma.js&lt;/A&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;script src="https://unpkg.com/enigma.js/enigma.min.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div id="main"&amp;gt;
        &amp;lt;div id="message"&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;iframe id="qlik_frame" style="border:none;width:100%;height:900px;"&amp;gt;&amp;lt;/iframe&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;script type="text/javascript"&amp;gt;
        // CONFIGURATION
        const TENANT = "xxxxxxxxxxxxx.xx.qlikcloud.com";
        const JWTENDPOINT = "https://example.com/api/v1/qlik/jwtToken"; // this endpoint create a JWT token using passed data and the private key mentioned in point #6 above
        const WEBINTEGRATIONID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // mentioned in point #3 above
        const APPID = "411111e0-36f8-4e6d-b25d-f0xxxxxxxxca"; // got using the REST API mentioned above
        const IDENTITY = "xxxxxxxxxxxxxx"; // An arbitrary string to establish a separate session state.

        // MAIN
        (async function main() {
            const isLoggedIn = await qlikLogin();
            const qcsHeaders = await getQCSHeaders();
            const [session, enigmaApp] = await connectEnigma(qcsHeaders, APPID, IDENTITY);

            handleDisconnect(session);
            const theme = await getTheme(enigmaApp);
            const spaceId = (await getApp(APPID)).spaceId;
            const spaceType = await getSpaceType(spaceId);
            const sheets = await getSheetList(enigmaApp, spaceType);

            renderSingleIframe("qlik_frame", APPID, sheets[0].qInfo.qId, theme, IDENTITY);
        })();

        // LOGIN
        async function qlikLogin() {
            const loggedIn = await checkLoggedIn();
            if (loggedIn.status !== 200) {
                const $jwtPostData = {
                    kid: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // mentioned in point #6 above
                    iss: "xxxxxxxxxxxxx.xx.qlikcloud.com", 
                    name: "?????????" // what it should be????
                };
                const tokenRes = await (await getJWTToken(JWTENDPOINT, $jwtPostData));
                const loginRes = await jwtLogin(tokenRes.body);

                if (loginRes.status != 200) {
                    const message = "Something went wrong while logging in.";
                    throw new Error(message);
                }
                const recheckLoggedIn = await checkLoggedIn();
                if (recheckLoggedIn.status !== 200) {
                    const message = "Third-party cookies are not enabled in your browser settings and/or browser mode.";
                    throw new Error(message);
                }
            }
            return true;
        }

        async function checkLoggedIn() {
            return await fetch(`https://${TENANT}/api/v1/users/me`, {
                mode: "cors",
                credentials: "include",
                headers: {
                    "qlik-web-integration-id": WEBINTEGRATIONID
                },
            })
        }

        // Get Method the JWT and use it to obtain Qlik Cloud session cookie.
        async function getJWTToken(jwtEndpoint, payloadData) {
            try {
                // Define the headers for the request, including the content type
                const headers = new Headers({
                    "Content-Type": "application/json",
                });

                // Create a request object with the specified method, headers, and body
                const requestOptions = {
                    method: "POST",
                    headers: headers,
                    mode: "cors",
                    body: JSON.stringify(payloadData), // Convert payloadData to JSON
                };

                // Use the fetch function to make a POST request to the specified endpoint
                const response = await fetch(jwtEndpoint, requestOptions);

                // Check if the response status code indicates success (e.g., 200 OK)
                if (response.ok) {
                    // Parse the response body as JSON, assuming it contains the JWT
                    const jwtData = await response.json();
                    return jwtData; // Return the JWT data
                } else {
                    // Handle HTTP error responses here if needed
                    throw new Error(`HTTP error! Status: ${response.status}`);
                }
            } catch (error) {
                // Handle any exceptions that may occur during the fetch request
                console.error("Error fetching JWT:", error);
                throw error;
            }
        }

        async function jwtLogin(token) {
            const authHeader = `Bearer ${token}`;
            return await fetch(`https://${TENANT}/login/jwt-session?qlik-web-integration-id=${WEBINTEGRATIONID}`, {
                credentials: "include",
                mode: "cors",
                method: "POST",
                headers: {
                    "Authorization": authHeader,
                    "qlik-web-integration-id": WEBINTEGRATIONID
                },
            })
        }

        async function getQCSHeaders() {
            const response = await fetch(`https://${TENANT}/api/v1/csrf-token`, {
                mode: "cors",
                credentials: "include",
                headers: {
                    "qlik-web-integration-id": WEBINTEGRATIONID
                },
            })

            const csrfToken = new Map(response.headers).get("qlik-csrf-token");
            return {
                "qlik-web-integration-id": WEBINTEGRATIONID,
                "qlik-csrf-token": csrfToken,
            };
        }

        // ENIGMA ENGINE CONNECTION
        async function connectEnigma(qcsHeaders, appId, identity) {
            const [session, app] = await getEnigmaSessionAndApp(appId, qcsHeaders, identity);
            return [session, app];
        }

        async function getEnigmaSessionAndApp(appId, headers, identity) {
            const params = Object.keys(headers)
                .map((key) =&amp;gt; `${key}=${headers[key]}`)
                .join("&amp;amp;");

            return (async () =&amp;gt; {
                const schema = await (await fetch("https://unpkg.com/enigma.js@2.7.0/schemas/12.612.0.json")).json();

                try {
                    return await createEnigmaAppSession(schema, appId, identity, params);
                } catch {
                    // If the socket is closed immediately following the connection this
                    // could be due to an edge-case race condition where the newly created
                    // user does not yet have access to the app due to access control propagation.
                    // This bit of code will make another attempt after a 1.5 seconds.
                    const waitSecond = await new Promise(resolve =&amp;gt; setTimeout(resolve, 1500));
                    try {
                        return await createEnigmaAppSession(schema, appId, identity, params);
                    } catch (e) {
                        throw new Error(e);
                    }
                }
            })();
        }

        async function createEnigmaAppSession(schema, appId, identity, params) {
            const session = enigma.create({
                schema,
                url: `wss://${TENANT}/app/${appId}/identity/${identity}?${params}`,
                createSocket: url =&amp;gt; new WebSocket(`wss://${TENANT}/app/${appId}/identity/${identity}?${params}`),
            });

            const enigmaGlobal = await session.open();
            const enigmaApp = await enigmaGlobal.openDoc(appId);
            return [session, enigmaApp];
        }

        // HANDLE ENGINE SESSION CLOSURE
        function handleDisconnect(session) {
            session.on("closed", () =&amp;gt; {
                console.log("Due to inactivity or loss of connection, this session has ended.");
            });

            session.on("suspended", () =&amp;gt; {
                console.log("Due to loss of connection, this session has been suspended.");
            });

            window.addEventListener("offline", () =&amp;gt; {
                session.close();
            });
        }

        // GET QLIK APP (FOR SPACE ID)
        async function getApp(appId) {
            var url = new URL(`https://${TENANT}/api/v1/items?resourceType=app&amp;amp;resourceId=${appId}`);
            const response = await fetch(url, {
                method: "GET",
                mode: "cors",
                credentials: "include",
                headers: {
                    "Content-Type": "application/json",
                    "qlik-web-integration-id": WEBINTEGRATIONID,
                },
            })
            responseJson = await response.json();
            return responseJson.data[0];
        }

        // GET SPACE (FOR SPACE TYPE)
        async function getSpaceType(spaceId) {
            var url = new URL(`https://${TENANT}/api/v1/spaces/${spaceId}`);
            const response = await fetch(url, {
                method: "GET",
                mode: "cors",
                credentials: "include",
                headers: {
                    "Content-Type": "application/json",
                    "qlik-web-integration-id": WEBINTEGRATIONID,
                },
            })
            responseJson = await response.json();
            return responseJson.type;
        }

        // GET THEME
        async function getTheme(enigmaApp) {
            const createAppProps = await enigmaApp.createSessionObject({
                qInfo: {
                    qId: "AppPropsList",
                    qType: "AppPropsList"
                },
                qAppObjectListDef: {
                    qType: "appprops",
                    qData: {
                        theme: "/theme"
                    }
                }
            });
            const appProps = await enigmaApp.getObject("AppPropsList");
            const appPropsLayout = await appProps.getLayout();
            const theme = appPropsLayout.qAppObjectList.qItems[0].qData.theme;
            return theme;
        }

        // GET SHEETS (WITH TYPE ADDED, E.G., BASE, COMMUNITY, PRIVATE)
        async function getSheetList(app, spaceType) {
            var sheets = await app.getObjects({
                "qOptions": {
                    "qTypes": [
                        "sheet"
                    ],
                    "qIncludeSessionObjects": false,
                    "qData": {}
                }
            })
            sheetsIncludingType = [];
            for await (const sheet of sheets) {
                var pushSheet = true;
                const sheetObject = await app.getObject(sheet.qInfo.qId);
                const sheetLayout = await sheetObject.getLayout();
                var isManaged = spaceType === "managed";
                var sheetTypeEnum = 1;
                var approved = sheet.qMeta.approved;
                var published = sheet.qMeta.published;
                const sheetTypeEnums = {
                    1: "Base",
                    2: "Community",
                    3: "Private"
                };
                if (!approved &amp;amp;&amp;amp; !published) {
                    sheetTypeEnum = 3;
                } else if (!approved &amp;amp;&amp;amp; published) {
                    if (isManaged) {
                        sheetTypeEnum = 2;
                    }
                }
                const sheetTypeObject = {
                    "sheetType": sheetTypeEnums[sheetTypeEnum],
                    "sheetTypeEnum": sheetTypeEnum
                };
                const mergedObject = {
                    ...sheetLayout,
                    ...sheetTypeObject
                };
                sheetsIncludingType.push(mergedObject)
            }
            sheetsIncludingType.sort((a, b) =&amp;gt; (a.sheetTypeEnum - b.sheetTypeEnum || a.rank - b.rank))
            return sheetsIncludingType;
        }

        // HELPER FUNCTION TO GENERATE IFRAME
        function renderSingleIframe(frameId, appId, sheetId, theme, identity) {
            const frameUrl = `https://${TENANT}/single/?appid=${appId}&amp;amp;sheet=${sheetId}&amp;amp;theme=${theme}&amp;amp;identity=${identity}&amp;amp;opt=ctxmenu,currsel`;
            document.getElementById(frameId).setAttribute("src", frameUrl);
        }
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;But when I tried to run, it is not working and returned following &lt;CODE&gt;JS&lt;/CODE&gt; error in console, related to &lt;CODE&gt;Socket&lt;/CODE&gt;:&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="console.log.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/160577i33CFE0400B917466/image-size/medium?v=v2&amp;amp;px=400" role="button" title="console.log.png" alt="console.log.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Following is the network logs when I tried to run this code:&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="network.log.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/160578i27D0E82B71F261AF/image-size/medium?v=v2&amp;amp;px=400" role="button" title="network.log.png" alt="network.log.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Question 2:&lt;/STRONG&gt; How to embed &lt;CODE&gt;sheet/app&lt;/CODE&gt;? In above code, Am I doing something wrong? Or if there are any other way to embed, please suggest me. Because I doubt, that it will need to create a lot of resources on the &lt;CODE&gt;QMC&lt;/CODE&gt;. So there should be some &lt;CODE&gt;API&lt;/CODE&gt;, to authenticate user, get token and use token to get embed code for the &lt;CODE&gt;sheet&lt;/CODE&gt;.&lt;/P&gt;
&lt;P&gt;Please help me. Any suggestion will also be helpful.&lt;/P&gt;
&lt;P&gt;Thank you&lt;/P&gt;</description>
      <pubDate>Fri, 23 Feb 2024 16:42:36 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2423034#M20004</guid>
      <dc:creator>pixlics12</dc:creator>
      <dc:date>2024-02-23T16:42:36Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2423680#M20019</link>
      <description>&lt;P&gt;Hey &lt;SPAN style="background: var(--ck-color-mention-background); color: var(--ck-color-mention-text);"&gt;&lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/289514"&gt;@pixlics12&lt;/a&gt;&lt;/SPAN&gt; , about your errors, you are using JWT auth, so please check if JWT auth goes correctly and check if Qlik 3rd party cookie is set in browser developer tool. When enigma try to create the websocket, it should leverage the cookie set by JWT login. The call to endpoint /users/me return 401 because you are not authenticahed, and this is ok because the code is handling this part, indeed as next step it starts the JWT authentication. Please aslo check if your web app hostname has been added as origin in web integration id configuration.&lt;/P&gt;
&lt;P&gt;About your questions; question number 1: at the moment you have to use Engine API (or enigma.js) for getting app sheets list. What you have in the example is correct.&lt;BR /&gt;Question number 2: the above code is using iframes the old way of doing this, I suggest to have a look to &lt;A href="https://qlik.dev/embed/qlik-embed/" target="_blank"&gt;qlik-embed&lt;/A&gt; for embedding entire app/sheets. This is the newset way of doing what you are doing.&lt;BR /&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 26 Feb 2024 16:51:04 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2423680#M20019</guid>
      <dc:creator>alex_colombo</dc:creator>
      <dc:date>2024-02-26T16:51:04Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424431#M20031</link>
      <description>&lt;P&gt;Hello &lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/145804"&gt;@alex_colombo&lt;/a&gt;, thank you for the reply.&lt;/P&gt;
&lt;P&gt;I checked and verified that my web app hostname added as origin in web integration id configuration.&lt;/P&gt;
&lt;P&gt;I also checked the &lt;A href="https://qlik.dev/embed/qlik-embed/" target="_blank" rel="nofollow noopener noreferrer"&gt;qlik-embed&lt;/A&gt; but I am still struggling on how to pre authenticate the app/sheet, so that the visitor don't need to authenticate. I just want to integrate app/sheet programmatically so that it will be pre authenticate.&lt;/P&gt;
&lt;P&gt;Can you please help me on this?&lt;/P&gt;</description>
      <pubDate>Wed, 28 Feb 2024 06:18:41 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424431#M20031</guid>
      <dc:creator>pixlics12</dc:creator>
      <dc:date>2024-02-28T06:18:41Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424524#M20033</link>
      <description>&lt;P&gt;&lt;A href="https://qlik.dev/embed/qlik-embed/authenticate/connect-qlik-embed/" target="_blank"&gt;Here &lt;/A&gt;you can find all the possible ways on qlik-embed and authentication. With this you can authenticate against Qlik tenant and then embed app/sheets.&lt;/P&gt;</description>
      <pubDate>Wed, 28 Feb 2024 09:18:13 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424524#M20033</guid>
      <dc:creator>alex_colombo</dc:creator>
      <dc:date>2024-02-28T09:18:13Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424583#M20034</link>
      <description>&lt;P&gt;Hello &lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/145804"&gt;@alex_colombo&lt;/a&gt;, Thank You for reaching out. I tried using the "Using OAuth clients" way.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;It is working as:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;First it will load the page like this with "Authorize" button:&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pixlics12_0-1709114745957.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/160808iEF6F6908FF517054/image-size/medium?v=v2&amp;amp;px=400" role="button" title="pixlics12_0-1709114745957.png" alt="pixlics12_0-1709114745957.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Then after Authorized, it will start showing the targeted object:&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pixlics12_2-1709114885861.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/160810i3FBFEBA45B8AF1A1/image-size/medium?v=v2&amp;amp;px=400" role="button" title="pixlics12_2-1709114885861.png" alt="pixlics12_2-1709114885861.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;But I don't want my users to authorize, I need to make it public, so that the objects/sheets/apps are pre-authorize using code.&lt;/P&gt;
&lt;P&gt;I have an admin panel, where admin controls the main website. Admin authorize once in the admin panel, select the app &amp;gt; sheet OR app &amp;gt; sheet &amp;gt; object, to render on the main website. I want the same object/sheet should render on main website.&lt;/P&gt;
&lt;P&gt;Admin once authorized so as I assume and did for other integrations, I stored the token of current user in safe place, and use same token to render sheet/object every time.&lt;/P&gt;
&lt;P&gt;I also checked&amp;nbsp; but it will need an IdP (Identity Provider), but my account is not setup in that way. I am looking for direct solution.&lt;/P&gt;
&lt;P&gt;Is there any way to did this? please help me.&lt;/P&gt;
&lt;P&gt;Thanks You,&lt;/P&gt;</description>
      <pubDate>Wed, 28 Feb 2024 10:28:41 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424583#M20034</guid>
      <dc:creator>pixlics12</dc:creator>
      <dc:date>2024-02-28T10:28:41Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424614#M20037</link>
      <description>&lt;P&gt;Ok, for avoiding users to click on Qlik OAuth Authorize button you have to do two things.&lt;/P&gt;
&lt;P&gt;First, please change consent method on OAuth configuration like below&lt;/P&gt;
&lt;P&gt;&lt;IMG style="width: 699px;" src="https://lithium-response-prod.s3.us-west-2.amazonaws.com/qlik.response.lithium.com/RESPONSEIMAGE/8b3516d8-9b2f-48d4-ba5e-96a5b5cc7e07.default.png" border="0" height="233" /&gt;&lt;/P&gt;
&lt;P&gt;Second, add &lt;I&gt;data-auto-redirect&lt;/I&gt; attribute and set it to true like below&lt;/P&gt;
&lt;P&gt;&lt;IMG src="https://lithium-response-prod.s3.us-west-2.amazonaws.com/qlik.response.lithium.com/RESPONSEIMAGE/0afc532e-312e-4441-bed5-8b2e818f835c.default.png" border="0" /&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 28 Feb 2024 10:50:44 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424614#M20037</guid>
      <dc:creator>alex_colombo</dc:creator>
      <dc:date>2024-02-28T10:50:44Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424664#M20038</link>
      <description>&lt;P&gt;Thank You &lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/145804"&gt;@alex_colombo&lt;/a&gt;, I tried given changes, it is working, but only if a user is logged in on the same Qlik account on same browser window. If a user is not logged in then it is redirecting user to the Qlik login page. But it doesn't matter user is logged in or not. I need to show the sheet/object always.&lt;/P&gt;
&lt;P&gt;Is this possible?&lt;/P&gt;
&lt;P&gt;Thank You&lt;/P&gt;</description>
      <pubDate>Wed, 28 Feb 2024 11:53:51 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424664#M20038</guid>
      <dc:creator>pixlics12</dc:creator>
      <dc:date>2024-02-28T11:53:51Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424738#M20041</link>
      <description>&lt;P&gt;Basically, if I understood correctly, you need an anonymous user access, correct? To do so, at the moment, you have to use JWT as IdP, and passing your anonymous user. This will create new users into the tenant. &lt;A href="https://qlik.dev/embed/iframe/quickstart/embedding-with-anonymous-access-and-qlik-cloud/#how-anonymous-access-works" target="_blank"&gt;Here &lt;/A&gt;you can find a link where it is explained. It is best practice to setting up anonymous access on a tenant should be done on a dedicated tenant.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;On Management Console side, below few optional things to do:&lt;/P&gt;
&lt;P&gt;Go to Management Console → Configuration → Settings → Feature control. Switch off all except for Creating Groups. If it is already switched off, turn on. This disable some features for anonymous users, it is up to you if this is needed or not.&lt;BR /&gt;Under Entitlements section ensure that you also have turned off Enable dynamic assignment of professional users and Enable dynamic assignment of analyzer users. This will not assigned license to anonymous users. As mentioned above, please use a dedicated tenant for anonymous access.&lt;/P&gt;</description>
      <pubDate>Wed, 28 Feb 2024 13:49:55 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2424738#M20041</guid>
      <dc:creator>alex_colombo</dc:creator>
      <dc:date>2024-02-28T13:49:55Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425244#M20056</link>
      <description>&lt;P&gt;Thank you &lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/145804"&gt;@alex_colombo&lt;/a&gt;, for the reply.&lt;/P&gt;
&lt;P&gt;Yes I need the same, an anonymous user access.&lt;/P&gt;
&lt;P&gt;I am just setting up the things as you mentioned, but can I setup these things on the free/trial account? I am able to see the 'Feature control' and 'Entitlements' in 'Settings', but some options are not visible like 'Creating Groups'.&lt;/P&gt;
&lt;P&gt;So just curious to know, that free/trial account have ability for this or not,&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pixlics12_0-1709204312031.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/160955i67317C2F28E6BC92/image-size/medium?v=v2&amp;amp;px=400" role="button" title="pixlics12_0-1709204312031.png" alt="pixlics12_0-1709204312031.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Thank You.&lt;/P&gt;</description>
      <pubDate>Thu, 29 Feb 2024 11:01:27 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425244#M20056</guid>
      <dc:creator>pixlics12</dc:creator>
      <dc:date>2024-02-29T11:01:27Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425247#M20057</link>
      <description>&lt;P&gt;I think you can try with trial tenant, and as you mentioned, you could have less feature. If you don't have "Creating Groups", you cannot use groups for managing space access, instead use user Id for this testing purpose.&lt;/P&gt;</description>
      <pubDate>Thu, 29 Feb 2024 11:06:49 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425247#M20057</guid>
      <dc:creator>alex_colombo</dc:creator>
      <dc:date>2024-02-29T11:06:49Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425395#M20062</link>
      <description>&lt;P&gt;Thank You &lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/145804"&gt;@alex_colombo&lt;/a&gt; for the reply.&lt;/P&gt;
&lt;P&gt;I tried with the Qlik trial account/tenant but that account doesn't have the 'Identity Provider' menu.&lt;/P&gt;
&lt;P&gt;So recently, I also arranged another Qlik account with premium subscription. Can I create APIs at my own server instead of AWS Lambda platform?&lt;/P&gt;
&lt;P&gt;Thanks,&lt;/P&gt;</description>
      <pubDate>Thu, 29 Feb 2024 15:14:59 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425395#M20062</guid>
      <dc:creator>pixlics12</dc:creator>
      <dc:date>2024-02-29T15:14:59Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425434#M20063</link>
      <description>&lt;P&gt;I'm not understanding the question, which API do you want to create? It is something related to Qlik?&lt;/P&gt;</description>
      <pubDate>Thu, 29 Feb 2024 15:56:03 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425434#M20063</guid>
      <dc:creator>alex_colombo</dc:creator>
      <dc:date>2024-02-29T15:56:03Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425460#M20065</link>
      <description>&lt;P&gt;I mean, the link you shared for "Embed content using IFrames and anonymous access", have some piece of code which setup on the AWS Lambda function, can I do same code at my own server?&lt;/P&gt;</description>
      <pubDate>Thu, 29 Feb 2024 16:20:03 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425460#M20065</guid>
      <dc:creator>pixlics12</dc:creator>
      <dc:date>2024-02-29T16:20:03Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425468#M20066</link>
      <description>&lt;P&gt;yes you can use whatever tool/language you prefer for generating the JWT tokens.&lt;/P&gt;</description>
      <pubDate>Thu, 29 Feb 2024 16:25:49 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425468#M20066</guid>
      <dc:creator>alex_colombo</dc:creator>
      <dc:date>2024-02-29T16:25:49Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425522#M20067</link>
      <description>&lt;P&gt;Thank You &lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/145804"&gt;@alex_colombo&lt;/a&gt;. I go through all the details you shared in this whole conversation and here &lt;A href="https://qlik.dev/embed/iframe/quickstart/embedding-with-anonymous-access-and-qlik-cloud/" target="_self"&gt;Embed content using iframes and anonymous access.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;-----------------------------------------------------------------------------------&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Following is Your reply, sent Yesterday:&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV id="bodyDisplay_6" class="lia-message-body lia-component-message-view-widget-body lia-component-body-signature-highlight-escalation lia-component-message-view-widget-body-signature-highlight-escalation"&gt;
&lt;DIV class="lia-message-body-content"&gt;
&lt;P&gt;&lt;EM&gt;Basically, if I understood correctly, you need an anonymous user access, correct? To do so, at the moment, you have to use JWT as IdP, and passing your anonymous user. This will create new users into the tenant. &lt;A href="https://qlik.dev/embed/iframe/quickstart/embedding-with-anonymous-access-and-qlik-cloud/#how-anonymous-access-works" target="_blank" rel="nofollow noopener noreferrer"&gt;Here &lt;/A&gt;you can find a link where it is explained. It is best practice to setting up anonymous access on a tenant should be done on a dedicated tenant.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;On Management Console side, below few optional things to do:&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Go to Management Console → Configuration → Settings → Feature control. Switch off all except for Creating Groups. If it is already switched off, turn on. This disable some features for anonymous users, it is up to you if this is needed or not.&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;Under Entitlements section ensure that you also have turned off Enable dynamic assignment of professional users and Enable dynamic assignment of analyzer users. This will not assigned license to anonymous users. As mentioned above, please use a dedicated tenant for anonymous access.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;-----------------------------------------------------------------------------------&lt;/P&gt;
&lt;P&gt;I find out and conclude that I already followed all the steps, and also have all the things which mentioned in this article (&lt;A href="https://qlik.dev/embed/iframe/quickstart/embedding-with-anonymous-access-and-qlik-cloud/" target="_self"&gt;Embed content using iframes and anonymous access&lt;/A&gt;) as I also mentioned in my top question.&lt;/P&gt;
&lt;P&gt;The code is also quite similar, just some minor differences are there. When I tried steps of this article, I reached at same error which I asked in the top question: &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Console error&lt;BR /&gt;&lt;/STRONG&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pixlics12_0-1709227142697.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/161014i5CD639F1DA40DBC4/image-size/medium?v=v2&amp;amp;px=400" role="button" title="pixlics12_0-1709227142697.png" alt="pixlics12_0-1709227142697.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Network Log&lt;BR /&gt;&lt;/STRONG&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pixlics12_1-1709228936882.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/161017iB7DEB2EBEE8B4132/image-size/medium?v=v2&amp;amp;px=400" role="button" title="pixlics12_1-1709228936882.png" alt="pixlics12_1-1709228936882.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;-----------------------------------------------------------------------------------&lt;BR /&gt;One more thing I noticed today, that the new code is creating an anonymous user every time when I run my code.&lt;/P&gt;
&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pixlics12_2-1709229053699.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/161019i71083EE8830A148A/image-size/medium?v=v2&amp;amp;px=400" role="button" title="pixlics12_2-1709229053699.png" alt="pixlics12_2-1709229053699.png" /&gt;&lt;/span&gt;
&lt;P&gt;-----------------------------------------------------------------------------------&lt;/P&gt;
&lt;P&gt;As I replied that I have arranged another Qlik account with premium subscription, I did setup on same account, and above attached screenshots are for same premium account.&lt;BR /&gt;I don't have full access of that account, so below things are remaining to setup as you said:&lt;BR /&gt;- Management Console → Configuration → Settings → Feature control/Entitlements&lt;/P&gt;
&lt;P&gt;Is this mandatory steps to follow in QMC, or just optional?&lt;/P&gt;
&lt;P&gt;Thank You &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;</description>
      <pubDate>Thu, 29 Feb 2024 18:00:07 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425522#M20067</guid>
      <dc:creator>pixlics12</dc:creator>
      <dc:date>2024-02-29T18:00:07Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425790#M20079</link>
      <description>&lt;P&gt;Those steps are not mandatory, it depends which kind of features you want to provide to your anonymous users. About the error, I should see it in actions and troubleshoot it, I can't help much than this at this stage. I just want to highlight that where you see a 401 error on users/me API call, this is correct becuase at first time you are not logged in, that's why you received 401.&lt;/P&gt;</description>
      <pubDate>Fri, 01 Mar 2024 09:56:45 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425790#M20079</guid>
      <dc:creator>alex_colombo</dc:creator>
      <dc:date>2024-03-01T09:56:45Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425894#M20082</link>
      <description>&lt;P&gt;ok&amp;nbsp;&lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/145804"&gt;@alex_colombo&lt;/a&gt;, Thank you and appreciate your efforts and help.&lt;/P&gt;
&lt;P&gt;I will reach out to you, if need something on this.&lt;/P&gt;
&lt;P&gt;Thank You very much. &lt;span class="lia-unicode-emoji" title=":thumbs_up:"&gt;👍🏻&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 01 Mar 2024 12:39:27 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2425894#M20082</guid>
      <dc:creator>pixlics12</dc:creator>
      <dc:date>2024-03-01T12:39:27Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2431456#M20220</link>
      <description>&lt;P&gt;Hello &lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/145804"&gt;@alex_colombo&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;Thank you for all of your help, now finally I am able to embed sheet of an app, using the code which I asked in the question using Enigma.js.&lt;/P&gt;
&lt;P&gt;One thing I tried, and it works. I made some changes in the code which generates JWT token. Now I am using following Payload:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;$payload = array(
	"jti" =&amp;gt; guidv4(),
	"sub" =&amp;gt; $sub,
	"subType" =&amp;gt; "user",
	"name" =&amp;gt; 'Qlik Test',
	"email" =&amp;gt; 'qliktest@xyz.com',
	"email_verified" =&amp;gt; true,
	"exp" =&amp;gt; $expir,
	"nbf" =&amp;gt; $not_before,
	"iat" =&amp;gt; $current_time,
	"aud" =&amp;gt; "qlik.api/login/jwt-session",
	"iss" =&amp;gt; $tenant,
	"groups" =&amp;gt; array('anonymous')
);&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Prior, I was using the random "name" and "email". But now I am using the "name" and "email" of my user. And I am using same email to login on the Qlik Cloud.And after this change I am able to embed sheet of an app.&lt;/P&gt;
&lt;P&gt;----------------------------------------------------------------------------------&lt;/P&gt;
&lt;P&gt;But I am facing an issue. I am able to list all of the apps by following API which I am seeing on the Qlik Cloud:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;GET https://xxxxxxxxxxxxxxx.us.qlikcloud.com/api/v1/items?resourceType=app&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;But I am unable to embed the sheets of all the apps.&lt;/P&gt;
&lt;P&gt;I tried to find out the root cause, and got that I can embed the sheets of only app where I am the owner.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pixlics12_0-1710523093826.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/162126i359499D7408F07EE/image-size/medium?v=v2&amp;amp;px=400" role="button" title="pixlics12_0-1710523093826.png" alt="pixlics12_0-1710523093826.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;There are more than 300 other apps listed on the Qlik Cloud, and I am unable to embed them. I can view all of the apps and sheets on the Qlik Cloud.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pixlics12_1-1710523954558.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/162127i7DBAEAC5CADAD03A/image-size/medium?v=v2&amp;amp;px=400" role="button" title="pixlics12_1-1710523954558.png" alt="pixlics12_1-1710523954558.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;If I am able to view the app on the Qlik, then it should be embed too.&lt;BR /&gt;Can you please help to figure out what I am missing. I think there are some permission related issue. Or only the creator/owner of the app can embed the app.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;EDIT&lt;/STRONG&gt;: One more thing I noticed, all other apps have spaceId, but the app which I owned don't have spaceId,&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pixlics12_1-1710526556096.png" style="width: 400px;"&gt;&lt;img src="https://community.qlik.com/t5/image/serverpage/image-id/162130i0A99A6F5A8E43B3C/image-size/medium?v=v2&amp;amp;px=400" role="button" title="pixlics12_1-1710526556096.png" alt="pixlics12_1-1710526556096.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Thank You&lt;/P&gt;</description>
      <pubDate>Fri, 15 Mar 2024 18:16:43 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2431456#M20220</guid>
      <dc:creator>pixlics12</dc:creator>
      <dc:date>2024-03-15T18:16:43Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2431458#M20221</link>
      <description>&lt;P&gt;Also, can you please answer last question and mention all of the issues which we discussed in this conversation in a single message, so that I will mark and accept that as a solution. It will be helpful for other people also.&lt;/P&gt;</description>
      <pubDate>Fri, 15 Mar 2024 17:43:55 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2431458#M20221</guid>
      <dc:creator>pixlics12</dc:creator>
      <dc:date>2024-03-15T17:43:55Z</dc:date>
    </item>
    <item>
      <title>Re: How to embed Qlik App/Sheet on the website</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2432720#M20232</link>
      <description>&lt;P&gt;&lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/289514"&gt;@pixlics12&lt;/a&gt;&amp;nbsp;try to open the app and check if you are able to see the sheets. Maybe sheets are not published by app owner, that's why you are not able to see them.&lt;/P&gt;
&lt;P&gt;About marking the solution as accepted, please pick one and mark it, it is enugh.&lt;/P&gt;</description>
      <pubDate>Wed, 20 Mar 2024 09:57:47 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/How-to-embed-Qlik-App-Sheet-on-the-website/m-p/2432720#M20232</guid>
      <dc:creator>alex_colombo</dc:creator>
      <dc:date>2024-03-20T09:57:47Z</dc:date>
    </item>
  </channel>
</rss>

