A comprehensive, production-ready website monitoring and status dashboard built with Next.js, TypeScript, and PostgreSQL. Monitor multiple projects, track route health, view uptime percentages, and get real-time status updates with automatic checking capabilities.
- Features
- Architecture
- Prerequisites
- Quick Start
- Configuration
- Usage
- API Reference
- Database
- Monitoring Logic
- Development
- Deployment
- Troubleshooting
- Contributing
- Multi-Project Dashboard: Monitor multiple websites/projects from a single interface
- Route-Level Tracking: Check individual API endpoints and pages within each project
- Real-Time Status Updates: Automated and manual status checking with instant feedback
- Uptime Calculation: Track uptime percentage based on recent status logs
- Response Time Tracking: Monitor and log response times for each request
- Historical Logs: Store and query historical status data in PostgreSQL
- Working: Routes with 200-299 responses and >70% uptime
- Previous Degradations: Routes that were previously degraded but are now healthy [Routes with 200-299 responses and <70% uptime]
- Degraded: Routes with 4xx errors or redirects too often
- Broken: Routes with connection failures (timeout/network) or 5xx server errors
- Unknown: Routes with no recent check data
- Auto-Checker: Client-side automatic re-checking of stale routes (configurable)
- Dynamic Route Handling: Detects and skips placeholder routes that require parameters
- Preview System: Live iframe previews of monitored websites with redirect handling
- Method Detection: Identifies POST-only endpoints returning 405 on GET requests
- Mobile Optimized: Responsive design with touch-friendly controls
- TypeScript: Fully typed codebase with strict type checking
- Dev Controls: Built-in development tools for testing and debugging
- Comprehensive Logging: Detailed server-side logging for troubleshooting
- Hot Reload: Fast development with Next.js hot module replacement
- Environment Validation: Settings validation on startup
- Frontend: Next.js 16 (App Router), React 19, TailwindCSS 4
- Backend: Next.js API Routes (serverless)
- Database: PostgreSQL with
pgdriver - UI Components: Radix UI, Lucide Icons, shadcn/ui
- Utilities: date-fns, clsx, zod
Status/
โโโ app/ # Next.js App Router
โ โโโ page.tsx # Main dashboard (all projects)
โ โโโ [project]/ # Project detail pages
โ โ โโโ page.tsx # Single project view
โ โ โโโ not-found.tsx # 404 handler
โ โโโ api/ # API routes
โ โโโ updateStatus/[site]/ # Route status checker
โ โโโ status/ # Get status data
โ โโโ report/ # Manual check endpoint
โ โโโ preview/ # Website preview iframe
โโโ components/ # React components
โ โโโ auto-checker.tsx # Auto-check client logic
โ โโโ manual-check-button.tsx # Manual check UI
โ โโโ route-chart.tsx # Status visualization
โ โโโ status-badge.tsx # Status indicator
โ โโโ project-preview.tsx # Website preview
โ โโโ ui/ # shadcn/ui components
โโโ lib/ # Core utilities
โ โโโ projectData.ts # Project & route definitions
โ โโโ settings.ts # Environment & config
โ โโโ db.ts # PostgreSQL connection pool
โ โโโ utils.ts # Status logic & DB queries
โ โโโ types.ts # TypeScript types
โโโ scripts/
โ โโโ setupDB.js # Database initialization
โโโ docs/
โ โโโ SYSTEM.md # System overview
โ โโโ SETTINGS.md # Configuration guide
โโโ certs/
โโโ ca.pem # Optional PostgreSQL CA cert
-
Status Check Trigger:
- Automated: Auto-checker detects stale routes (client-side)
- Manual: User clicks "Check Now" button
- Scheduled: External cron/scheduler calls API
-
API Processing (
/api/updateStatus/[site]):- Validates project exists
- Separates static vs. dynamic routes
- Fetches each static route with timeout
- Records status code and response time
- Inserts log into PostgreSQL
-
Status Determination (
lib/utils.ts):- Queries recent logs (default: last 20)
- Calculates uptime percentage
- Determines status based on error patterns
- Returns aggregated route status
-
UI Display:
- Server-side: Fetches latest status on page load
- Client-side: Auto-checker updates stale data
- Real-time: Status badges reflect current state
- Node.js: 18.x or higher
- PostgreSQL: 12.x or higher (local or cloud)
- npm or pnpm: Package manager
- Vercel Account: For easy deployment (optional)
- Neon/Supabase: Managed PostgreSQL for production (optional)
git clone https://github.com/yourusername/status.git
cd statusnpm installCreate a .env.local file in the root directory:
# Database (Required)
POSTGRES_URL=postgresql://user:password@host:5432/database?sslmode=require
# Optional Settings
NODE_ENV=development
POSTGRES_MAX_CLIENTS=5
PREVIEW_MAX_REDIRECTS=3
RECENT_ROUTE_LOGS_DEFAULT_LIMIT=20
NEXT_PUBLIC_DISABLE_AUTO_CHECK=false
NEXT_PUBLIC_AUTO_CHECK_STALE_MINUTES=45See docs/SETTINGS.md for all available environment variables.
npm run db:setupThis creates the status_logs table and required indexes.
Edit lib/projectData.ts to define your monitored projects:
export const projects: Project[] = [
{
slug: "my-app",
title: "My Application",
description: "Production web application",
visitLink: "https://myapp.com",
routes: [
{
path: "/",
title: "Home Page",
description: "Main landing page"
},
{
path: "/api/health",
title: "Health Check",
description: "API health endpoint"
}
]
}
]npm run devOpen http://localhost:3000 in your browser.
Manually check a project:
curl -X POST http://localhost:3000/api/updateStatus/my-appDefine all monitored projects and their routes:
{
slug: "unique-identifier", // URL-safe project ID
title: "Display Name", // Shown in UI
description: "Project details", // Brief description
visitLink: "https://example.com", // Base URL
routes: [ // Monitored endpoints
{
path: "/api/endpoint", // Route path (appended to visitLink)
title: "Endpoint Name", // Display name
description: "What it does" // Brief description
}
]
}Dynamic Routes: Routes with placeholders (e.g., /api/users/[id]) are automatically skipped. To monitor them, add a concrete example:
{ path: "/api/users/123", title: "User Example", description: "Sample user endpoint" }See docs/SETTINGS.md for comprehensive configuration options.
Quick Reference:
POSTGRES_URL: PostgreSQL connection string (required)NEXT_PUBLIC_DISABLE_AUTO_CHECK: Disable auto-checker (true/false)NEXT_PUBLIC_AUTO_CHECK_STALE_MINUTES: Minutes before auto-recheck (default: 45)PREVIEW_FETCH_TIMEOUT_MS: Preview fetch timeout in ms (default: 10000)
If using PostgreSQL with custom CA (e.g., Neon, Azure):
- Place certificate in
certs/ca.pem - The system automatically loads it if present
- Main Page (
/): Overview of all projects with status badges - Project Page (
/[project-slug]): Detailed route monitoring for one project
- Navigate to a project page
- Click "Check Now" on any route
- Wait for status update (page auto-reloads)
The auto-checker runs client-side and:
- Checks if any route is stale (older than
staleMinutes) - Triggers update API for stale routes
- Reloads page when updates complete
- Throttles requests to avoid overwhelming server
Disable auto-checking:
NEXT_PUBLIC_DISABLE_AUTO_CHECK=true- Hover over project cards to see live preview
- Previews follow redirects (waits 3-5s)
- POST-only endpoints show "Preview unavailable"
In development mode, additional controls appear:
- Clear status logs
- Force refresh
- View raw status data
Checks all routes for a project and logs status.
Parameters:
site(path): Project slug fromprojectData.ts
Response:
{
"results": [
{
"route": "/api/health",
"statusCode": 200,
"responseTime": 145,
"success": true,
"logged": true
}
],
"summary": {
"total": 5,
"successful": 4,
"failed": 1,
"skipped": 0
}
}Status Codes:
200-299: Success (logged as working)300-399: Redirect (logged as degraded)400-499: Client error (logged as degraded)500-599: Server error (logged as broken)0: Connection failure/timeout (logged as broken)-1: Dynamic route skipped (not logged)
Retrieves current status for all projects or a specific project.
Query Parameters:
project(optional): Filter by project slug
Response:
{
"projects": [
{
"slug": "my-app",
"title": "My Application",
"overallStatus": "working",
"routes": [
{
"path": "/api/health",
"currentStatus": "working",
"uptime": 100,
"lastChecked": "2025-12-23T10:30:00Z"
}
]
}
]
}Triggers manual check for specific routes.
Body:
{
"projectSlug": "my-app",
"routes": ["/api/health", "/"]
}Returns HTML preview of a target URL.
Query Parameters:
url(required): Target URL to preview
Response: HTML content suitable for iframe
CREATE TABLE status_logs (
id BIGSERIAL PRIMARY KEY,
project_slug TEXT NOT NULL,
route_path TEXT NOT NULL,
status_code INTEGER NOT NULL,
response_time INTEGER,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_status_logs_project_route_created_at
ON status_logs (project_slug, route_path, created_at DESC);Insert Status Log:
insertStatusLog(projectSlug, routePath, statusCode, responseTime?)Get Recent Logs:
getRecentRouteLogs(projectSlug, routePath, limit = 20)Clear All Logs (dev only):
DELETE FROM status_logs WHERE project_slug = $1;Cleanup old logs (example):
DELETE FROM status_logs
WHERE created_at < NOW() - INTERVAL '30 days';Add to cron for automatic cleanup.
function determineStatus(logs: StatusLog[]) {
// 1. Calculate uptime (% of 2xx responses)
const uptime = (2xx_count / total_logs) * 100
// 2. Check for critical errors
if (has_connection_errors || has_5xx_errors)
return "broken"
// 3. Check for degraded state
if (has_4xx_errors || has_3xx_redirects || uptime < 70)
return "degraded"
// 4. Default to working
return "working"
}- Based on recent logs (default: last 20 checks)
- Only
200-299responses count as "up" - Percentage rounded to nearest integer
- Measured in milliseconds
- Includes network + server processing time
- Stored per log for trend analysis
- 10-second timeout (configurable)
# Install dependencies
npm install
# Set up database
npm run db:setup
# Start dev server
npm run dev# Check single project
curl -X POST http://localhost:3000/api/updateStatus/my-app
# Get current status
curl http://localhost:3000/api/status?project=my-app
# Test preview
curl "http://localhost:3000/api/preview?url=https://example.com"Enable verbose logging:
ENABLE_DB_QUERY_LOGS=trueCheck logs in terminal where npm run dev is running.
This project uses shadcn/ui. Add new components:
npx shadcn@latest add [component-name]-
Push to GitHub:
git push origin main
-
Import to Vercel:
- Go to vercel.com
- Import your repository
- Add environment variables
-
Set Environment Variables:
POSTGRES_URL=your_production_database_url -
Deploy: Vercel auto-deploys on push
- Use managed PostgreSQL (Neon, Supabase, Railway)
- Run
npm run db:setupafter creating database - Or manually execute SQL from
scripts/setupDB.js
Set in Vercel dashboard or .env.production:
POSTGRES_URL: Production databaseNEXT_PUBLIC_*: Client-visible settings- See docs/SETTINGS.md for all options
- Verify database connection
- Trigger initial checks via API
- Set up monitoring/alerting (optional)
Solution: Set POSTGRES_URL in .env.local:
POSTGRES_URL=postgresql://user:pass@host:5432/dbnameSolution: Restart dev server. Ensure POSTGRES_URL is valid.
Check:
NEXT_PUBLIC_DISABLE_AUTO_CHECKis nottrue- Routes have
lastCheckedtimestamp - Timestamp is older than
staleMinutes
Solution:
NEXT_PUBLIC_DISABLE_AUTO_CHECK=false
NEXT_PUBLIC_AUTO_CHECK_STALE_MINUTES=45Solution: Add project to lib/projectData.ts with matching slug.
Solution:
- Place CA certificate in
certs/ca.pem - Or use connection string with
?sslmode=require
Solution: Reduce POSTGRES_MAX_CLIENTS:
POSTGRES_MAX_CLIENTS=3Check:
- Target URL allows iframes (no
X-Frame-Options: DENY) - CORS policy permits preview endpoint
- Increase timeout:
PREVIEW_FETCH_TIMEOUT_MS=15000
- SYSTEM.md: System architecture and implementation details
- SETTINGS.md: Complete environment variable reference
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow existing TypeScript patterns
- Add types for new features
- Update documentation
- Test locally before submitting
This project is licensed under the MIT License.
For issues and questions:
- Open a GitHub issue
- Check docs/ for detailed documentation
- Review existing issues for solutions
Made with โค๏ธ for reliable website monitoring
