tutorial

How to Monitor Uhtml with Vigilmon

Set up uptime monitoring, heartbeat checks, and instant alerting for your uhtml-powered web application with Vigilmon — catch outages before your users do.

Uhtml is a micro-sized alternative to lighterhtml — the same template-literal-based UI rendering in a fraction of the bytes. It's perfect for lightweight web apps that need fast, reactive rendering without framework overhead. But small bundle size doesn't mean immunity from downtime. Vigilmon provides continuous HTTP monitoring, heartbeat checks, and alert delivery so you catch failures the moment they occur rather than when users start complaining.

What You'll Build

  • A /health endpoint for your uhtml Node.js backend
  • Vigilmon HTTP monitors for your app and API
  • A heartbeat monitor for background tasks
  • Alert channels (email and Slack)
  • An uptime badge in your uhtml UI

Prerequisites

  • A Node.js project using uhtml (with Express or a plain HTTP server)
  • A free Vigilmon account

Step 1: Add a Health Endpoint

Uhtml handles client-side rendering; your backend needs an HTTP health endpoint that Vigilmon can probe:

// server.js
import express from "express";

const app = express();

app.get("/health", async (req, res) => {
  const checks = {};
  let degraded = false;

  // Database check
  try {
    // await db.query("SELECT 1");
    checks.database = "ok";
  } catch (err) {
    checks.database = `error: ${err.message}`;
    degraded = true;
  }

  // Cache check (e.g. Redis)
  try {
    // await redisClient.ping();
    checks.cache = "ok";
  } catch (err) {
    checks.cache = `error: ${err.message}`;
    degraded = true;
  }

  res.status(degraded ? 503 : 200).json({
    status: degraded ? "degraded" : "ok",
    timestamp: new Date().toISOString(),
    checks,
  });
});

app.use(express.static("public"));
app.listen(process.env.PORT ?? 3000);

Test locally:

curl http://localhost:3000/health | jq .
# {"status":"ok","timestamp":"2026-06-29T...","checks":{"database":"ok","cache":"ok"}}

Step 2: Configure Vigilmon HTTP Monitors

Log in to VigilmonMonitors → New Monitor:

Monitor 1: Uhtml App (Frontend)

| Field | Value | |---|---| | URL | https://yourapp.com/ | | Method | GET | | Expected status | 200 | | Expected body | A stable string from your HTML shell | | Check interval | 1 minute |

Monitor 2: Health API

| Field | Value | |---|---| | URL | https://yourapp.com/health | | Method | GET | | Expected status | 200 | | Expected body | "status":"ok" | | Check interval | 1 minute |

Two independent monitors mean a CDN misconfiguration (frontend down, API up) is distinct from a database failure (API down, frontend still served).


Step 3: Heartbeat for Background Tasks

Uhtml apps that fetch remote data often have background processes — polling APIs, refreshing tokens, syncing state. A Vigilmon heartbeat monitor detects when these jobs stop running silently:

// background.js
import cron from "node-cron";

const VIGILMON_HEARTBEAT_URL = process.env.VIGILMON_HEARTBEAT_URL ?? "";

async function pingHeartbeat() {
  if (!VIGILMON_HEARTBEAT_URL) return;
  try {
    await fetch(VIGILMON_HEARTBEAT_URL, { signal: AbortSignal.timeout(5000) });
  } catch {
    // Heartbeat errors must never crash the background job
  }
}

// Run every 15 minutes
cron.schedule("*/15 * * * *", async () => {
  try {
    await syncRemoteData();
    await pingHeartbeat();
  } catch (err) {
    console.error("[background] Data sync failed:", err);
    // No ping → Vigilmon alerts after the grace window
  }
});

async function syncRemoteData() {
  // Fetch and cache data your uhtml UI consumes
}

Set up the heartbeat in Vigilmon:

  1. Monitors → New Heartbeat Monitor
  2. Set Expected interval to 30 minutes
  3. Add to your environment:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx

Step 4: Embed an Uptime Badge in Your Uhtml UI

Uhtml's tagged template literals make it easy to include a live status badge in your rendered output:

// app.js (client-side with uhtml)
import { html, render } from "uhtml";

const BADGE_URL = "https://vigilmon.online/api/badge/your-monitor-id.svg";
const STATUS_URL = "https://vigilmon.online/status/your-monitor-slug";

function Footer() {
  return html`
    <footer class="footer">
      <a
        href="${STATUS_URL}"
        target="_blank"
        rel="noopener noreferrer"
        aria-label="Service uptime"
      >
        <img src="${BADGE_URL}" alt="Uptime" width="120" height="20" />
      </a>
    </footer>
  `;
}

function App(data) {
  return html`
    <div>
      <main>${renderMain(data)}</main>
      ${Footer()}
    </div>
  `;
}

render(document.getElementById("app"), () => App(appData));

Because uhtml only re-renders the parts of the DOM that change, the badge sits in the footer without interfering with your reactive state updates.


Step 5: Set Up Alert Channels

In Vigilmon's Alert Channels settings:

Email

  1. Alert Channels → Email → add your on-call address
  2. Attach to all monitors

Slack

  1. Create a Slack Incoming Webhook for #alerts
  2. Alert Channels → Webhook → paste the URL
  3. Payload template:
{
  "text": "🚨 *{{ monitor.name }}* is DOWN\n{{ monitor.url }}\nStatus: {{ event.status }}\n<https://vigilmon.online|Open Vigilmon>"
}

Step 6: Verify Everything Works

# 1. Health check
curl -s https://yourapp.com/health | jq .status

# 2. Simulate degraded state — remove DB credentials and redeploy
# Expected: 503 returned; Vigilmon alert fires within ~2 minutes

# 3. Remove the heartbeat URL and let the scheduler run one cycle
# Expected: heartbeat alert fires after the expected interval elapses

# 4. Vigilmon → "Test Alert" to verify email and Slack delivery

Summary

| Monitor | What It Catches | |---|---| | HTTP app check | Static file serving failures, CDN outages | | HTTP health API | Database, cache, and external dependency failures | | Heartbeat | Silent background job crashes |


Next Steps

  • Create separate Vigilmon projects for staging and production
  • Use Vigilmon's response time graphs to detect performance regressions when your data payloads grow
  • Configure multi-channel alerting with different severity thresholds

Ready to get started? Sign up for Vigilmon free — have your first monitor running in under 5 minutes.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →