Skip to content

Working with Qlik Sense bookmarks

Introduction

Bookmarks in Qlik Sense are a way to save selections for later use. You can create, interact with, and delete bookmarks using qlik-embed.

A complete example is available at the end of this guide.

Prerequisites

To use the example page in this guide, ensure that you have the following:

Variable substitution and vocabulary

Throughout this tutorial, variables will be used to communicate value placement. The variable substitution format is VARIABLE_NAME or <VARIABLE_NAME>. Here is a list of variables that appear in the sample code.

VariableDescription
QLIK_TENANT_URLThe domain for the tenant you are accessing. Equivalent to tenant.region.qlikcloud.com.
QLIK_OAUTH_CLIENT_IDThe clientId of the OAuth SPA you configured.
QLIK_REDIRECT_URIThe Redirect URL for the OAuth2 client to provide an access token.
QLIK_APP_IDThe unique identifier of the application.
QLIK_OBJECT_IDThe unique identifier of the sheet.

This example loads these values from process.env, which you can set in a .env file and reference when running the example with node.js 20+ using node --env-file=.env server.js.

You must connect to the Qlik Sense app before applying existing bookmarks or creating new ones. You do this using the qix.openAppSession method.

import { auth, qix } from "https://cdn.jsdelivr.net/npm/@qlik/api/index.js";


// Retrieve settings from environment
const QLIK_TENANT_URL = process.env.QLIK_TENANT_URL;
const QLIK_OAUTH_CLIENT_ID = process.env.QLIK_OAUTH_CLIENT_ID;
const QLIK_APP_ID = process.env.QLIK_APP_ID;
const QLIK_SHEET_ID = process.env.QLIK_SHEET_ID;
const QLIK_REDIRECT_URI = process.env.QLIK_REDIRECT_URI;


// OAuth authentication settings
const hostConfig = {
    host: QLIK_TENANT_URL,
    authType: "oauth2",
    clientId: QLIK_OAUTH_CLIENT_ID,
    redirectUri: QLIK_REDIRECT_URI
};

auth.setDefaultHostConfig(hostConfig);

let app;

async function initQlik() {
    try {
        const session = await qix.openAppSession(QLIK_APP_ID);
        app = await session.getDoc();
        console.log("Qlik app initialized:", app);
    } catch (error) {
        console.error("Error initializing Qlik:", error);
    }
}

Examples of use

Learn what you can do with the Bookmark API.

Create a new bookmark based on the current selection

Use the createBookmark method of the Qix Doc object object to create a bookmark based on the current selection.

let bmkId = null;

async function createBookmarks() {
    if (!app) {
        console.error("App is not initialized");
        return;
    }

    try {
        const newBookmark = await app.createBookmark({
            qInfo: {
                qType: "bookmark",
            },
            qMetaDef: {
                title: "MyBookmark",
                // You can add more meta properties as needed
            },
            qData: {
                bookmark: "MyBookmark",
                description: "This is a sample bookmark",
                // Add more data properties as needed
            },
        });
        console.log("BookmarkId created:", newBookmark.id);
        bmkId = newBookmark.id;
    } catch (error) {
        console.error("Error creating bookmark:", error);
    }
}

The JSON payload provided as a parameter to the createBookmark method contains these properties:

  • qType: The type of object being created. In this case, a bookmark. Must be part of the qInfo object.
  • title: The title is the value shown in the Qlik Sense user interface when users access bookmarks. Must be part of the qMetaDef object.
  • description: A snippet of text for telling users what the bookmark is going to do. Must be part of the qData object.

Remove a bookmark that you have applied

Use the destroyBookmark method to remove an existing bookmark.

async function removeBookmark(bookmarkId) {
    if (!app) {
        console.error("App is not initialized");
        return;
    }

    if (!bookmarkId) {
        console.error("bookmarkId is not initialized");
        return;
    }

    try {
        await app.destroyBookmark(bookmarkId);
        console.log("Bookmark removed:", bookmarkId);
    } catch (error) {
        console.error("Error removing bookmark:", error);
    }
}

Full code example

Below is an example built using qlik-api and qlik-embed web components.

Style sheet: web-component-bookmark.css

