tutorial

How to Monitor Nanohtml with Vigilmon

Add production-grade monitoring to a Nanohtml app — health endpoints, heartbeat checks, and instant alerts when your app goes down.

Nanohtml is a tiny library for creating HTML elements using tagged template literals, with optional DOM diffing via nanomorph. It keeps your bundle small and your rendering logic plain JavaScript — no virtual DOM, no build magic. When a Nanohtml-powered UI is live, you need to know the instant it becomes unavailable. Vigilmon gives you continuous uptime monitoring, heartbeat checks, and instant alerts to email or Slack.

What You'll Build

  • A health endpoint for your Nanohtml app's backend
  • Vigilmon HTTP monitors covering your app shell and API
  • A heartbeat for scheduled background jobs
  • Alert channels (email and Slack)
  • An uptime badge rendered with Nanohtml

Prerequisites

  • A Nanohtml project (typically served by a Node/Express backend)
  • A free Vigilmon account

Step 1: Add a Health Endpoint

Nanohtml apps ship their UI as static or server-rendered HTML backed by an API. Add a /health route to your Express backend:

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

const app = express();

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

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

  // External dependency check
  try {
    const response = await fetch("https://api.example.com/ping", {
      signal: AbortSignal.timeout(3000),
    });
    checks.externalApi = response.ok ? "ok" : `http_${response.status}`;
  } catch {
    checks.externalApi = "unreachable";
    degraded = true;
  }

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

app.listen(process.env.PORT ?? 3000);

Test it locally:

curl http://localhost:3000/health | jq .
# {"status":"ok","timestamp":"2026-07-03T...","checks":{"database":"ok","externalApi":"ok"}}

Step 2: Configure Vigilmon HTTP Monitors

Log in to VigilmonMonitors → New Monitor.

Monitor 1: Nanohtml App

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

Monitor 2: Health API

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

Two monitors cover two distinct failure classes: static file serving and backend data layer failures.


Step 3: Heartbeat for Background Jobs

Apps that use Nanohtml often pair it with server-side processing — report generation, data aggregation, cache warming. Use a Vigilmon heartbeat to detect silent failures.

npm install node-cron
// scheduler.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 {
    // Never let monitoring crash the job
  }
}

cron.schedule("*/10 * * * *", async () => {
  try {
    await runAggregation();
    await pingHeartbeat();
  } catch (err) {
    console.error("[scheduler] Aggregation failed:", err);
    // Vigilmon fires after the heartbeat window expires with no ping
  }
});

async function runAggregation() {
  // Your scheduled task logic here
}

Create the heartbeat in Vigilmon:

  1. Monitors → New Heartbeat Monitor
  2. Set Expected interval to 20 minutes (2× the cron interval)
  3. Copy the ping URL into your environment:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx

Step 4: Render an Uptime Badge with Nanohtml

Nanohtml's template literal approach makes adding a badge element trivial:

// src/components/status-badge.js
import html from "nanohtml";
import morph from "nanomorph";

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

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

// Mount into your page footer
const footer = document.querySelector("footer");
if (footer) {
  footer.appendChild(StatusBadge());
}

Because Nanohtml returns real DOM nodes, you can append them directly — no diffing library required for simple cases. Use nanomorph only when you need efficient in-place updates:

// Updating an existing badge node
import morph from "nanomorph";

const badgeNode = document.getElementById("uptime-badge");
morph(badgeNode, StatusBadge());

Step 5: Configure Alert Channels

In Vigilmon's Alert Channels settings:

Email

  1. Alert Channels → Email → add your on-call address
  2. Attach to both HTTP monitors and the heartbeat

Slack

  1. Create a Slack Incoming Webhook for #alerts
  2. Alert Channels → Webhook → paste the webhook 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. Confirm the health endpoint
curl -s https://yourapp.com/health | jq .

# 2. Simulate a DB failure → confirm health returns 503
# Expected: Vigilmon alert within ~2 minutes

# 3. Remove VIGILMON_HEARTBEAT_URL and let the scheduler run
# Expected: heartbeat alert after the grace window

# 4. Vigilmon → "Test Alert" → confirm delivery to Slack/email

Summary

| Monitor | What It Catches | |---|---| | HTTP app check | CDN failures, broken static deploys | | HTTP health API | Database, external API, and service failures | | Heartbeat | Silent scheduler failures, broken background jobs |


Next Steps

  • Create separate monitors for staging and production environments
  • Use Vigilmon's response time graphs to catch latency regressions across releases
  • Route critical alerts to Slack, low-severity alerts to email

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 →