diff --git a/src/index.html b/src/index.html
index 52cf5067e7a7dc96679aa3e66cb932d5a043632a..3acb8320a1996351f17cc2035f5f578bd6bd9b96 100644
--- a/src/index.html
+++ b/src/index.html
@@ -16,10 +16,6 @@
       integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf"
       crossorigin="anonymous"
     ></script>
-    <script>
-      hljs.highlightAll();
-    </script>
-
     <title>Dashboard SDK Example</title>
   </head>
   <body>
@@ -46,7 +42,31 @@
       </div>
     </div>
 
-    <!-- Modal -->
+    <div class="p-3">
+      <h3>Settings</h3>
+      <div class="mb-3">
+        <label for="endpointInput" class="form-label">Polaris Rights Engine Endpoint</label>
+        <input type="text" class="form-control" id="endpointInput" aria-describedby="endpointHelp" />
+        <div id="endpointHelp" class="form-text">e.g. http://127.0.0.1:8003/api/v1/provider/result</div>
+      </div>
+      <div class="mb-3">
+        <label for="tokenInput" class="form-label">JWT Token</label>
+        <input type="text" class="form-control" id="tokenInput" aria-describedby="tokenHelp" />
+        <div id="tokenHelp" class="form-text">
+          Create visualization token for testing:
+          <p>
+            curl -X POST http://[RIGHTS_ENGINE]/api/v1/provider/visualization-tokens/create --data '{"engines":
+            ["count_h5p_statements", "collect_h5p_count_statements", "collect_counts_all_providers",
+            "count_moodle_statements", "collect_counts_all_providers"], "context_id": "user1@polaris.com",
+            "engines_with_context": ["h5p_count_user_statements", "h5p_statements_distribution"]}' -H "Content-Type:
+            application/json" -H "Authorization: Basic [APPLICATION_TOKEN]"
+          </p>
+        </div>
+      </div>
+      <button type="submit" id="saveSettingsBtn" class="btn btn-primary">Save</button>
+    </div>
+
+    <!-- Widget Description Modal -->
     <div class="modal fade" id="myModal" role="dialog">
       <div class="modal-dialog">
         <!-- Modal content-->
@@ -56,6 +76,16 @@
       </div>
     </div>
 
+    <!-- Error Modal -->
+    <div class="modal fade" id="myErrorModal" role="dialog">
+      <div class="modal-dialog">
+        <!-- Modal content-->
+        <div class="modal-content">
+          <div class="modal-body" id="error-modal-content-body"></div>
+        </div>
+      </div>
+    </div>
+
     <script defer src="./bundle.js"></script>
   </body>
 </html>
diff --git a/src/js/app.js b/src/js/app.js
index 3447a826ee75b8d9d89f70d309516b3c3fbcc5c6..03fe2d883d6d8a927e5924e05c3701af60b9efcb 100644
--- a/src/js/app.js
+++ b/src/js/app.js
@@ -14,11 +14,11 @@ import { CourseRatingChart } from "./custom-charts/courseRatingChart";
  * JWT Token - hardcoded for demotrastion
  * This jwt token is generated in the backend.
  */
