Skip to content

Step-by-Step Guide: Create Dynamic Dashboards with Real-Time Data

Step-by-Step Guide: Create Dynamic Dashboards with Real-Time Data
Step-by-Step Guide: Create Dynamic Dashboards with Real-Time Data

Overview

The Custom Visual Data App follows the same dynamic SQL model setup as other Data App types, but replaces the built-in chart renderer with a fully custom React/TypeScript UI. The visual is defined in a provided App.tsx template, customized by the developer, bundled into a single .js file using the instructions in the template repository README, and uploaded to UNIFI. The resulting widget embeds identically to any other Data App.

Use case: When the built-in chart types (bar, line, table, etc.) are insufficient — for example, custom KPI cards, bespoke layouts, branded dashboards, or interactive data displays — the Custom Visual workflow allows full UI control using React while still connecting to the same UNIFI data pipeline.
Note: Access to the custom visual template repository will be provided separately. This document covers the workflow steps once the template repo is available.

How It Works

The custom visual template is a React + TypeScript project. UNIFI communicates with it through sessionStorage — when the Data App runs, it writes the query results as JSON into a known sessionStorage key. The App.tsx file reads from that key, parses the data, and renders whatever UI the developer has defined.

ComponentRole
Dynamic SQL ModelQueries the database and returns structured JSON results to UNIFI
UNIFI sessionStorage bridgeUNIFI writes query results into sessionStorage under the SESSION_STORAGE_KEY at runtime
App.tsxDeveloper-edited entry point — reads from sessionStorage, parses results, renders custom UI
Template repo + READMEProvides the project scaffold, build tooling, and bundling instructions
Bundled .js fileThe build output — a single JavaScript file uploaded to UNIFI as the custom visual

The SESSION_STORAGE_KEY

The session storage key is the critical bridge between UNIFI and the custom visual. UNIFI generates a unique key for each Data App instance and writes the query result JSON to that key at runtime. App.tsx must use the matching key to read the data.

// App.tsx — the two key identifiers for a custom visual instance
// 1. Session storage key — UNIFI writes query results here at runtimeexport const SESSION_STORAGE_KEY = “0e35b917-1970-443a-adb6-0da622c9c0c9”;
// 2. Data App ID and token — read from URL params at runtimeexport const dataAppId = new URLSearchParams(window.location.search).get(“dataAppId”);export const dataAppToken = new URLSearchParams(window.location.search).get(“dataAppToken”);
// Reading the data UNIFI has written:const sessionStorageData = sessionStorage.getItem(SESSION_STORAGE_KEY);const visualData = sessionStorageData ? JSON.parse(sessionStorageData) : [];
Tip: The SESSION_STORAGE_KEY is unique per Data App instance. If you create a new custom visual Data App, UNIFI will generate a new key — update App.tsx with the new key before rebuilding and re-uploading.

Step 1 — Create the Dynamic SQL Data Model

In UNIFI: Models → Add Model → select your PostgreSQL source → Dynamic Query

This step is identical to other Data App types. The custom visual uses the same dynamic SQL model requirement — the query must include at least one :variable token.

RequirementDetail
Retrieval methodDynamic Query — required for all Data Apps
Variable syntaxColon prefix: :variable_name
Retrieve-all workaroundWHERE ‘:variable’ IS NOT NULL — returns all rows when no filtering is needed
DOM selector bindingConfigured in the model’s ‘Harvest your data’ step — maps a DOM element to each :variable
PreviewAlways use Show Preview before saving — column names become available to App.tsx via the data JSON
Tip: The column names returned by the SQL query are the keys you will reference in App.tsx when iterating over visualData. Confirm the column names in Show Preview before writing UI code against them.

Step 2 — Create the Custom Visual Data App

In UNIFI: Data Apps → New Data App → select your model → Custom Visual

2.1  Select Custom Visual Type

  1. Create a new Data App and select the dynamic SQL model created in Step 1
  2. In the visual type selector, choose Custom Visual
  3. UNIFI will display the SESSION_STORAGE_KEY for this Data App instance — copy it immediately
Important: Copy the SESSION_STORAGE_KEY before navigating away. This key is unique to this Data App instance and must be pasted into App.tsx. If you lose it, you can find it again by reopening the custom visual configuration screen.

2.2  Note the Key and Identifiers

Record the following values from the UNIFI screen — you will need them in App.tsx:

IdentifierWhere to Find It
SESSION_STORAGE_KEYDisplayed on the Custom Visual configuration screen when the visual type is selected — a UUID string
dataAppIdRead automatically at runtime from the URL query parameter dataAppId — no manual action needed
dataAppTokenRead automatically at runtime from the URL query parameter dataAppToken — no manual action needed

Step 3 — Edit App.tsx

In the custom visual template repository — edit src/App.tsx

The template repository provides a React + TypeScript project scaffold with App.tsx as the only file you need to modify. All other project files (build config, dependencies, bundler setup) are pre-configured.

3.1  Update the SESSION_STORAGE_KEY

  1. Open src/App.tsx in the template repository
  2. Replace the value of SESSION_STORAGE_KEY with the key copied from UNIFI in Step 2:
