- 15 minutes to read

Custom Dashboard Items

πŸ’‘On this page, you learn how to extend the Nodinite Dashboard with your own HTML widgets and with metrics from Monitoring Agents, to show business-specific KPIs, notices, and charts next to the built-in Dashboard content.

HTML widgets on the Dashboard and in a Monitor View, animated walkthrough (7.12)
Animated walkthrough: an environment badge on the Dashboard, and an on-call widget that shows only in its own Monitor View (Extending Monitor Views).

Warning

Transitional feature: HTML widgets are a transitional feature: Nodinite 8 replaces them with a more secure extensibility solution. Keep widgets few and simple, and don't build critical functionality on them.

Important

Breaking Change in 7.4.0: HTML widgets need the DashboardPlugins feature (Custom Dashboard) in your Nodinite product key. Installations that used widgets before 7.4.0 stop showing them until the product key includes the feature. Contact Nodinite support if you have a business need for it. The feature can't be switched on locally.

Tip

Security settings (7.4.0+): The widgets run in a sandboxed iframe with a Content Security Policy. The DashboardPluginSettings system parameter has five switches for it. Only AllowScripts is on by default, so the Web Client's own scripts (Angular, for the Log View counter below) run, while inline scripts and anything from other sites are blocked.

Available Custom Dashboard Items

Nodinite offers two ways to extend the Dashboard with content of your own:

  1. HTML Widgets - Static content (environment badges, team announcements) and counters from the internal Web API
  2. Metrics Charts - Performance graphs from Monitoring Agents

For Power BI reports on Nodinite data, use the Web API reports in Power BI itself: a widget can't embed Power BI, because frames to other sites are always blocked.


HTML Widgets for Dashboard

HTML widgets appear at the top of the Dashboard, for every signed-in user. Don't put anything in a widget that only some users may read.

When to Use HTML Widgets

Good Use Cases

  • Environment identification badges - A clear visual sign of which environment users are in (Production, UAT, Development)
  • Team announcements - Team notices, change windows, or links to runbooks
  • Contact information - On-call engineer details or escalation contacts
  • Counters from the internal Web API - Counts and KPIs from Nodinite Log Views

Blocked Use Cases

With the default DashboardPluginSettings, the browser blocks:

  • ❌ Inline scripts - <script> blocks, inline event handlers (onclick), javascript: URLs, and eval()
  • ❌ Content and calls to other sites - Scripts, images, fonts, stylesheets, and API calls from outside Nodinite
  • ❌ Third-party JavaScript libraries from other sites - Use the Web Client's own libraries instead (Angular, Chart.js, moment)
  • ❌ Frames to other sites - Always blocked, whatever the settings, for example a Power BI embed

Step-by-Step: Adding Dashboard HTML Widget

Prerequisites

New 7.4.0

  • Nodinite product key with the DashboardPlugins feature (contact support to request it)
  • Write access to the Plugins folder of the Web Client site on the web server

Version 7.4.0+ Breaking Change: If widgets don't appear after upgrading to 7.4.0 or later, your product key doesn't include the DashboardPlugins feature. The feature can't be enabled locally or through configuration files.

