tutorial

Monitoring Your Svelte App with Vigilmon: Vite Dev, SPA Health Checks & Uptime Alerts

Add production-grade monitoring to a Svelte SPA — a lightweight health API, heartbeat checks for background jobs, and instant alerts when your app goes down.

Svelte compiles down to vanilla JS, which means there's no framework runtime to blame when something breaks in production. The failure surface is smaller — but that makes silent failures harder to detect. Your SPA could be serving a blank white screen because a CDN deployment went wrong, your API backend could be unreachable, or a background sync could have silently crashed three days ago. Vigilmon catches all of this. This tutorial shows how to wire uptime monitoring, health checks, and heartbeat alerts into a Svelte app.

What You'll Build

  • A lightweight Express health API to run alongside your Svelte SPA
  • Vigilmon HTTP monitors for your frontend CDN URL and your health API
  • A heartbeat for background scheduled tasks
  • Email and Slack alert channels
  • A status badge in your Svelte footer

Prerequisites

  • A Svelte project (Vite + Svelte recommended)
  • Node.js backend (Express) for the health API
  • A free Vigilmon account

Step 1: Add a Health API Alongside Your Svelte App

Svelte SPAs are static — there's no server-side route to hit. You need a small backend process to expose a health endpoint. If you're already running an Express API, add the route there. If you're SPA-only, add a minimal Express server for ops:

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 backend is reachable
  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 integrations
  try {
    const res = await fetch("https://api.stripe.com/v1/", {
      signal: AbortSignal.timeout(3000),
    });
    checks.stripe = res.status < 500 ? "ok" : `http_${res.status}`;
  } catch {
    checks.stripe = "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}`);
});

Start it alongside your Vite dev server:

// package.json
{
  "scripts": {
    "dev": "vite",
    "dev:health": "node health-server.js",
    "start": "concurrently \"npm run preview\" \"npm run dev:health\""
  }
}

Test it:

curl http://localhost:3001/health | jq .
# {"status":"ok","timestamp":"2026-06-29T...","checks":{"api":"ok","stripe":"ok"}}

Step 2: Set Up Vigilmon HTTP Monitors

Log in to Vigilmon and create two monitors:

Monitor 1: Svelte SPA (CDN Check)

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

This catches CDN outages, broken deployments, and misconfigured headers.

Monitor 2: Health API

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


Step 3: Heartbeat for Background Jobs

If you run background tasks — nightly data imports, webhook processors, email digest generators — wire them to a Vigilmon heartbeat so you're alerted when they stop running.

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 failure must never crash the scheduler
  }
}

async function runNightlySync() {
  console.log("[scheduler] Starting nightly sync...");
  // Your actual sync logic here
  console.log("[scheduler] Sync complete");
}

cron.schedule("0 2 * * *", async () => {
  try {
    await runNightlySync();
    await pingHeartbeat(); // Only ping on success
  } catch (err) {
    console.error("[scheduler] Nightly sync failed:", err);
    // Vigilmon will alert after the heartbeat window expires
  }
});

console.log("[scheduler] Started");

In Vigilmon, create a Heartbeat monitor:

  1. Monitors → New Heartbeat Monitor
  2. Set the expected interval to 25 hours (1-hour grace on a nightly job)
  3. Copy the ping URL to your .env:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx

Step 4: Add a Status Badge to Your Svelte Footer

Display your uptime status directly in your app's footer.

<!-- src/lib/StatusBadge.svelte -->
<script>
  const BADGE_URL = "https://vigilmon.online/api/badge/your-monitor-id.svg";
  const MONITOR_URL = "https://vigilmon.online/status/your-monitor-slug";
</script>

<a href={MONITOR_URL} target="_blank" rel="noopener noreferrer" aria-label="Service status">
  <img
    src={BADGE_URL}
    alt="Uptime status"
    loading="lazy"
    width="120"
    height="20"
  />
</a>

Add it to your layout:

<!-- src/App.svelte -->
<script>
  import StatusBadge from "./lib/StatusBadge.svelte";
</script>

<main>
  <slot />
</main>

<footer>
  <StatusBadge />
</footer>

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 a CDN failure: temporarily point the monitor at a broken URL
# Expected: Vigilmon alerts within 2 minutes

# 3. Disable VIGILMON_HEARTBEAT_URL and let the scheduled job run
# Expected: heartbeat alert fires after the grace window

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

Summary

| Monitor | What It Catches | |---|---| | HTTP SPA check | CDN outages, broken builds, misconfigured headers | | HTTP health API | Backend failures, third-party outages | | Heartbeat | Scheduler crashes, silent background job failures |


Next Steps

  • Add monitors for staging and production environments separately
  • Use Vigilmon's response time graphs to catch latency regressions after deploys
  • Configure on-call escalation so alerts page your phone, not just your inbox

Want uptime monitoring in under 5 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 →