Running Changedetection.io: Website Change Alerts
You want to know when a product drops in price, when a job posting appears, when a government page updates, or when your competitor changes their pricing. You could check manually every day. Or you could let a self-hosted tool do it for you.
Changedetection.io monitors any webpage and alerts you when something changes. It’s like Google Alerts, but for the actual visual content of any page — not just search results.
What It Does
- Monitor any URL for changes (text, HTML, visual)
- Filter changes — only alert on specific parts of a page
- Notification channels — Email, Telegram, Discord, Slack, webhooks, and 80+ more
- Visual diff — See exactly what changed, highlighted
- Scheduling — Check every minute, hour, day, or custom interval
- JavaScript rendering — Handle SPAs and dynamic sites via built-in browser
- CSS/XPath selectors — Watch specific elements, ignore the rest
- API — Integrate with other tools
Use Cases
- Price tracking — Alert when an item drops below your target price
- Job boards — Know instantly when new positions are posted
- Government/regulatory — Track policy changes, permit updates
- Competitor monitoring — Pricing changes, new features, blog posts
- Stock/availability — Get notified when out-of-stock items return
- News/blog monitoring — Follow sites that don’t have RSS feeds
- Legal/compliance — Track Terms of Service changes
- Real estate — New listings matching your criteria
Prerequisites
- Docker and Docker Compose
- ~256 MB RAM (lightweight without browser)
- ~512 MB RAM (with Playwright browser for JavaScript sites)
Installation
Basic Setup (No JavaScript Rendering)
Good for static sites, blogs, product pages with server-rendered content.
mkdir -p ~/changedetection
cd ~/changedetection
# docker-compose.yml
services:
changedetection:
image: ghcr.io/dgtlmoon/changedetection.io:latest
container_name: changedetection
ports:
- "5000:5000"
volumes:
- ./data:/datastore
environment:
- TZ=America/New_York
- BASE_URL=http://localhost:5000
restart: unless-stopped
docker compose up -d
Open http://your-server-ip:5000.
Full Setup (With JavaScript Browser)
For sites that load content dynamically (SPAs, React apps, pages requiring JavaScript):
# docker-compose.yml
services:
changedetection:
image: ghcr.io/dgtlmoon/changedetection.io:latest
container_name: changedetection
ports:
- "5000:5000"
volumes:
- ./data:/datastore
environment:
- TZ=America/New_York
- BASE_URL=http://localhost:5000
- PLAYWRIGHT_DRIVER_URL=ws://playwright-chrome:3000
depends_on:
- playwright-chrome
restart: unless-stopped
playwright-chrome:
image: dgtlmoon/sockpuppetbrowser:latest
container_name: playwright-chrome
restart: unless-stopped
environment:
- SCREEN_WIDTH=1920
- SCREEN_HEIGHT=1080
- MAX_CONCURRENT_CHROME_PROCESSES=5
docker compose up -d
The Playwright browser runs headless Chrome to render JavaScript before checking for changes.
Adding Your First Watch
- Click Add Watch (or paste a URL into the quick-add bar)
- Enter the URL you want to monitor
- Set the check interval (default: every 3 hours)
- Click Watch
The first check establishes a baseline. You’ll get alerts starting from the second check when changes are detected.
Filtering: Watch Only What Matters
Most pages have noise — ads, timestamps, random elements. Filters let you focus on what you care about.
CSS Selector Filter
Watch only a specific part of the page:
/* Product price */
.product-price
/* Job listings container */
#job-results .job-card
/* Main content, ignore sidebar */
article.main-content
Enter selectors in the watch settings under CSS/JSON/XPath Filter.
XPath Filter
More powerful for complex selections:
//div[@class="price-current"]
//table[@id="results"]//tr
//h2[contains(text(), "Available")]
Text Filtering
Ignore lines matching patterns (useful for removing timestamps, ad content):
Ignore text: Add regex patterns for lines to exclude:
Trigger Keywords
Only alert when specific words appear in the change:
Trigger text:
This is powerful — monitor a page but only get alerted when relevant keywords appear in the diff.
Setting Up Notifications
Go to Settings → Notification URLs.
Telegram
Get your bot token from @BotFather and chat ID from @userinfobot.
Discord
Create a webhook in your Discord server settings → Integrations → Webhooks.
Email (SMTP)
Slack
Gotify
Full Notification Format
You can customize the notification message with variables:
Changedetection supports 80+ notification services via Apprise.
Practical Examples
Price Drop Alert
URL: https://amazon.com/dp/B0xxxxx
CSS Filter: #priceblock_ourprice, .a-price .a-offscreen
Trigger text: (leave empty — any price change triggers)
Check interval: Every 6 hours
Job Board Monitoring
URL: https://company.com/careers
CSS Filter: .job-listing
Trigger text: engineer, developer, remote
Check interval: Every 1 hour
Out-of-Stock Alerts
URL: https://store.com/product-page
CSS Filter: .availability, .stock-status
Trigger text: in stock, available, add to cart
Check interval: Every 30 minutes
Terms of Service Changes
URL: https://service.com/terms
CSS Filter: main, article, .content (skip headers/footers)
Check interval: Every 24 hours
Blog Without RSS
URL: https://blog-with-no-rss.com
CSS Filter: .post-list, article:first-of-type
Check interval: Every 6 hours
Visual Diff Mode
By default, Changedetection shows text diffs. With the Playwright browser, you can also enable visual diff — actual screenshots compared side by side.
Enable per-watch: Edit → Request → Fetch Method → Chrome/Playwright
This catches changes that text-based detection misses (layout changes, image swaps, visual redesigns).
API Usage
Changedetection has a REST API for automation:
# List all watches
curl http://localhost:5000/api/v1/watch
# Add a new watch
curl -X POST http://localhost:5000/api/v1/watch \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "title": "Example Watch"}'
# Trigger a recheck
curl -X POST http://localhost:5000/api/v1/watch/UUID/trigger-check
Combine with n8n or cron for advanced automation workflows.
Proxy Support
If you’re monitoring sites that might block your IP:
environment:
- HTTP_PROXY=http://proxy:8080
- HTTPS_PROXY=http://proxy:8080
Or set per-watch proxies for specific sites that need different IPs.
Backup
Your watches and history are stored in ./data/. Back up with compose-backup:
compose-backup --only changedetection
Troubleshooting
“No change detected” on Dynamic Sites
Switch to the Playwright browser:
- Edit watch → Request → Fetch method → Chrome/Playwright
- Make sure
playwright-chromecontainer is running
Too Many False Alerts
- Add CSS selectors to focus on relevant content
- Use Ignore text to filter out timestamps, counters, ads
- Increase check interval (some sites have minor fluctuations)
Playwright Container Crashes
# Check memory — Playwright needs ~512MB
docker stats playwright-chrome
# Limit concurrent browsers if low on RAM
environment:
- MAX_CONCURRENT_CHROME_PROCESSES=2
Can’t Access Behind Login
Changedetection supports:
- Basic auth — Enter credentials in watch settings
- Cookie injection — Paste cookies from your browser session
- Custom headers — Add Authorization or session headers
Slow Checks
- Reduce
MAX_CONCURRENT_CHROME_PROCESSESif memory is tight - Use text-based fetching (not Playwright) for static sites
- Increase check intervals for non-urgent monitors
Resource Usage
| Setup | RAM | CPU | Storage |
|---|---|---|---|
| Basic (no browser) | ~100 MB | Minimal | ~50 MB + history |
| With Playwright | ~500 MB | Light | ~100 MB + history |
| 100+ watches | ~800 MB | Moderate | ~500 MB |
Very lightweight for what it does.
Comparison with Alternatives
| Feature | Changedetection | Huginn | Visualping | Distill.io |
|---|---|---|---|---|
| Self-hosted | ✅ | ✅ | ❌ | ❌ |
| Free | ✅ | ✅ | Freemium | Freemium |
| Visual diff | ✅ | ❌ | ✅ | ✅ |
| JS rendering | ✅ | ❌ | ✅ | ✅ |
| Ease of setup | Easy | Complex | N/A | N/A |
| Notifications | 80+ | Many | Limited | Limited |
Changedetection hits the sweet spot: powerful enough for complex monitoring, simple enough to set up in 5 minutes.
Conclusion
Changedetection.io replaces a dozen browser tabs you check manually. Set it up once, add your URLs, configure alerts, and forget about it. When something changes, you’ll know.
Especially useful for price tracking, job hunting, and monitoring anything that doesn’t offer proper notifications or RSS feeds.
More self-hosting guides at selfhostsetup.com. Check server health with selfhost-doctor.