// Replace this value with the key from your UNIFI Data App instance:export const SESSION_STORAGE_KEY = “paste-your-key-here”;

3.2  Access the Data

The template already includes the sessionStorage read pattern. The visualData variable holds the parsed JSON array of rows returned by your SQL model:

// This is already in the template — no changes needed hereconst sessionStorageData = sessionStorage.getItem(SESSION_STORAGE_KEY);const visualData = sessionStorageData ? JSON.parse(sessionStorageData) : [];
// visualData is an array of row objects.// Each object’s keys match the column names from your SQL query.// Example — if your query returns ‘category’ and ‘total_value’:// visualData = [{ category: ‘Electronics’, total_value: 42000 }, …]

3.3  Build Your Custom UI

Replace the template return statement with your custom React UI. Use visualData to drive the rendering:

// Example: render a custom list of rowsreturn (  <Box p={4}>    {visualData.map((row, i) => (      <Text key={i}>{row.category}: {row.total_value}</Text>    ))}  </Box>);
// You can use any React-compatible library available in the template// (Chakra UI components are pre-installed in the scaffold)
Tip: The template includes Chakra UI out of the box. You can import Box, Text, Code, Table, and other Chakra components without any additional installation. Add other libraries via npm install if needed, then re-run the build.

Step 4 — Build and Upload

4.1  Build the .js Bundle

Follow the README instructions in the template repository to produce a single bundled .js file. The general steps are:

# Install dependencies (first time only)npm install
# Build the production bundlenpm run build
# The output .js file will be in the dist/ folder# Exact filename and path are specified in the README
Important: Always rebuild after any change to App.tsx — including updating the SESSION_STORAGE_KEY. The uploaded .js file must match the current state of your code for UNIFI to read data correctly.

4.2  Upload to UNIFI

  1. Return to the Custom Visual Data App configuration screen in UNIFI
  2. Click Upload or Upload Custom Visual and select the bundled .js file from the dist/ folder
  3. UNIFI will validate and register the file as the visual for this Data App instance
  4. Save the Data App configuration

4.3  Test the Visual

  1. Open the Data App preview inside UNIFI to confirm the custom visual renders with live data
  2. If the visual shows ‘No data available’ or is blank, verify the SESSION_STORAGE_KEY in App.tsx matches the key shown in UNIFI exactly
  3. If the visual shows ‘No data app id or token’, confirm the Data App is being accessed via the correct UNIFI-generated URL with dataAppId and dataAppToken query parameters
  4. Iterate on App.tsx, rebuild, and re-upload as needed until the visual renders correctly

Step 5 — Embed in an HTML Page

Once the custom visual is validated in UNIFI, export and embed it the same way as any other Data App:

  1. In the Data App, click Export or Embed to get the JavaScript snippet
  2. Paste the snippet into your target HTML page inside a <script> tag
  3. If the model uses filter variables, add the corresponding DOM elements with matching IDs
  4. Open the HTML page in a browser and confirm the custom visual loads and renders data correctly
Tip: The exported embed snippet is self-contained and references your uploaded custom visual bundle. If you update and re-upload the .js file in UNIFI, the embed snippet does not need to change — it will automatically use the latest uploaded version.

Troubleshooting

SymptomResolution
Visual shows ‘No data available’Check that SESSION_STORAGE_KEY in App.tsx exactly matches the key from UNIFI. Rebuild and re-upload after any change.
Visual shows ‘No data app id or token’The app is not being loaded via the UNIFI-generated URL. Access it through UNIFI’s Data App embed or preview, which appends dataAppId and dataAppToken as query parameters.
visualData is empty arrayThe SQL model returned no rows. Check the query and DOM selector binding in the model configuration. Use Show Preview in the model to verify data is returned.
Column names not matching in App.tsxThe keys in visualData rows match the SQL column names exactly (case-sensitive). Re-run Show Preview in the model to confirm the exact column names.
Build failsCheck the README for the correct Node.js version and build command. Run npm install before building if dependencies are missing.

Quick Reference — Workflow Summary

StepActionKey Detail
1Create Dynamic SQL ModelSame as other Data Apps — Dynamic Query with :variable; retrieve-all or real filter; configure DOM selector binding
2Create Custom Visual Data AppSelect Custom Visual type; copy the SESSION_STORAGE_KEY immediately
3aUpdate SESSION_STORAGE_KEYPaste the UNIFI-generated key into the SESSION_STORAGE_KEY constant in App.tsx
3bAccess visualDatasessionStorage.getItem(SESSION_STORAGE_KEY) → JSON.parse → array of row objects keyed by SQL column names
3cBuild custom UIReplace the return statement in App.tsx with your React UI; Chakra UI components available out of the box
4aBuild the bundlenpm install + npm run build → outputs .js to dist/ folder per README instructions
4bUpload to UNIFIUpload dist/.js to the Custom Visual Data App configuration screen
4cTest in UNIFI previewVerify data renders; check SESSION_STORAGE_KEY and column names if blank
5Export and embedSame JS snippet export as other Data Apps; re-upload updated .js without changing the snippet

Request A Demo And
See It In Action

Take your marketing insights to the next level with AI-powered automation, real-time analytics, and seamless integrations.