Self-Hosting changedetection.io: Track Changes on Any Website Automatically
You want to know when a price drops on a product page. When a government website updates a policy. When a competitor changes their pricing page. When a job listing appears. You could check manually every day, or you could have a self-hosted tool watch the page for you and send a notification the moment something changes.
changedetection.io does exactly this. Point it at any URL, tell it what part of the page to watch, and it'll check on a schedule and notify you when something changes. It handles JavaScript-rendered pages, visual diffs, and integrates with dozens of notification services.
Why changedetection.io?
- Monitor any URL — Track changes on any public web page
- CSS/XPath selectors — Watch specific sections, not the whole page
- Visual diff — See exactly what changed, highlighted
- JavaScript support — Uses a real browser to render dynamic pages
- Notification integrations — Email, Slack, Discord, Telegram, ntfy, webhooks, and 70+ more via Apprise
- JSON/API monitoring — Track changes in API responses, not just HTML
- Import/export — Share watch lists as JSON
The self-hosted advantage: commercial alternatives like Visualping charge $10-40/month for 100-1,000 checks. changedetection.io is free and unlimited.
Docker Deployment
Basic setup (no JavaScript rendering)
# docker-compose.yml
services:
changedetection:
image: ghcr.io/dgtlmoon/changedetection.io:latest
ports:
- "5000:5000"
volumes:
- changedetection_data:/datastore
environment:
- BASE_URL=https://changes.yourdomain.com
- PUID=1000
- PGID=1000
restart: unless-stopped
volumes:
changedetection_data:
With Playwright for JavaScript-rendered pages
Many modern websites render content with JavaScript. Without a real browser, changedetection.io only sees the raw HTML (which is often empty). Add Playwright:
# docker-compose.yml
services:
changedetection:
image: ghcr.io/dgtlmoon/changedetection.io:latest
ports:
- "5000:5000"
volumes:
- changedetection_data:/datastore
environment:
- BASE_URL=https://changes.yourdomain.com
- PLAYWRIGHT_DRIVER_URL=ws://playwright-chrome:3000
- PUID=1000
- PGID=1000
depends_on:
- playwright-chrome
restart: unless-stopped
playwright-chrome:
image: dgtlmoon/sockpuppetbrowser:latest
environment:
- SCREEN_WIDTH=1920
- SCREEN_HEIGHT=1080
- MAX_CONCURRENT_CHROME_PROCESSES=5
restart: unless-stopped
volumes:
changedetection_data:
docker compose up -d
The web interface is at http://your-server:5000.
Adding Your First Watch
- Click Add Watch
- Enter the URL to monitor
- Set the check interval (default: 3 hours)
- Click Save
changedetection.io fetches the page and stores the initial snapshot. On the next check, it compares the new content with the previous version and flags any differences.
Filtering: Watch What Matters
Most pages have headers, footers, ads, and timestamps that change constantly. You don't want notifications about those. Use CSS selectors or XPath to watch only the content you care about.
CSS selector filtering
Edit a watch and set CSS/XPath Filter:
/* Watch only the product price */
.product-price
/* Watch a specific div */
#main-content .article-body
/* Watch multiple elements */
.price, .availability-status
XPath filtering
//div[@class="price-container"]
//table[@id="schedule"]/tbody
Text filtering
Ignore lines matching a pattern:
# In "Ignore Text" field
/Last updated:.*/
/Copyright \d{4}/
/Session ID: [a-f0-9]+/
This removes dynamic content that would trigger false change notifications.
Notification Setup
changedetection.io uses the Apprise library, which supports 70+ notification services with a simple URL format.
Discord
discord://webhook_id/webhook_token
Telegram
tgram://bot_token/chat_id
Slack
slack://token_a/token_b/token_c/#channel
ntfy (self-hosted push notifications)
ntfy://ntfy.yourdomain.com/changedetection
Email (SMTP)
mailto://user:[email protected]:587/[email protected]
Configure notification URLs in Settings > Notifications for global defaults, or per-watch for specific URLs.
Practical Use Cases
Price monitoring
Watch a product page, filter to the price element:
- CSS filter:
.price-nowor[data-test="product-price"] - Check interval: Every 6 hours
- Notification: Send to your phone via Telegram or ntfy
Job listing monitoring
Track a company's careers page:
- CSS filter:
.job-listingor#open-positions - Check interval: Every 4 hours
- Trigger: Any new content in the filtered section
API monitoring
changedetection.io can monitor JSON API responses:
- Set the URL to an API endpoint
- Choose "JSON" as the fetch type
- Use JSONPath to watch specific fields:
$.data.priceor$.results[0].status
Competitor monitoring
Watch a competitor's pricing or feature page:
- CSS filter:
.pricing-tableor.features-list - Check interval: Daily
- Visual diff: See exactly what changed
Government and legal monitoring
Track policy pages, license renewals, or regulatory updates:
- CSS filter:
#contentor.document-body - Check interval: Daily
- Ignore text: Remove timestamps and session IDs
Advanced Features
Visual selector tool
Don't know the CSS selector? Use the built-in visual selector:
- Edit a watch
- Click Visual Selector
- The page renders in your browser
- Click on the element you want to watch
- changedetection.io generates the CSS selector for you
Conditional notifications
Only notify when specific text appears or disappears:
- Trigger text:
"In Stock"— Only notify when this text appears - Trigger text (negative):
"Sold Out"— Notify when this text disappears
Proxy support
If you're monitoring many pages, use proxies to avoid rate limiting:
# In Settings > Proxy
http://proxy-user:proxy-pass@proxy-host:8080
Restock detection mode
changedetection.io has a built-in restock detection mode for e-commerce. Enable it per-watch to automatically detect "Add to Cart," "In Stock," and similar indicators across major e-commerce platforms.
Resource Usage
changedetection.io is lightweight on its own:
- Without Playwright: ~50 MB RAM, minimal CPU
- With Playwright: ~500 MB RAM (the browser is the heavy part)
For most homelabs, the Playwright container is the main resource concern. Limit concurrent browser processes with MAX_CONCURRENT_CHROME_PROCESSES to control memory usage.
The Bottom Line
changedetection.io automates the tedious task of manually checking websites for updates. The combination of CSS selector filtering, JavaScript rendering support, and Apprise notification integration makes it versatile enough for everything from price monitoring to regulatory compliance tracking. Deploy it with Playwright for JavaScript support, set up a notification channel, and let it watch the internet for you. It replaces manual checking habits that waste hours per month with automated, instant notifications.