DEV Community

Vigilmon
Vigilmon

Posted on

Monitoring Your Vue.js App with Vigilmon: Frontend Uptime, API Health & Alerts

Vue.js apps break in ways that don't show up in your browser console. Your backend API times out. Your CDN serves a cached build that references a deleted endpoint. A Vite preview deployment silently returns a blank page. Vigilmon watches your frontend and backend continuously so you find out about outages before users do. This tutorial walks you through wiring a Vue.js / Vite app into Vigilmon.

What You'll Build

  • A health check composable that probes your API from the browser
  • Vigilmon HTTP monitors for both your SPA and backend API
  • A cron heartbeat for scheduled Vue tasks (Node.js or Vite SSR)
  • A webhook error notification for unhandled Vue errors
  • Email and Slack alert channels

Prerequisites

  • Vue 3 project (Vite or Nuxt 3 work equally well)
  • A backend API (any language/framework)
  • A free Vigilmon account

Step 1: Create a Health Check Composable

Put your health-check logic in a reusable composable so any component or route guard can use it.

// src/composables/useHealthCheck.ts
import { ref } from "vue";

export interface HealthStatus {
  healthy: boolean;
  latencyMs: number | null;
  error: string | null;
}

export function useHealthCheck(apiBaseUrl: string) {
  const status = ref<HealthStatus>({
    healthy: false,
    latencyMs: null,
    error: null,
  });
  const loading = ref(false);

  async function check(): Promise<HealthStatus> {
    loading.value = true;
    const start = Date.now();
    try {
      const res = await fetch(`${apiBaseUrl}/health`, {
        signal: AbortSignal.timeout(5000),
      });
      const latencyMs = Date.now() - start;
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      status.value = { healthy: true, latencyMs, error: null };
    } catch (err) {
      status.value = {
        healthy: false,
        latencyMs: null,
        error: err instanceof Error ? err.message : "Unknown error",
      };
    } finally {
      loading.value = false;
    }
    return status.value;
  }

  return { status, loading, check };
}
Enter fullscreen mode Exit fullscreen mode

Use it in a component or on the app's mounted hook:

// src/App.vue (script setup)
import { onMounted, onUnmounted } from "vue";
import { useHealthCheck } from "@/composables/useHealthCheck";

const { status, check } = useHealthCheck(import.meta.env.VITE_API_BASE_URL);

let intervalId: ReturnType<typeof setInterval>;

onMounted(async () => {
  await check();
  intervalId = setInterval(check, 60_000); // re-check every minute
});

onUnmounted(() => clearInterval(intervalId));
Enter fullscreen mode Exit fullscreen mode

This tells you at runtime whether your API is reachable, but it only runs in the browser. You also need Vigilmon polling from the outside.


Step 2: Add Vigilmon HTTP Monitors

You need two monitors — one for the frontend SPA and one for the API.

Monitor 1: Vue SPA Uptime

Field Value
URL https://app.yourdomain.com/
Method GET
Expected status 200
Expected body <div id="app"> (or any stable string in your index.html)
Check interval 1 minute

This catches CDN outages, broken Vite builds, and misconfigured Nginx rewrites.

Monitor 2: Backend API Health

Field Value
URL https://api.yourdomain.com/health
Method GET
Expected status 200
Check interval 1 minute

If your API returns 500 or times out, Vigilmon alerts you immediately — before any user opens the app and sees a broken UI.

Create both monitors in Vigilmon under Monitors → New HTTP Monitor.


Step 3: Backend Health Endpoint

The Vigilmon API monitor needs something to check. Add a /health route to your backend. Here's an Express example (adapt to your backend):

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

  try {
    await db.query("SELECT 1"); // or your ORM equivalent
    checks.database = "ok";
  } catch (err) {
    checks.database = `error: ${err.message}`;
    degraded = true;
  }

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

Make sure to add Access-Control-Allow-Origin if your health check composable calls this from the browser.


Step 4: Heartbeat for Scheduled Tasks

