Keywords: domain monitor
β’ domain checker
β’ whois lookup
β’ ssl certificate tracker
β’ domain expiration alerts
β’ sveltekit
β’ cloudflare workers
β’ slack notifications
β’ resend notifications
β’ email notifications
π Check Live Demo
Monitor domain availability, track expiration dates, and get notifications when domains become available or are about to expire.
A modern domain monitoring tool built with SvelteKit and Cloudflare Workers that tracks domain availability, SSL certificates, and sends smart notifications via Slack or email (Resend).
Perfect for: Domain investors, web developers, businesses tracking competitor domains, and anyone managing domain portfolios.
- Frontend: SvelteKit
- Platform: Cloudflare Workers
- Database: Cloudflare D1 (SQLite)
- Notifications: Slack Webhooks, Resend API
- Scheduling: Cloudflare Cron Triggers
- Domain API: WhoisJSON (1000 free calls/month)
- π Overview
- π Features
- π¦ Setup
- π οΈ Development
- π Deployment
- ποΈ Database Schema
- π Troubleshooting
A SvelteKit application running on Cloudflare Workers that monitors domain availability and sends notifications via Slack or Email (Resend) when domains become available.
In addition to available domains, you also receive:
- A list of domains that are expiring within 30 days
- A list of domains that have already expired but are still registered
A daily summary keeps you informed and helps you act fast.
- Domain Monitoring: Monitor domain status, including availability, nameservers (NS), and SSL certificate validity.
- Automated Checks: A cron job runs every minute to evaluate if notification conditions are met (via Slack or Resend), based on the configured time and settings.
- Notifications via Slack or Email (Resend): Get notified when domains become available or when specific conditions are met. Choose your preferred notification method (Slack or Email) and configure when alerts should be sent.
- Settings Panel: Configure API key for WhoisJSON, choose your preferred view mode for the interface, and manage notification settings for Slack and Resend.
- Web Interface: A clean and functional UI where you can add new domains, view and manually refresh domain status, perform bulk checks, and manage your domain list with ease.
- Node.js and pnpm
- Cloudflare Account
- WhoIs JSON API key - Get your API key for domain lookups
- Slack Webhooks β Create a Slack app and generate an incoming webhook URL for Slack notifications
- Resend API β Generate your Resend API key to enable email notifications
-
Environment Configuration
Create a local
.env
file by duplicating the example:# Copy the example environment file cp .env.example .env
Then edit
.env
with your specific values:PUBLIC_ENVIRONMENT=dev PUBLIC_TIMEZONE=Europe/Ljubljana CRON_SECRET=dev-super-secure-key PRODUCTION_DOMAIN=https://your-app.com
-
Local Database Setup
Create and configure your local development database:
# Creation of DB and applying schema to local database npx wrangler d1 execute local-domain-watcher --local --file=./schema.sql
-
Verify Database Setup
Check that your database was created successfully:
# Verify local database connection npx wrangler d1 execute local-domain-watcher --local --command="SELECT * FROM domains;"
Expected output: Existing test data
-
Start Development Server
Launch the local development server:
# Start development server pnpm run dev
Your application will be available at: http://localhost:5173
-
Build the application:
pnpm run build
-
Start local development server:
npx wrangler dev --local
-
Test with cron jobs:
npx wrangler dev --test-scheduled
Visit the following URL to manually trigger a cron job:
http://localhost:8787/__scheduled?cron=*+*+*+*+*
π Starting cron...
π Check at: 21:23
π Note: If you see "β Local - Self-call completed successfully!" in the logs, it means the local cron function is running successfully.
The cron job runs every minute to check scheduled notifications. Since you can set specific times in Slack or Resend settings (e.g., "Send at 14:30"), the cron job must check every minute to trigger notifications at the exact scheduled time.
Example: If notification is set for 14:30, the cron job checks every minute until it matches 14:30, then sends the notification.
Deploy your application using Cloudflare Worker with GitHub integration.
β οΈ Important: Complete database setup before deploying your application!
# Connect to CF account and create production database
npx wrangler d1 create prod-domain-watcher
After creating the database, copy the generated d1_databases
configuration into your wrangler.jsonc file under env.production.d1_databases
:
"d1_databases": [
{
"binding": "DB",
"database_name": "prod-domain-watcher",
"database_id": "generated-id"
}
]
# Apply schema to production database
npx wrangler d1 execute prod-domain-watcher --remote --file=./schema.sql
# Check if tables were created successfully
npx wrangler d1 execute prod-domain-watcher --remote --command="SELECT * FROM domains;"
1. Go to Cloudflare Dashboard:
- Navigate to Workers & Pages under Compute (Workers)
- Click Create β Workers
- Select Connect to Git
2. Import Repository:
- Choose your repository (e.g., "domain-watcher")
- Enter your project name
-
Build command:
pnpm run build
-
Deploy command:
npx wrangler deploy --env production
-
Build variables:
Set these environment variables (update timezone and generate your own secret):
PUBLIC_ENVIRONMENT = production PUBLIC_TIMEZONE = Europe/Ljubljana # Change to your timezone (e.g., America/New_York, UTC) CRON_SECRET = strong-secret-key-here # Replace with a secure random string (32+ characters) PRODUCTION_DOMAIN = https://your-app.com # Live application URL for email assets and robots.txt control ALLOW_ROBOTS = false # Set to true ONLY when ready for search engine indexing
β οΈ Important: The CRON_SECRET environment variable must be identical to the value set in yourwrangler.jsonc
configuration file underenv.production.vars.CRON_SECRET
!
- Push to Repository: Commit and push your changes to trigger automatic deployment
- Monitor Build: Check build logs in Cloudflare Pages dashboard
- Verify Deployment: Visit your deployed URL to confirm everything works
Set Environment Variables in Cloudflare Worker Dashboard:
- Go to Settings > Build > Variables and Secrets
- Add
PUBLIC_ENVIRONMENT
,PUBLIC_TIMEZONE
,PRODUCTION_DOMAIN
,CRON_SECRET
andALLOW_ROBOTS
The application uses two main tables:
domains
Table
- Stores domain names and availability status
- Tracks domain expiration dates and check history
- Stores complete API responses from WhoisJSON (domain, DNS, SSL data)
- Includes error logging and check statistics
settings
Table
- Category-based configuration storage (api, ui, notifications)
- JSON-based config data for flexible settings management
- Handles API credentials, UI preferences, and notification settings
- Supports enabled/disabled states for notification services
For detailed table structure and relationships, see schema.sql
- "Database not found": Ensure you've created the database and updated the
database_id
inwrangler.jsonc
- "Environment variables missing": Set
PUBLIC_ENVIRONMENT
,PUBLIC_TIMEZONE
,CRON_SECRET
andALLOW_ROBOTS
in Cloudflare Dashboard - Cron jobs not working: Ensure
CRON_SECRET
values are identical inwrangler.toml
and Cloudflare Dashboard Variables and Secrets - Cron jobs not working locally: Use
npx wrangler dev --test-scheduled
and test via the/__scheduled
endpoint
- Check logs in Cloudflare Dashboard under Functions > Logs
- Use
console.log
statements in your code for debugging - Test API endpoints manually using curl or browser developer tools
### LOCAL ###
# Check database
npx wrangler d1 execute local-domain-watcher --local --command="SELECT * FROM domains";
# Check database structure
npx wrangler d1 execute local-domain-watcher --local --command="PRAGMA table_info(domains);"
# Export database backup
npx wrangler d1 export local-domain-watcher --local --output=backup.sql
### PRODUCTION ###
# Check production database
npx wrangler d1 execute prod-domain-watcher --remote --command="SELECT * FROM domains";
# Check database structure
npx wrangler d1 execute prod-domain-watcher --remote --command="PRAGMA table_info(domains);"
- Fork the repository
- Create a feature branch
- Make your changes
- Test locally with
npx wrangler dev
- Submit a pull request