Maquette is a minimalistic virtual DOM library designed for simplicity and performance with zero dependencies. Its tiny footprint makes it ideal for embedding UI in any environment — but a fast virtual DOM provides no protection against server downtime or silent background job failures. Vigilmon closes that gap with continuous uptime monitoring, heartbeat checks, and instant alerts routed to email or Slack.
What You'll Build
- A health endpoint for your Maquette app's backend
- Vigilmon HTTP monitors for your app and API
- A heartbeat for scheduled background tasks
- Alert channels (email and Slack)
- An uptime badge rendered via Maquette's
h()function
Prerequisites
- A Maquette project (with a Node/Express or similar backend)
- A free Vigilmon account
Step 1: Add a Health Endpoint
Maquette apps are static assets backed by a separate API. Add a /health route to your Node/Express backend:
// 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 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:
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: Maquette SPA
| Field | Value |
|---|---|
| URL | https://yourapp.com/ |
| Method | GET |
| Expected status | 200 |
| Expected body | A stable string from your HTML (e.g. 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 |
Two separate monitors catch two failure classes independently: CDN/static serving and backend data layer issues.
Step 3: Heartbeat for Background Tasks
Scheduled tasks can fail silently for days. A Vigilmon heartbeat fires an alert when the expected ping doesn't arrive within the grace window.
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 crash the job over monitoring
}
}
cron.schedule("*/5 * * * *", async () => {
try {
await syncDataFeeds();
await pingHeartbeat();
} catch (err) {
console.error("[scheduler] Data sync failed:", err);
// Vigilmon alerts after the heartbeat window expires
}
});
async function syncDataFeeds() {
// Your scheduled task logic here
}
Set up the heartbeat in Vigilmon:
- Monitors → New Heartbeat Monitor
- Set Expected interval to 10 minutes (2× the cron interval)
- Copy the ping URL into your environment:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx
Step 4: Render an Uptime Badge with Maquette
Maquette's h() hyperscript function makes it easy to embed a live status image:
// src/components/statusBadge.js
import { h } from "maquette";
const BADGE_URL = "https://vigilmon.online/api/badge/your-monitor-id.svg";
const STATUS_URL = "https://vigilmon.online/status/your-monitor-slug";
export function renderStatusBadge() {
return h("a", {
href: STATUS_URL,
target: "_blank",
rel: "noopener noreferrer",
"aria-label": "Service uptime status",
}, [
h("img", {
src: BADGE_URL,
alt: "Uptime",
width: "120",
height: "20",
}),
]);
}
Include it in your root render function:
// src/app.js
import { createProjector, h } from "maquette";
import { renderStatusBadge } from "./components/statusBadge";
const projector = createProjector();
function renderApp() {
return h("div.app", [
h("main", [
// your main content
]),
h("footer.footer", [
renderStatusBadge(),
]),
]);
}
projector.append(document.body, renderApp);
Step 5: Configure Alert Channels
In Vigilmon's Alert Channels settings:
- Alert Channels → Email → add your on-call address
- 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. Confirm the health endpoint
curl -s https://yourapp.com/health | jq .
# 2. Break the DB connection → confirm health returns 503
# Expected: Vigilmon alert within ~2 minutes
# 3. Remove VIGILMON_HEARTBEAT_URL and let the cron run
# Expected: heartbeat alert 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, external API, and service failures | | Heartbeat | Silent scheduler failures, broken background tasks |
Next Steps
- Set up separate monitors for staging vs. production
- Use Vigilmon's response time graphs to correlate latency spikes with Maquette re-render cycles or API changes
- 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.