Reef.js lets you build reactive, state-driven UI components without a framework, build step, or virtual DOM — just a tiny library you drop in. But no framework overhead still doesn't protect you from server outages, broken APIs, or silently failing background jobs. Vigilmon gives you the production observability your Reef.js app needs: continuous HTTP monitoring, heartbeat checks, and instant alerts routed to email or Slack.
What You'll Build
- A health API endpoint for your Reef.js application backend
- Vigilmon HTTP monitors for your Reef.js SPA and backend API
- A heartbeat for scheduled background tasks
- Alert channels (email and Slack)
- An uptime badge rendered as a Reef.js component
Prerequisites
- A Reef.js project (using
reefjsor the CDN build) - Node.js backend for the health endpoint
- A free Vigilmon account
Step 1: Add a Health Endpoint
Reef.js handles your client-side state; your backend provides data and serves your app. Add a /health route:
// server.js (Express)
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;
}
// External API check
try {
const response = await fetch("https://api.example.com/ping", {
signal: AbortSignal.timeout(3000),
});
checks.external_api = response.ok ? "ok" : `http_${response.status}`;
} catch (err) {
checks.external_api = "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","external_api":"ok"}}
Step 2: Configure Vigilmon HTTP Monitors
Log in to Vigilmon → Monitors → New Monitor:
Monitor 1: Reef.js SPA (frontend)
| Field | Value |
|---|---|
| URL | https://yourapp.com/ |
| Method | GET |
| Expected status | 200 |
| Expected body | A stable string from your HTML (e.g. <div id="app">) |
| Check interval | 1 minute |
Monitor 2: Backend Health API
| Field | Value |
|---|---|
| URL | https://yourapp.com/health |
| Method | GET |
| Expected status | 200 |
| Check interval | 1 minute |
Covering both monitors lets you distinguish CDN/static serving failures from backend data layer failures.
Step 3: Heartbeat for Background Tasks
Reef.js apps are often backed by lightweight backends running scheduled tasks — data polling, cache warming, notification queues. These fail silently without a heartbeat check.
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 pollExternalData();
await pingHeartbeat();
} catch (err) {
console.error("[scheduler] Data poll failed:", err);
// Vigilmon alerts after the heartbeat window expires with no ping
}
});
async function pollExternalData() {
// Fetch and cache data that Reef.js components will consume
}
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 as a Reef.js Component
Reef.js makes it easy to build a reactive status badge component that re-renders when state changes:
// src/status-badge.js
import Reef from "reefjs";
const BADGE_URL = "https://vigilmon.online/api/badge/your-monitor-id.svg";
const STATUS_URL = "https://vigilmon.online/status/your-monitor-slug";
const badgeStore = new Reef.Store({
data: { loaded: false },
});
const statusBadge = new Reef("#vigilmon-badge", {
store: badgeStore,
template(props) {
return `
<a
href="${STATUS_URL}"
target="_blank"
rel="noopener noreferrer"
aria-label="Service uptime status"
style="display:inline-flex;align-items:center"
>
<img
src="${BADGE_URL}"
alt="Uptime"
width="120"
height="20"
style="opacity:${props.loaded ? 1 : 0};transition:opacity 0.2s"
/>
</a>
`;
},
});
document.addEventListener("reef:render", (event) => {
if (!event.target.closest("#vigilmon-badge")) return;
const img = event.target.querySelector("img");
if (img) {
img.addEventListener("load", () => {
badgeStore.data.loaded = true;
}, { once: true });
}
});
Add the mount point to your HTML:
<!-- index.html -->
<footer>
<div id="vigilmon-badge"></div>
</footer>
<script type="module" src="/src/status-badge.js"></script>
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. Remove VIGILMON_HEARTBEAT_URL → let the scheduler run without pinging
# 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 data poll failures |
Next Steps
- Create separate monitors for staging vs. production
- Use Vigilmon's response time graphs to spot API latency spikes that affect Reef.js data loading
- 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.