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.

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
AllowScriptsis 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:
- HTML Widgets - Static content (environment badges, team announcements) and counters from the internal Web API
- 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, andeval() - β 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
Pluginsfolder 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
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.Open the Plugins folder (create it if it doesn't exist)
<Web Client folder>\Plugins\Create HTML Widget File
- Create a file with any
.htmlname (e.g.,team-announcements.html,environment-notice.html) - The file name doesn't need to match anything specific
- All
.htmlfiles in the folder are shown together, in one frame. With the default settings the frame grows to fit its content.
- Create a file with any
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
- Open or reload the Dashboard, for example
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 thereplaceconfiguration 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.

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"> </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=17with 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
textvalue is an expression without quotes around it: Angular evaluates it, withencodeURIComponent,moment, andvariablesavailable
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:
- Replace
'eval'with'text' - 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
Windows Server Monitoring Agent
- CPU (and individual cores)
- Memory
- Disk
- Network
- IIS Performance Counters
BizTalk Server Monitoring Agent
- Throttling in BizTalk (global and individual hosts)
- Spool table(s)
- TrackingData table(s)
- Group information (aggregated current state)
-
- Response-time for Web Services
-
- Logon hours statistics
- Logon history (last logon)
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):
Create an HTML file in the
Pluginsfolder of the Web Client (<Web Client folder>\Plugins\)Copy the HTML content from the Metrics modal (Resource in Monitor View where Actions are allowed and Metrics are available)

Example: Copy metrics HTML code from a resource's metrics modal.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.htmlnotwidget1.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), andjavascript: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
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
Check File Location
- Dashboard widgets:
<Web Client folder>\Plugins\*.html - File must have
.htmlextension - Ensure file is directly in
Plugins\folder, not in a subfolder
- Dashboard widgets:
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
Check Browser Cache
- Hard refresh:
Ctrl+F5(Windows),Cmd+Shift+R(Mac) - Clear browser cache and reload
- Hard refresh:
Counter Shows No Number
Problem
A Log View counter shows its title, but the count stays empty or on Loading....
Solution
- 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:syntaxerror. - Check the Log View - Press
F12and read the answer of theFlowSearchcall. The Log View inlogViewIdmust 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
Use Bootstrap Classes
- Leverage existing classes:
mb-3,text-center,alert-info - Consistent styling with Nodinite UI
- Leverage existing classes:
Avoid Global CSS Resets
- Don't use
* { margin: 0; }orbody { font-family: ... } - These override Nodinite styles
- Don't use
Scope CSS to Widget
- Use specific class names:
.my-widget-container { ... } - Avoid generic selectors that affect entire page
- Use specific class names:
JavaScript Doesn't Run in a Widget
Problem
The widget HTML shows, but its JavaScript doesn't run.
Solution
- Check the switches -
AllowScriptsmust betruein the DashboardPluginSettings system parameter (the default). Scripts written in the widget itself also needAllowInlineScripts, and scripts from a CDN needAllowExternalScripts. Check that the JSON value is valid. - Check the browser console - Press
F12and 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
- Images, fonts, and stylesheets - Set
AllowExternalContenttotruein DashboardPluginSettings - API calls - Set
AllowExternalCallstotrue. The external API must also send CORS headers that allow your Nodinite Web Client site, over HTTPS. - 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:
- Product key - Widgets need the DashboardPlugins feature in the product key. It can't be enabled locally.
- 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. - File system access control - Only administrators with access to the Web Client folder can deploy widget files.
- Settings - The DashboardPluginSettings system parameter opens parts of the policy. Only
AllowScriptsis on by default. - 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
- Restrict file system access - Only allow trusted administrators to add widget files
- Code review all widgets - Manually inspect HTML files before deployment
- Audit logging - Monitor widget file changes via file system auditing
- Minimize usage - Remove unnecessary widgets to reduce attack surface
- Never use untrusted sources - Do not copy widget code from forums, blogs, or community templates
- Request the feature only when needed - Ask for DashboardPlugins in the product key only for a business need (7.4.0+)
- Use internal APIs - Calls to sites outside Nodinite are blocked unless you open them
- Review DashboardPluginSettings - Start with the default, and open only what a widget needs
Before You Create a Custom Widget
- Evaluate alternatives - Review built-in Dashboard features, Stylesheets, and Display Field Configurations first
- Understand the sandbox - Inline scripts and content from other sites are blocked by default; frames to other sites always are
- Request the product key feature - Contact support to add DashboardPlugins to your license
- Use internal APIs - Dynamic widgets can call Nodinite Web API endpoints
- 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
- DashboardPluginSettings - Set what widgets may do in their sandbox
- Dashboard Overview - Main Dashboard features and capabilities
Related Topics
- LogEventsPerDayThresholds - Warning and error levels for the built-in Log Events per day chart
- Extending Monitor Views - Add custom widgets to specific Monitor Views
- Stylesheets - Apply custom CSS to log messages and alerts
- Display Field Configurations - Customize column visibility in Log and Monitor Views
- Web API - REST API for custom integrations
- Reports - Power BI reports on Nodinite data
- HTTP Security Headers - The Web Client's Content Security Policy