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 };
}
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));
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(),
});
});
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
}
});
Set up the heartbeat in Vigilmon:
- Monitors → New Heartbeat Monitor
- Set expected interval to 90 minutes (gives the hourly job a 30-minute grace period)
- Copy the ping URL into your
.env:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx
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");
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:
- Go to Alert Channels → Email
- Add your team's ops email
- Attach to both the SPA monitor and the API monitor
Slack Webhook
- Create a Slack Incoming Webhook for
#alerts - In Vigilmon, go to Alert Channels → Webhook
- Paste the Slack URL
- Use this template:
{
"text": "🚨 *{{ monitor.name }}* is DOWN\n{{ monitor.url }}\nStatus: {{ event.status }}\n<https://vigilmon.online|Open Vigilmon>"
}
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
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)