Steps

  1. Open the Web Client folder

    On Windows Server, this is the physical path of the Web Client site in IIS Manager: the folder that holds Nodinite.WebClientCore.dll.

  2. Open the Plugins folder (create it if it doesn't exist)

    <Web Client folder>\Plugins\
    
  3. Create HTML Widget File

    • Create a file with any .html name (e.g., team-announcements.html, environment-notice.html)
    • The file name doesn't need to match anything specific
    • All .html files in the folder are shown together, in one frame. With the default settings the frame grows to fit its content.
  4. Verify Widget Appears

    • Open or reload the Dashboard, for example https://nodinite.contoso.com/. The Web Client reads the files on every request, so no restart or recycle is needed.
    • The widget appears at the top of the Dashboard page

Dashboard Widget Example (Static Content)

You can use static HTML for branding, team announcements, and environment badges. The following example shows a simple card with on-call engineer information and a link to runbooks.

<!-- File: <Web Client folder>\Plugins\team-status.html -->
<div class="card mb-4" style="border-left: 4px solid #0066cc;">
  <div class="card-header bg-light">
    <h5 class="mb-0">
      <i class="fas fa-info-circle text-primary" aria-hidden="true"></i>
      Integration Team Status
    </h5>
  </div>
  <div class="card-body">
    <p><strong>On-Call Engineer:</strong> Sarah Johnson (ext. 5432)</p>
    <p><strong>Next Maintenance Window:</strong> Saturday, March 15, 2025 - 02:00-06:00 UTC</p>
    <p>
      <a href="https://wiki.contoso.com/integration-runbooks" class="btn btn-primary btn-sm">
        <i class="fas fa-book" aria-hidden="true"></i> View Runbooks
      </a>
    </p>
  </div>
</div>

Status: Works with the default settings - Static HTML only

Environment Badge Example

<!-- File: environment-badge.html -->
<div class="alert alert-warning mb-3" role="alert" style="border-left: 4px solid #ff9800;">
  <h4 class="alert-heading">
    <i class="fas fa-flask" aria-hidden="true"></i>
    UAT Environment
  </h4>
  <p class="mb-0">
    You are viewing the <strong>User Acceptance Testing</strong> environment.
    Changes here do not affect production systems.
  </p>
</div>

Status: Works with the default settings - Static HTML only

Dynamic Log View Counter Example

Important

Breaking Change in 7.3.0: Parameter replacement syntax changed from 'eval' to 'text'. If you have existing Log View widgets from earlier versions, you must update the replace configuration as shown below.

Using any of the user-defined Log Views, the returned number of events can be rendered dynamically. Use the customJsonCountController with simple parameter replacement as exemplified below.
Events today counter widget showing 0 in red (7.12)
Example: Number of Log Events from a Nodinite Log View, drawn red at 0 events (7.12).

<!-- File: orders-today.html -->
<div class="card mb-3" ng-controller="customJsonCountController" ng-init="init('',{'title':'Events today',progressbar:true, refreshInterval:30, call:{ webapi: webApiUrl + 'api/Search/FlowSearch?logViewId=17&searchJson=%7B%22FilterGroups%22%3A%5B%5D,%22NumberOfItems%22%3A0,%22Page%22%3A1,%22From%22%3A%22$from$%22,%22To%22%3A%22$to$%22,%22DataSource%22%3A%7B%7D%7D',jsonPath:'Collection.Pagination.TotalNumberOfItemsAvailable','replace':[{'find':'$from$', 'text': encodeURIComponent(moment().startOf('day').format(variables.dateTimeFormat))},{'find':'$to$', 'text': encodeURIComponent(moment().endOf('day').format(variables.dateTimeFormat))}]}})">
    <div ng-show="gui.loading" class="card-header"><span><i class="fa fa-spinner fa-spin"></i> Loading...</span></div>
    <div ng-show="!gui.loading" class="card-header ng-hide"><i ng-if="gui.titleIcon" class="fa" ng-class="gui.titleIcon"></i> <span class="ng-hide" ng-show="gui.title">{{gui.title}}</span></div>
    <div class="card-body p-1">
        <div style="font-size:100px; text-align:center;" ng-style="{'color':gui.count == 0?'#FF3F2C':'#3d9970'}">
            <div class="ng-hide" ng-show="!gui.loading">{{gui.count}}</div>
            <div ng-show="gui.loading">&nbsp;</div>
        </div>
        <div style="font-size:8px; padding-right:4px;" class="text-gray pull-right ng-hide" ng-show="!gui.loading">Last updated: {{gui.lastupdated}}</div>
        <div class="clearfix"></div>
        <div class="widget-progressbar">
            <div ng-if="gui.progressbar.enabled" ng-class="{'notransition':gui.progressbar.value==0}" class="progress" ng-style="{'width':gui.progressbar.value + '%'}"></div>
        </div>
        <div class="clearfix"></div>
    </div>
</div>

Configuration:

  • Replace logViewId=17 with the ID of your Log View (17 in this example)
  • The widget automatically refreshes every 30 seconds (refreshInterval:30)
  • Set a title ('title':'Events today')
  • Colors change based on count: Red (#FF3F2C) for 0 events, Green (#3d9970) for >0
  • Date range is dynamically set to "today" using $from$ and $to$ parameter replacement
  • The text value is an expression without quotes around it: Angular evaluates it, with encodeURIComponent, moment, and variables available

Migration from pre-7.3.0 versions:

If you have existing widgets using the old 'eval' syntax, update your replace configuration:

// ❌ Old syntax (pre-7.3.0) - Blocked: the Content Security Policy forbids eval
'replace':[
  {'find':'$from$', 'eval':'encodeURIComponent(moment().startOf(\'day\').format(variables.dateTimeFormat))'},
  {'find':'$to$', 'eval':'encodeURIComponent(moment().endOf(\'day\').format(variables.dateTimeFormat))'}
]

// βœ… New syntax (7.3.0+) - The expression without quotes
'replace':[
  {'find':'$from$', 'text': encodeURIComponent(moment().startOf('day').format(variables.dateTimeFormat))},
  {'find':'$to$', 'text': encodeURIComponent(moment().endOf('day').format(variables.dateTimeFormat))}
]

Key changes:

  1. Replace 'eval' with 'text'
  2. Remove the quotes around the expression, so '...' becomes the expression itself and \'day\' becomes 'day'

Status: Works with the default settings - Needs AllowScripts, which is on by default

Accessibility Notes

  • Use semantic HTML: <h2>, <h3>, <p>, <ul>, <a>
  • Add ARIA attributes: aria-label, aria-hidden="true" on decorative icons
  • Ensure color contrast meets WCAG AA (4.5:1 for normal text)
  • Provide text alternatives: Don't rely on color alone for meaning

Metrics Charts from Monitoring Agents

Using Metrics from any of the supported Monitoring Agents an Administrator can add, and organize information on the Dashboard.

Available Metrics Sources

Adding Metrics to Dashboard

Follow these steps to add Metrics graphs to the Dashboard (you need write access to the Web Client folder on the web server):

  1. Create an HTML file in the Plugins folder of the Web Client (<Web Client folder>\Plugins\)

  2. Copy the HTML content from the Metrics modal (Resource in Monitor View where Actions are allowed and Metrics are available)
    Metrics HTML example
    Example: Copy metrics HTML code from a resource's metrics modal.

  3. Reload Dashboard page

Metrics Template

The following template may be used to create a single framed box hosting 4 metrics graphs in a 2Γ—2 table. Replace the card-header with your appropriate title and replace the comments with the code to embed from metrics enabled resources.

<div class="row">
  <div class="col-12 col-md-6 mb-3">
    <div class="card">
      <div class="card-header">Server Performance - Production SQL01</div>
      <div class="card-body p-2">
        <div class="row">
          <!-- Replace with CPU metrics embed code -->
          <!-- Replace with Memory metrics embed code -->
        </div>
        <div class="row">
          <!-- Replace with Disk metrics embed code -->
          <!-- Replace with Network metrics embed code -->
        </div>
      </div>
    </div>
  </div>
</div>

Available Libraries and Styling

The widget frame loads the Web Client's own stylesheets: Bootstrap 4.6.2 and Font Awesome Pro 7.3.0. Use Bootstrap 4 classes, for example font-weight-bold (not the Bootstrap 5 fw-bold), and Font Awesome icons such as fas fa-info-circle. See Extending Monitor Views for a list of useful classes.

Best Practices

Do's

  • Keep content simple - HTML markup and the Web Client's CSS classes (Bootstrap, Font Awesome)
  • Include ARIA attributes - aria-label, aria-hidden, role="alert" for accessibility
  • Use semantic HTML - Proper heading hierarchy (<h2>, <h3>), lists, paragraphs
  • Use descriptive file names - team-announcements.html not widget1.html
  • Minimize widget usage - Only create widgets when built-in features cannot meet your needs
  • Plan for migration - Nodinite 8 replaces HTML widgets
  • Responsive design - Use Bootstrap grid classes (col-md-6, mb-3) for proper layout
  • Test accessibility - Verify color contrast (4.5:1 minimum), screen reader compatibility

Don'ts

  • Don't write inline scripts - <script> blocks, inline event handlers (onclick), and javascript: URLs are blocked by default
  • Don't load content from other sites - Scripts, stylesheets, images, and fonts from CDNs are blocked by default
  • Never embed credentials - Don't include API keys, passwords, or connection strings
  • Don't put restricted information in a widget - Every signed-in user sees the Dashboard widgets
  • Don't embed other sites in an iframe - Frames to other sites are always blocked
  • Don't rely on color alone - Use icons + text for status indicators (WCAG AA)
  • Keep widgets simple - Complex functionality is better suited for built-in features

Troubleshooting

Widget Not Appearing

Problem

Widget HTML file created but not visible on Dashboard.

Solutions

New 7.4.0

  1. Verify the Product Key Includes the DashboardPlugins Feature (7.4.0+)

    • HTML widgets need the DashboardPlugins feature in your Nodinite product key
    • Contact Nodinite support to request the feature
    • Check the product key in Administration β†’ Settings β†’ Manage License
    • Security by design: This feature can't be enabled locally or through configuration files
  2. Check File Location

    • Dashboard widgets: <Web Client folder>\Plugins\*.html
    • File must have .html extension
    • Ensure file is directly in Plugins\ folder, not in a subfolder
  3. Verify File Permissions

    • The IIS application pool identity must have Read access to the file
    • Right-click file β†’ Properties β†’ Security β†’ Verify IIS AppPool\[PoolName] has Read access
  4. Check Browser Cache

    • Hard refresh: Ctrl+F5 (Windows), Cmd+Shift+R (Mac)
    • Clear browser cache and reload

Counter Shows No Number

Problem

A Log View counter shows its title, but the count stays empty or on Loading....

Solution

  1. Check the syntax - Write each 'text' value without quotes around the expression (see Dynamic Log View Counter Example). With quotes, the browser console shows an AngularJS $parse:syntax error.
  2. Check the Log View - Press F12 and read the answer of the FlowSearch call. The Log View in logViewId must accept a From and To time from the caller; otherwise it answers 400 Bad Request. Missing time interval.

Styling Conflicts

Problem

Widget styling clashes with Nodinite built-in styles.

Solution

  1. Use Bootstrap Classes

    • Leverage existing classes: mb-3, text-center, alert-info
    • Consistent styling with Nodinite UI
  2. Avoid Global CSS Resets

    • Don't use * { margin: 0; } or body { font-family: ... }
    • These override Nodinite styles
  3. Scope CSS to Widget

    • Use specific class names: .my-widget-container { ... }
    • Avoid generic selectors that affect entire page

JavaScript Doesn't Run in a Widget

Problem

The widget HTML shows, but its JavaScript doesn't run.

Solution

  1. Check the switches - AllowScripts must be true in the DashboardPluginSettings system parameter (the default). Scripts written in the widget itself also need AllowInlineScripts, and scripts from a CDN need AllowExternalScripts. Check that the JSON value is valid.
  2. Check the browser console - Press F12 and look for Content Security Policy or sandbox errors from the widget iframe

Content or Calls to Other Sites Are Blocked

Problem

Images, fonts, or calls to an API outside Nodinite fail, or an embedded page stays empty.

Solution

  1. Images, fonts, and stylesheets - Set AllowExternalContent to true in DashboardPluginSettings
  2. API calls - Set AllowExternalCalls to true. The external API must also send CORS headers that allow your Nodinite Web Client site, over HTTPS.
  3. Iframes - A frame to another site can't load in a widget, whatever the settings

Security Considerations

New 7.4.0

Security Model (Version 7.4.0+)

As of version 7.4.0, Nodinite has these security controls for HTML widgets:

  1. Product key - Widgets need the DashboardPlugins feature in the product key. It can't be enabled locally.
  2. Sandboxed iframe with a Content Security Policy - The widget HTML isn't rewritten. It is shown, as it is, in a sandboxed frame, and the browser blocks what the policy forbids: inline scripts, eval(), javascript: URLs, <object>, and content, calls, and frames to other sites.
  3. File system access control - Only administrators with access to the Web Client folder can deploy widget files.
  4. Settings - The DashboardPluginSettings system parameter opens parts of the policy. Only AllowScripts is on by default.
  5. Read-only API access - Calls from a widget to the Web API run with a reduced, read-only set of the user's permissions, so a widget can't change data.

Security Best Practices

  1. Restrict file system access - Only allow trusted administrators to add widget files
  2. Code review all widgets - Manually inspect HTML files before deployment
  3. Audit logging - Monitor widget file changes via file system auditing
  4. Minimize usage - Remove unnecessary widgets to reduce attack surface
  5. Never use untrusted sources - Do not copy widget code from forums, blogs, or community templates
  6. Request the feature only when needed - Ask for DashboardPlugins in the product key only for a business need (7.4.0+)
  7. Use internal APIs - Calls to sites outside Nodinite are blocked unless you open them
  8. Review DashboardPluginSettings - Start with the default, and open only what a widget needs

Before You Create a Custom Widget

  1. Evaluate alternatives - Review built-in Dashboard features, Stylesheets, and Display Field Configurations first
  2. Understand the sandbox - Inline scripts and content from other sites are blocked by default; frames to other sites always are
  3. Request the product key feature - Contact support to add DashboardPlugins to your license
  4. Use internal APIs - Dynamic widgets can call Nodinite Web API endpoints
  5. Test thoroughly - Verify accessibility, responsiveness, and appearance

Use widgets for static content, team announcements, and internal API counters. For analytics, use Power BI on the Web API outside the Dashboard.

Next Steps