tutorial

How to Monitor Yo-yo with Vigilmon

Add production-grade uptime monitoring, health checks, and heartbeat alerts to applications built with Yo-yo — the modular UI library built on bel and morphdom.

Yo-yo is a modular UI library built on bel and morphdom that lets you build reactive, functional view components using template literals and efficient DOM diffing. It embraces a simple mental model: pure functions that return DOM nodes, patched in place when state changes. But simplicity in the UI layer doesn't make your app immune to production failures — your server can go down, your background workers can stall, and your CDN can serve stale or broken assets without anyone noticing. Vigilmon gives you the visibility to catch those failures fast. This tutorial shows you how.

What You'll Build

  • A health endpoint for the server powering your Yo-yo app
  • Vigilmon HTTP monitors for your app URL and health API
  • A heartbeat for background tasks that feed your Yo-yo views
  • Email and Slack alerts when something goes wrong
  • A status badge embedded in your rendered UI

Prerequisites

  • A Node.js/browser app using Yo-yo for UI rendering
  • A free Vigilmon account

Step 1: Add a Health Endpoint

Yo-yo apps are typically served from a Node.js backend. Add a /health route so Vigilmon can probe your app's liveness:

npm install express
// health-server.js
import express from "express";

const app = express();
const PORT = process.env.HEALTH_PORT ?? 3001;

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

  // Check your API or data source
  try {
    const response = await fetch(process.env.API_BASE_URL + "/ping", {
      signal: AbortSignal.timeout(3000),
    });
    checks.api = response.ok ? "ok" : `http_${response.status}`;
    if (!response.ok) degraded = true;
  } catch (err) {
    checks.api = `error: ${err.message}`;
    degraded = true;
  }

  // Check any third-party service your views depend on
  try {
    const res = await fetch(process.env.THIRD_PARTY_URL, {
      signal: AbortSignal.timeout(3000),
    });
    checks.thirdParty = res.status < 500 ? "ok" : `http_${res.status}`;
  } catch {
    checks.thirdParty = "unreachable";
  }

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

app.listen(PORT, () => {
  console.log(`[health] Listening on :${PORT}`);
});

Test it:

curl http://localhost:3001/health | jq .
# {"status":"ok","timestamp":"2026-07-03T...","checks":{"api":"ok","thirdParty":"ok"}}

Step 2: Set Up Vigilmon HTTP Monitors

Log in to Vigilmon and create two monitors.

Monitor 1: Yo-yo App URL

| Field | Value | |---|---| | URL | https://yourapp.com/ | | Method | GET | | Expected status | 200 | | Expected body | A stable string from your page (e.g. your app's <title>) | | Check interval | 1 minute |

This catches server crashes, broken builds, and CDN misconfigurations that prevent your Yo-yo UI from loading at all.

Monitor 2: Health API

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


Step 3: Heartbeat for Background Workers

Yo-yo views often consume data from background processes — WebSocket servers, polling loops, or server-sent event emitters. If these workers stall, your UI freezes silently. Wire them to a Vigilmon heartbeat:

npm install node-cron
// worker.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 a monitoring ping crash the worker
  }
}

async function fetchAndBroadcast() {
  console.log("[worker] Fetching latest data...");
  // Fetch data and push to connected Yo-yo clients
  console.log("[worker] Broadcast complete");
}

cron.schedule("* * * * *", async () => {
  try {
    await fetchAndBroadcast();
    await pingHeartbeat(); // Ping only after successful execution
  } catch (err) {
    console.error("[worker] Failed:", err);
    // Vigilmon will alert when the heartbeat window expires
  }
});

In Vigilmon:

  1. Monitors → New Heartbeat Monitor
  2. Set the expected interval to 5 minutes (2× the cron period as a grace window)
  3. Copy the ping URL to your .env:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx

Step 4: Embed a Status Badge in Your Yo-yo View

Yo-yo components are just functions that return DOM nodes. Add a status badge component:

// components/status-badge.js
const yo = require("yo-yo");

function statusBadge() {
  const BADGE_URL = "https://vigilmon.online/api/badge/your-monitor-id.svg";
  const MONITOR_URL = "https://vigilmon.online/status/your-monitor-slug";

  return yo`
    <a href="${MONITOR_URL}" target="_blank" rel="noopener noreferrer">
      <img
        src="${BADGE_URL}"
        alt="Uptime status"
        width="120"
        height="20"
      />
    </a>
  `;
}

module.exports = statusBadge;

Use it in your main app component:

// app.js
const yo = require("yo-yo");
const statusBadge = require("./components/status-badge");

function render(state) {
  return yo`
    <div id="app">
      <main>
        <h1>${state.title}</h1>
        <!-- Your app content -->
      </main>
      <footer>
        ${statusBadge()}
      </footer>
    </div>
  `;
}

Step 5: Configure Alert Channels

In Vigilmon's Alert Channels settings:

Email Alerts

  1. Alert Channels → Email → enter your ops email
  2. Attach to both HTTP monitors and the heartbeat monitor

Slack Webhook

  1. Create a Slack Incoming Webhook for #ops-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: Test End-to-End

# 1. Verify the health endpoint
curl -s https://yourapp.com/health | jq .

# 2. Simulate failure: point the HTTP monitor at a broken URL
# Expected: Vigilmon alerts within 2 minutes

# 3. Clear VIGILMON_HEARTBEAT_URL and let the worker run
# Expected: heartbeat alert fires after the grace window

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

Summary

| Monitor | What It Catches | |---|---| | HTTP app check | Server crashes, broken builds, CDN outages | | HTTP health API | Dependency and third-party service failures | | Heartbeat | Stalled workers, silent background job failures |


Next Steps

  • Set up separate monitors for staging and production environments
  • Use Vigilmon's response time graphs to detect latency spikes after deploys
  • Configure on-call escalation so alerts reach your phone, not just your inbox

Ready to monitor your Yo-yo app in minutes? Sign up for Vigilmon free — no credit card required.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →