Snabbdom is a fast, modular virtual DOM library built around simplicity and performance — a lean patch function, composable modules, and no unnecessary abstractions. But a 1 ms patch cycle is cold comfort when your backend is down or your scheduled sync silently stopped running. Vigilmon gives you the observability layer that keeps production honest: continuous HTTP monitoring, heartbeat checks, and instant alerts via email or Slack.
What You'll Build
- A health API endpoint for your Snabbdom app's backend (Node/Express)
- Vigilmon HTTP monitors for your SPA and backend health route
- A heartbeat for scheduled background tasks
- Alert channels (email and Slack)
- An uptime badge patched into your Snabbdom virtual DOM
Prerequisites
- A Snabbdom project (bundled with Rollup, Vite, or webpack)
- A Node.js backend to host your health endpoint
- A free Vigilmon account
Step 1: Add a Health Endpoint
Snabbdom runs in the browser. Add a health endpoint to the server that hosts or backs your app:
// 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.execute("SELECT 1");
checks.database = "ok";
} catch (err) {
checks.database = `error: ${err.message}`;
degraded = true;
}
// Cache check
try {
// await redisClient.ping();
checks.cache = "ok";
} catch (err) {
checks.cache = `error: ${err.message}`;
degraded = true;
}
// External API check
try {
const resp = await fetch("https://api.stripe.com/v1/", {
signal: AbortSignal.timeout(3000),
});
checks.stripe = resp.status < 500 ? "ok" : `http_${resp.status}`;
} catch {
checks.stripe = "unreachable";
degraded = true;
}
res.status(degraded ? 503 : 200).json({
status: degraded ? "degraded" : "ok",
timestamp: new Date().toISOString(),
checks,
});
});
// Serve Snabbdom SPA
app.use(express.static("dist"));
app.listen(process.env.PORT ?? 3000);
Test it:
curl http://localhost:3000/health | jq .
# {"status":"ok","timestamp":"2026-06-29T...","checks":{"database":"ok","cache":"ok","stripe":"ok"}}
Step 2: Configure Vigilmon HTTP Monitors
Log in to Vigilmon → Monitors → New Monitor:
Monitor 1: Snabbdom SPA
| Field | Value |
|---|---|
| URL | https://yourapp.com/ |
| Method | GET |
| Expected status | 200 |
| Expected body | A stable string from your HTML (e.g. the root mount element id) |
| 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 independent failure classes: static hosting and backend data.
Step 3: Heartbeat for Background Tasks
Background jobs — data fetching, cache warming, webhook delivery — can crash silently for hours without user-visible impact, right up until the moment they cause one. A Vigilmon heartbeat fires an alert when the expected ping stops arriving.
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 {
// Monitoring must never crash the job
}
}
cron.schedule("*/5 * * * *", async () => {
try {
await warmCache();
await pingHeartbeat();
} catch (err) {
console.error("[scheduler] Cache warm failed:", err);
// No ping → Vigilmon alerts after the grace window expires
}
});
async function warmCache() {
// Your actual cache warming logic
}
Set up the heartbeat in Vigilmon:
- Monitors → New Heartbeat Monitor
- Set Expected interval to 10 minutes (2× the cron interval)
- Copy the ping URL to your
.env:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx
Step 4: Display Uptime Status in Your Snabbdom Virtual DOM
Snabbdom's h function and module system make it easy to patch a live status badge into your vdom tree:
// src/components/status-badge.js
import { h } from "snabbdom";
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(loaded, onLoad) {
return h(
"a",
{
attrs: {
href: STATUS_URL,
target: "_blank",
rel: "noopener noreferrer",
"aria-label": "Service uptime status",
},
style: { display: "inline-flex", alignItems: "center" },
},
[
h("img", {
attrs: {
src: BADGE_URL,
alt: "Uptime",
width: "120",
height: "20",
},
style: {
opacity: loaded ? "1" : "0",
transition: "opacity 0.2s",
},
on: { load: onLoad },
}),
]
);
}
Patch it into your app:
// src/app.js
import { init, h } from "snabbdom";
import { classModule } from "snabbdom/modules/class";
import { styleModule } from "snabbdom/modules/style";
import { attributesModule } from "snabbdom/modules/attributes";
import { eventListenersModule } from "snabbdom/modules/eventlisteners";
import { statusBadge } from "./components/status-badge.js";
const patch = init([classModule, styleModule, attributesModule, eventListenersModule]);
let badgeLoaded = false;
function render() {
return h("div", null, [
h("main", null, [/* your app content */]),
h("footer", null, [
statusBadge(badgeLoaded, () => {
badgeLoaded = true;
vnode = patch(vnode, render());
}),
]),
]);
}
const container = document.getElementById("app");
let vnode = patch(container, render());
Step 5: Set Up Alert Channels
In Vigilmon's Alert Channels settings:
- Alert Channels → Email → add your on-call email
- Attach to both HTTP monitors and the heartbeat
Slack
- Create a Slack Incoming Webhook for
#alerts - Alert Channels → Webhook → paste the URL
- 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 endpoint
curl -s https://yourapp.com/health | jq .
# 2. Break the DB connection string → confirm health returns 503
# Expected: Vigilmon alerts within 2 minutes
# 3. Unset VIGILMON_HEARTBEAT_URL → let the scheduler run
# Expected: heartbeat alert fires after the grace window
# 4. Vigilmon → "Test Alert" → confirm delivery to Slack/email
Summary
| Monitor | What It Catches | |---|---| | HTTP SPA check | CDN failures, broken static deploys | | HTTP health API | Database, cache, and third-party API failures | | Heartbeat | Scheduler crashes, silent background job failures |
Next Steps
- Create separate monitors for staging vs. production
- Use Vigilmon's response time graphs to detect latency spikes correlated with Snabbdom patch cycles or data fetches
- Configure multi-channel alerting: email for low-severity, Slack for critical
Ready to get started? Sign up for Vigilmon free — have your first monitor running in under 5 minutes.