Van.js is the simplest reactive UI framework that exists — a 1kB no-dependency library that lets you build fully reactive frontends with plain JavaScript objects, no JSX, no transpilation, no build step required. But simplicity on the client doesn't protect you from server outages, deployment failures, or background jobs that silently die at 2 a.m. Vigilmon gives you the visibility layer: continuous HTTP monitoring, heartbeat checks, and instant alerts delivered to email or Slack.
What You'll Build
- A health endpoint for your Van.js app's backend
- Vigilmon HTTP monitors for the SPA and the health API
- A heartbeat monitor for background tasks
- Alert channels (email and Slack)
- A live uptime badge rendered with Van.js reactivity
Prerequisites
- A Van.js project (can be a plain HTML file or bundled with any build tool)
- A Node.js / Express backend serving data to the frontend
- A free Vigilmon account
Step 1: Add a Health Endpoint
Van.js lives entirely in the browser; the health check belongs on your server. Add a /health route:
// 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;
}
// Third-party API reachability
try {
const resp = await fetch("https://api.example.com/ping", {
signal: AbortSignal.timeout(3000),
});
checks.externalApi = resp.ok ? "ok" : `http_${resp.status}`;
} catch {
checks.externalApi = "unreachable";
degraded = true;
}
res.status(degraded ? 503 : 200).json({
status: degraded ? "degraded" : "ok",
timestamp: new Date().toISOString(),
checks,
});
});
// Serve the Van.js SPA
app.use(express.static("public"));
app.listen(process.env.PORT ?? 3000);
Test it:
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 Vigilmon → Monitors → New Monitor:
Monitor 1: Van.js SPA
| Field | Value |
|---|---|
| URL | https://yourapp.com/ |
| Method | GET |
| Expected status | 200 |
| Expected body | A stable string from your HTML (e.g. <title>My App</title>) |
| Check interval | 1 minute |
Monitor 2: Health API
| Field | Value |
|---|---|
| URL | https://yourapp.com/health |
| Method | GET |
| Expected status | 200 |
| Check interval | 1 minute |
Separating the two monitors means a CDN outage and a database failure each trigger different alerts with accurate failure attribution.
Step 3: Heartbeat for Background Tasks
Silent scheduler failures are notoriously hard to detect. Use a Vigilmon heartbeat to catch them:
// jobs/processor.js
const HEARTBEAT_URL = process.env.VIGILMON_HEARTBEAT_URL ?? "";
async function pingHeartbeat() {
if (!HEARTBEAT_URL) return;
try {
await fetch(HEARTBEAT_URL, { signal: AbortSignal.timeout(5000) });
} catch {
// Monitoring must never crash the job itself
}
}
export async function runHourlySync() {
try {
await processQueue();
await sendDigestEmails();
await pingHeartbeat(); // Only ping on success
} catch (err) {
console.error("[processor] Sync failed:", err);
// No heartbeat ping → Vigilmon alerts after the grace window
}
}
Set it up in Vigilmon:
- Monitors → New Heartbeat Monitor
- Set Expected interval to match your schedule (e.g.
65 minutesfor an hourly job gives a small grace window) - Add the ping URL to your environment:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx
Step 4: Reactive Uptime Badge with Van.js
Van.js makes it trivial to build a live status badge that fetches JSON and reacts to state changes:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>My App</title>
<script type="module" src="https://cdn.jsdelivr.net/npm/vanjs-core@latest/src/van.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="module">
import van from "https://cdn.jsdelivr.net/npm/vanjs-core@latest/src/van.min.js";
const { div, a, img, span } = van.tags;
const BADGE_URL = "https://vigilmon.online/api/badge/your-monitor-id.svg";
const STATUS_URL = "https://vigilmon.online/status/your-monitor-slug";
function StatusBadge() {
return a(
{ href: STATUS_URL, target: "_blank", rel: "noopener noreferrer" },
img({ src: BADGE_URL, alt: "Uptime", width: 120, height: 20 })
);
}
function App() {
return div(
{ id: "root" },
// ... your app content ...
div({ class: "footer" }, StatusBadge())
);
}
van.add(document.getElementById("app"), App());
</script>
</body>
</html>
For a reactive JSON status display (no image badge):
const status = van.state("loading");
async function fetchStatus() {
try {
const res = await fetch("https://vigilmon.online/status/your-monitor-slug.json");
const data = await res.json();
status.val = data.status ?? "unknown";
} catch {
status.val = "error";
}
}
fetchStatus();
setInterval(fetchStatus, 60_000); // Refresh every minute
function StatusIndicator() {
return span(
() => ({
class: `status-dot status-${status.val}`,
title: `Service status: ${status.val}`,
}),
() => status.val
);
}
Step 5: Set Up Alert Channels
In Vigilmon's Alert Channels settings:
- Alert Channels → Email → add your on-call address
- Attach the channel to both HTTP monitors and the heartbeat
Slack
- Create a Slack Incoming Webhook for
#alerts - Alert Channels → Webhook → paste the URL
- Use this payload template:
{
"text": "🚨 *{{ monitor.name }}* is DOWN\n{{ monitor.url }}\nStatus: {{ event.status }}\n<https://vigilmon.online|Open Vigilmon>"
}
Step 6: Verify the Setup
# 1. Confirm health endpoint
curl -s https://yourapp.com/health | jq .
# 2. Force degraded state — disconnect the DB — restart the server
# Expected: /health returns 503; Vigilmon alerts within 2 minutes
# 3. Let the scheduler run without pinging the heartbeat
# Expected: alert fires after the grace window
# 4. Vigilmon → "Test Alert" button → confirm delivery to email/Slack
Summary
| Monitor | What It Catches | |---|---| | HTTP SPA check | CDN failures, broken static deployments | | HTTP health API | Database, third-party API, and backend failures | | Heartbeat | Silent job crashes, queue processing failures |
Next Steps
- Create separate monitors for staging vs. production environments
- Use Vigilmon's response time graphs to detect API latency regressions
- Configure multi-channel alerting: email for warnings, Slack for critical failures
Ready to get started? Sign up for Vigilmon free — have your first monitor running in under 5 minutes.