-const TOKEN =
+let token =
   "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJjb250ZXh0X2lkIjoidXNlcjFAcG9sYXJpcy5jb20iLCJleHAiOjE2Nzg5NzA4NTIsImVuZ2luZXMiOlsxLDQsNSwyLDVdLCJlbmdpbmVzX3dpdGhfY29udGV4dCI6WzYsN119.WxxMD5BWWHw5o_X1bbtfNP9ExFfbZjr-qam5g7xaxCq-ri0cu0USTD_8ux6jKqJLupVVUtysHxxJc9w03a6IY7Sn63tMLnP1lswm8SNrGr21RFg3n95Nf4vNGzeDNuT2_gdqUX65_wnf504K-f770JP7WcdDuJyZTLbgs0sFBUiM8VtKvRpHzVyEGszvIO4rnJiME5IL7yzUR92kcz1zqcL9If53a9vakf2y0BQRZTzUsdPokDDHMGyzCwJZq0tHG1d-06ZNl4XvkCD_96mdsj79oC26QrDN0zQBeOqHDmTiPUnLJFQkPwBhipsnnwKJ_zJkKMuEqlzlZm01wEhwdpj1dmxthiuC7EY8mvpmSDD73EStmjf7BOvwu9cYoDOeJXeSg2pdiqw9E1XfsGj7Va7UY1km8N1p5ZZzzzsrOVuX6hDZTQ7n1pjI2dnLO0I0QFpd30EOWtqOO58fQyD564UDWkX-avGahFKm3mRJ8H42PdEtslkSP9AO7ztFWa1Du8NcchyTW2Iomh-ztJGk4kCTR37eyumP9yDdzfQLsVPEbUtgZrJXfPKwA57eeD5BDNey15qLdA_HGF8FueMDZ-Y1f6C039WjoWQETy_TA17-VSvITy437sCq3sGDa9-ErNwc-K7E3dfiGHFxch_2zMI3Gm-vmlMoWO0IMAXrmBA";
 
 // Rights Engine Endpoint
-const URL = "http://vs-code-cloud.digitallearning.gmbh:8003/api/v1/provider/result";
+let url = "http://localhost:8003/api/v1/provider/result";
 
 const subGrid = [
   { x: 0, y: 0, w: 4, h: 4, widgetId: "second-widget" },
@@ -101,10 +101,22 @@ const onShowDesc = (desc) => {
 };
 
 /**
- * Get analytics engine results and render widgets
+ * Opens bootstrap error modal.
+ * @param {*} message
  */
-getResult(TOKEN, URL).then((data) => {
-  //  Create widgets with data from analytics engine results
+const showErrorModal = (message) => {
+  const modalContent = document.getElementById("error-modal-content-body");
+  modalContent.innerText = message;
+  const modal = new bootstrap.Modal(document.getElementById("myErrorModal"), {});
+  modal.show();
+};
+
+/**
+ *  Built widgets from results data.
+ * @param {*} data
+ * @returns
+ */
+const buildWidgets = (data) => {
   const widgets = {
     "second-widget": new BarChartWidget(
       "Statements H5P",
@@ -211,8 +223,16 @@ getResult(TOKEN, URL).then((data) => {
     ),
   };
 
+  return widgets;
+};
+
+const setupGrid = (data) => {
+  //  Create widgets with data from analytics engine results
+
+  const widgets = buildWidgets(data);
+
   // Initialize grid with widgets at configured positions
-  const grid = initGrid(widgets, widgets_confgg);
+  grid = initGrid(widgets, widgets_confgg);
 
   // Handle toggle button click
   const toggleBtn = document.getElementById("toggle-sidebar-btn");
@@ -230,4 +250,42 @@ getResult(TOKEN, URL).then((data) => {
       grid.load(oldGrid);
     }, 2000);
   };
-});
+};
+
+let grid = null;
+
+const onInit = () => {
+  // Set default settings value in UI
+  document.getElementById("endpointInput").value = url;
+  document.getElementById("tokenInput").value = token;
+
+  const saveSettingsBtn = document.getElementById("saveSettingsBtn");
+  saveSettingsBtn.addEventListener("click", handleSaveSettingsClick);
+
+  /**
+   * Get analytics engine results and render widgets
+   */
+  getResult(token, url)
+    .then(setupGrid)
+    .catch((err) => {
+      showErrorModal(err.message);
+    });
+};
+
+const handleSaveSettingsClick = () => {
+  url = document.getElementById("endpointInput").value;
+  token = document.getElementById("tokenInput").value;
+
+  getResult(token, url)
+    .then((data) => {
+      if (grid) {
+        const newWidgets = buildWidgets(data);
+        grid.refreshWidgets(newWidgets);
+      } else setupGrid(data);
+    })
+    .catch((err) => {
+      showErrorModal(err.message);
+    });
+};
+
+onInit();