If your app runs any scheduled tasks (nightly exports, email digests, cache warmers), you want to know if they stop running.

Node.js Cron Heartbeat

// src/jobs/scheduler.ts
import cron from "node-cron";
import fetch from "node-fetch";

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 {
    // don't let monitoring failure crash the job
  }
}

// Example: run data export every hour
cron.schedule("0 * * * *", async () => {
  try {
    await runDataExport();
    await pingHeartbeat(); // only ping on success
  } catch (err) {
    console.error("Data export failed:", err);
    // Vigilmon will alert after the expected interval passes without a ping
  }
});
Enter fullscreen mode Exit fullscreen mode

Set up the heartbeat in Vigilmon:

  1. Monitors → New Heartbeat Monitor
  2. Set expected interval to 90 minutes (gives the hourly job a 30-minute grace period)
  3. Copy the ping URL into your .env:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx
Enter fullscreen mode Exit fullscreen mode

Step 5: Webhook Alert on Unhandled Vue Errors

Vue's global error handler lets you fire a webhook whenever your app catches an unhandled error. This is different from uptime monitoring — it catches runtime JS errors that don't take down the whole app.

// src/main.ts
import { createApp } from "vue";
import App from "./App.vue";

const app = createApp(App);

app.config.errorHandler = async (err, instance, info) => {
  console.error("[Vue error]", err, info);

  const webhookUrl = import.meta.env.VITE_VIGILMON_WEBHOOK_URL;
  if (!webhookUrl) return;

  // Rate-limit to avoid flooding on repeated errors
  const key = `err_reported_${String(err).slice(0, 40)}`;
  if (sessionStorage.getItem(key)) return;
  sessionStorage.setItem(key, "1");

  try {
    await fetch(webhookUrl, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        text: `Vue error in ${info}: ${err}`,
        url: window.location.href,
      }),
    });
  } catch {
    // never throw from errorHandler
  }
};

app.mount("#app");
Enter fullscreen mode Exit fullscreen mode

In Vigilmon, create a Webhook Alert Channel and set its URL as VITE_VIGILMON_WEBHOOK_URL. You'll get a notification on Slack or email when users hit JavaScript errors in production.

Security note: don't expose a webhook URL directly in client-side code for high-security apps — proxy the call through your backend instead.


Step 6: Configure Alert Channels

In Vigilmon's Alerts settings:

Email

  1. Go to Alert Channels → Email
  2. Add your team's ops email
  3. Attach to both the SPA monitor and the API monitor

Slack Webhook

  1. Create a Slack Incoming Webhook for #alerts
  2. In Vigilmon, go to Alert Channels → Webhook
  3. Paste the Slack URL
  4. Use this template:
{
  "text": "🚨 *{{ monitor.name }}* is DOWN\n{{ monitor.url }}\nStatus: {{ event.status }}\n<https://vigilmon.online|Open Vigilmon>"
}
Enter fullscreen mode Exit fullscreen mode

Step 7: Test Everything

# 1. Verify health endpoint
curl -s https://api.yourdomain.com/health | jq .

# 2. Trigger a Vue error manually (dev console)
# window.__vueApp.config.errorHandler(new Error("test"), null, "manual test")

# 3. Stop the cron process, wait 90+ minutes → heartbeat alert fires

# 4. Use Vigilmon's "Test Alert" button to verify Slack/email delivery
Enter fullscreen mode Exit fullscreen mode

What You Now Have

Monitor Catches
HTTP SPA check CDN outage, broken builds, misconfigured rewrites
HTTP API health Backend crashes, DB failures, slow responses
Heartbeat Cron jobs stopping, scheduler crashes
Vue error webhook Runtime JS errors in production

Next Steps

  • Add a Vigilmon status page and embed the badge in your app's footer
  • Create separate monitor groups for staging and production
  • Use Vigilmon's response time history to track API latency trends over time

Found this useful? Vigilmon is free to start — sign up here and have your first monitor live in under 5 minutes.

Top comments (0)