Capri is a static site generator built around the islands architecture — it renders pages to pure HTML at build time and hydrates only the interactive "islands" in the browser, giving you the speed of static HTML with the richness of a component framework. But a fast site doesn't protect you from CDN outages, broken build pipelines, or API dependencies that go silent overnight. Vigilmon fills that gap: continuous HTTP monitoring, heartbeat checks, and instant alerts delivered to email or Slack.
What You'll Build
- HTTP monitors for your Capri-generated static site
- A health endpoint for any server-side functions or API proxies
- A heartbeat for your build and deploy pipeline
- Alert channels (email and Slack)
- A status badge embedded as a Capri island
Prerequisites
- A Capri site (supporting React, Preact, Vue, Svelte, or Solid islands)
- Hosting on a static CDN (Netlify, Vercel, Cloudflare Pages, or similar)
- A free Vigilmon account
Step 1: Monitor Your Static Site
Capri's primary output is static HTML deployed to a CDN. Configure a Vigilmon HTTP monitor to verify the site is reachable and the CDN is serving correctly:
Log in to Vigilmon → Monitors → New Monitor:
Monitor 1: Static Site Root
| Field | Value |
|---|---|
| URL | https://yoursite.com/ |
| Method | GET |
| Expected status | 200 |
| Expected body | A stable string from your generated HTML (e.g. your site title) |
| Check interval | 1 minute |
Monitor 2: Critical Content Page
Monitor a page that depends on your most important content pipeline:
| Field | Value |
|---|---|
| URL | https://yoursite.com/blog/ |
| Method | GET |
| Expected status | 200 |
| Expected body | A stable heading or string from the page |
| Check interval | 5 minutes |
Step 2: Add a Health Endpoint for Server Functions
If your Capri site uses a backend API, server-side rendering for specific routes, or an API proxy (common with Netlify Functions or Vercel Functions), add a health endpoint:
// netlify/functions/health.js (Netlify Functions example)
export const handler = async () => {
const checks = {};
let degraded = false;
// CMS / data source check
try {
const res = await fetch("https://your-cms.io/api/health", {
signal: AbortSignal.timeout(3000),
});
checks.cms = res.ok ? "ok" : `http_${res.status}`;
if (!res.ok) degraded = true;
} catch {
checks.cms = "unreachable";
degraded = true;
}
// Database check (if applicable)
try {
// await db.query("SELECT 1");
checks.database = "ok";
} catch (err) {
checks.database = `error: ${err.message}`;
degraded = true;
}
return {
statusCode: degraded ? 503 : 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
status: degraded ? "degraded" : "ok",
timestamp: new Date().toISOString(),
checks,
}),
};
};
Add a Vigilmon monitor for it:
| Field | Value |
|---|---|
| URL | https://yoursite.com/.netlify/functions/health |
| Method | GET |
| Expected status | 200 |
| Check interval | 1 minute |
Step 3: Heartbeat for Your Build Pipeline
Capri sites are built and deployed by a CI/CD pipeline. A failed build that nobody notices means your users see stale or broken content. A Vigilmon heartbeat detects this automatically:
GitHub Actions example
# .github/workflows/deploy.yml
name: Build & Deploy
on:
push:
branches: [main]
schedule:
- cron: "0 2 * * *" # Nightly rebuild for fresh content
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build Capri site
run: npm run build
- name: Deploy to Netlify
run: npx netlify-cli deploy --prod --dir=dist
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
- name: Ping Vigilmon heartbeat
if: success()
run: curl -s "${{ secrets.VIGILMON_HEARTBEAT_URL }}" > /dev/null
Set up the heartbeat in Vigilmon:
- Monitors → New Heartbeat Monitor
- Set Expected interval to
25 hours(covers both scheduled nightly builds and ad-hoc deploys) - Add the ping URL to your repo secrets as
VIGILMON_HEARTBEAT_URL
Step 4: Status Badge as a Capri Island
Capri's island architecture is perfect for a live status badge — it's interactive (fetches live data) but lightweight. Here's an example using a React island:
// src/islands/StatusBadge.tsx (React island)
import { useState, useEffect } from "react";
const BADGE_URL = "https://vigilmon.online/api/badge/your-monitor-id.svg";
const STATUS_URL = "https://vigilmon.online/status/your-monitor-slug";
export default function StatusBadge() {
const [visible, setVisible] = useState(false);
useEffect(() => setVisible(true), []);
return (
<a
href={STATUS_URL}
target="_blank"
rel="noopener noreferrer"
aria-label="Service uptime status"
style={{ display: "inline-flex", alignItems: "center" }}
>
<img
src={BADGE_URL}
alt="Uptime"
width={120}
height={20}
style={{ opacity: visible ? 1 : 0, transition: "opacity 0.2s" }}
/>
</a>
);
}
Include it in a Capri page:
// src/pages/index.tsx
import StatusBadge from "../islands/StatusBadge";
export default function Home() {
return (
<main>
<h1>My Capri Site</h1>
{/* Static content — rendered at build time */}
<p>Fast, static, and always up to date.</p>
{/* Island — hydrated in the browser */}
<footer>
<StatusBadge client:load />
</footer>
</main>
);
}
The client:load directive tells Capri to hydrate StatusBadge immediately after the page loads, while the rest of the page stays as static HTML.
Step 5: Set Up Alert Channels
In Vigilmon's Alert Channels settings:
- Alert Channels → Email → add your on-call address
- Attach it to all monitors and the heartbeat
Slack
- Create a Slack Incoming Webhook for
#alerts - Alert Channels → Webhook → paste the URL
- Use this payload template:
{
"text": "🚨 *{{ monitor.name }}* is DOWN\n{{ monitor.url }}\nStatus: {{ event.status }}\n<https://vigilmon.online|Open Vigilmon>"
}
Step 6: Verify the Setup
# 1. Confirm static site returns 200
curl -s -o /dev/null -w "%{http_code}" https://yoursite.com/
# 2. Confirm health function (if applicable)
curl -s https://yoursite.com/.netlify/functions/health | jq .
# 3. Force a CMS connectivity failure in the health function
# Expected: returns 503; Vigilmon alerts within 2 minutes
# 4. Block the build pipeline without pinging the heartbeat
# Expected: heartbeat alert fires after the grace window
# 5. Vigilmon → "Test Alert" → confirm delivery to email/Slack
Summary
| Monitor | What It Catches | |---|---| | HTTP root check | CDN outages, broken deployments, certificate failures | | HTTP health function | CMS, database, and third-party API failures | | Heartbeat | Failed builds, broken deploy pipelines |
Next Steps
- Add monitors for each critical page that relies on different content sources
- Use Vigilmon's response time graphs to detect CDN latency regressions after island hydration
- Configure multi-channel alerting: email for warnings, Slack for critical failures
Ready to get started? Sign up for Vigilmon free — have your first monitor running in under 5 minutes.