Atomico is a small but powerful framework for building web components with a hooks API inspired by React. It lets you write functional, reusable custom elements with minimal boilerplate. But that elegant developer experience means nothing when your app is down, your API is unreachable, or a background task is silently failing. Vigilmon gives you the visibility layer you need: continuous HTTP monitoring, heartbeat checks, and instant alerts routed to email or Slack.
What You'll Build
- A health API endpoint for your Atomico backend
- Vigilmon HTTP monitors for your Atomico app and backend
- A heartbeat for scheduled background tasks
- Alert channels (email and Slack)
- An uptime badge as a reusable Atomico web component
Prerequisites
- An Atomico project (
npm install atomico) - Node.js/Express backend for the health endpoint
- A free Vigilmon account
Step 1: Add a Health Endpoint
Atomico apps are typically served as SPAs with a separate backend. Add a /health route to your Express server:
// 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;
}
// External API dependency check
try {
const r = await fetch("https://api.example.com/ping", {
signal: AbortSignal.timeout(3000),
});
checks.externalApi = r.ok ? "ok" : `http_${r.status}`;
} catch {
checks.externalApi = "unreachable";
degraded = true;
}
res.status(degraded ? 503 : 200).json({
status: degraded ? "degraded" : "ok",
timestamp: new Date().toISOString(),
checks,
});
});
// Serve Atomico SPA
app.use(express.static("dist"));
app.get("*", (req, res) => res.sendFile("dist/index.html", { root: "." }));
app.listen(process.env.PORT ?? 3000);
Test it:
curl http://localhost:3000/health | jq .
# {"status":"ok","timestamp":"2026-06-29T...","checks":{"database":"ok","externalApi":"ok"}}
Step 2: Configure Vigilmon HTTP Monitors
Log in to Vigilmon → Monitors → New Monitor:
Monitor 1: Atomico 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 |
With both monitors, you cover two independent failure classes: the static/CDN serving layer and the backend/data layer.
Step 3: Heartbeat for Background Tasks
Background jobs — token refresh, cache warming, webhook ingestion — can fail silently for days without anyone noticing. A Vigilmon heartbeat catches this by alerting when the expected ping doesn't arrive.
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 processTokenRefresh();
await pingHeartbeat();
} catch (err) {
console.error("[scheduler] Token refresh failed:", err);
// Vigilmon alerts after the heartbeat window expires with no ping
}
});
async function processTokenRefresh() {
// Your actual token refresh logic
}
Set up the heartbeat in Vigilmon:
- Monitors → New Heartbeat Monitor
- Set Expected interval to 10 minutes (2× the cron interval for a grace window)
- Copy the ping URL to your
.env:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx
Step 4: Display Uptime Status as an Atomico Web Component
Atomico makes it trivial to create a reusable <status-badge> custom element with hooks:
// src/components/status-badge.js
import { c, html, css } from "atomico";
function StatusBadge({ badgeUrl, statusUrl }) {
return html`
<host shadowDom>
<a
href="${statusUrl}"
target="_blank"
rel="noopener noreferrer"
aria-label="Service uptime status"
>
<img
src="${badgeUrl}"
alt="Uptime"
width="120"
height="20"
/>
</a>
</host>
`;
}
StatusBadge.props = {
badgeUrl: {
type: String,
value: "https://vigilmon.online/api/badge/your-monitor-id.svg",
},
statusUrl: {
type: String,
value: "https://vigilmon.online/status/your-monitor-slug",
},
};
export const statusBadge = c(StatusBadge);
customElements.define("status-badge", statusBadge);
Use it anywhere in your HTML or Atomico templates:
<!-- index.html or any Atomico component -->
<script type="module" src="./src/components/status-badge.js"></script>
<footer>
<status-badge></status-badge>
</footer>
Or embed it in another Atomico component:
// src/components/app-footer.js
import { c, html } from "atomico";
import "./status-badge.js";
function AppFooter() {
return html`
<host shadowDom>
<footer class="footer">
<status-badge></status-badge>
</footer>
</host>
`;
}
export const appFooter = c(AppFooter);
customElements.define("app-footer", appFooter);
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 responds correctly
curl -s https://yourapp.com/health | jq .
# 2. Simulate DB failure → confirm health returns 503
# Expected: Vigilmon alerts within 2 minutes
# 3. Remove 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 and third-party API failures | | Heartbeat | Scheduler crashes, silent background task failures |
Next Steps
- Create separate monitors for staging vs. production
- Use Vigilmon's response time graphs to spot latency regressions
- 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.