body,
html {
    margin: 0;
    padding: 0;
    font-family: sans-serif;
    font-size: 14px;
    background-color: #f5f5f5;
    color: #333;
    height: 100%;
    width: 100%;
}

.flex-container {
    display: flex;
    flex-wrap: wrap;
    margin: 0 45px 45px 0;
}

.qvobject {
    flex: 1 1 auto;
    height: 300px;
    min-width: 400px;
    margin: 45px 0 0 45px;
}

.buttons-container {
    position: fixed;
    top: 10px;
    left: 10px;
    z-index: 1000;
}

button {
    margin-right: 10px;
}

JavaScript: web-component-bookmark.js

import { auth, qix } from "https://cdn.jsdelivr.net/npm/@qlik/api/index.js";


// Retrieve settings from environment
const QLIK_TENANT_URL = process.env.QLIK_TENANT_URL;
const QLIK_OAUTH_CLIENT_ID = process.env.QLIK_OAUTH_CLIENT_ID;
const QLIK_APP_ID = process.env.QLIK_APP_ID;
const QLIK_SHEET_ID = process.env.QLIK_SHEET_ID;
const QLIK_REDIRECT_URI = process.env.QLIK_REDIRECT_URI;


// OAuth authentication settings
const hostConfig = {
    host: QLIK_TENANT_URL,
    authType: "oauth2",
    clientId: QLIK_OAUTH_CLIENT_ID,
    redirectUri: QLIK_REDIRECT_URI
};

auth.setDefaultHostConfig(hostConfig);

let app;

async function initQlik() {
    try {
        const session = await qix.openAppSession(QLIK_APP_ID);
        app = await session.getDoc();
        console.log("Qlik app initialized:", app);
    } catch (error) {
        console.error("Error initializing Qlik:", error);
    }
}

let bmkId = null;

async function createBookmarks() {
    if (!app) {
        console.error("App is not initialized");
        return;
    }

    try {
        const newBookmark = await app.createBookmark({
            qInfo: {
                qType: "bookmark",
            },
            qMetaDef: {
                title: "MyBookmark",
                // You can add more meta properties as needed
            },
            qData: {
                bookmark: "MyBookmark",
                description: "This is a sample bookmark",
                // Add more data properties as needed
            },
        });
        console.log("BookmarkId created:", newBookmark.id);
        bmkId = newBookmark.id;
    } catch (error) {
        console.error("Error creating bookmark:", error);
    }
}

async function removeBookmark(bookmarkId) {
    if (!app) {
        console.error("App is not initialized");
        return;
    }

    if (!bookmarkId) {
        console.error("bookmarkId is not initialized");
        return;
    }

    try {
        await app.destroyBookmark(bookmarkId);
        console.log("Bookmark removed:", bookmarkId);
    } catch (error) {
        console.error("Error removing bookmark:", error);
    }
}

document.addEventListener("DOMContentLoaded", async () => {
    await initQlik();
    document.getElementById("toggleBookmark").addEventListener("click", createBookmarks);
    document.getElementById("removeBookmark").addEventListener("click", () => {
        removeBookmark(bmkId);
    });
});

HTML: web-component-bookmark.html

<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="<QLIK_TENANT_URL>/resources/autogenerated/qlik-styles.css" />
    <link rel="stylesheet" href="web-component-variable.css" />
    <script crossorigin="anonymous" type="application/javascript"
        src="https://cdn.jsdelivr.net/npm/@qlik/embed-web-components@1/dist/index.min.js"
        data-host="<QLIK_TENANT_URL>" data-client-id="<QLIK_OAUTH_CLIENT_ID>"
        data-redirect-uri="<QLIK_REDIRECT_URI>" data-access-token-storage="session"></script>
    <script type="module" src="web-component-bookmark.js"></script>
</head>

<body>
    <div class="buttons-container">
        <button id="toggleBookmark">Toggle bookmark</button>
        <button id="removeBookmark">Remove bookmark</button>
    </div>
    <div class="flex-container">
        <div class="qvobject">
            <qlik-embed ui="analytics/chart" app-id="<QLIK_APP_ID>" object-id="<QLIK_OBJECT_ID>" />
        </div>
    </div>
</body>

</html>

Was this page helpful?