Get EdgeViz running on your site in minutes.
EdgeViz uses a Service Worker to detect connectivity failures anywhere in the path — ISP issues, DNS failures, CDN edge problems, or origin outages. Because Service Workers must be served from the same origin as your site, you need to proxy three files through your web server:
/edgeviz.js — the bootstrap loader (registers the service worker)/edgeviz-sw.js — the service worker itself/edgeviz-core.js — the core detection and reporting logicOnce proxied, add a single script tag to every page of your site and you're done.
# Add to your server block
location ~ ^/(edgeviz-sw|edgeviz-core|edgeviz)\.js$ {
proxy_pass https://edgeviz.net;
# Required: without SNI, edgeviz.net answers 421.
proxy_ssl_server_name on;
proxy_set_header Host edgeviz.net;
}
Then reload nginx:
nginx -t && nginx -s reload
Requires mod_proxy, mod_proxy_http and mod_ssl enabled.
# Add to your VirtualHost
# Required: edgeviz.net is HTTPS. Without it every file returns 500.
SSLProxyEngine on
ProxyPass "/edgeviz-sw.js" "https://edgeviz.net/edgeviz-sw.js"
ProxyPassReverse "/edgeviz-sw.js" "https://edgeviz.net/edgeviz-sw.js"
ProxyPass "/edgeviz-core.js" "https://edgeviz.net/edgeviz-core.js"
ProxyPassReverse "/edgeviz-core.js" "https://edgeviz.net/edgeviz-core.js"
ProxyPass "/edgeviz.js" "https://edgeviz.net/edgeviz.js"
ProxyPassReverse "/edgeviz.js" "https://edgeviz.net/edgeviz.js"
Put these lines above any catch-all ProxyPass "/". Apache uses the first rule that matches.
If the VirtualHost sets ProxyPreserveHost On, Apache sends your hostname to edgeviz.net and every file returns 500. Turn it off for these three paths only:
<LocationMatch "^/edgeviz(-sw|-core)?\.js$">
ProxyPreserveHost Off
</LocationMatch>
Then restart Apache:
apachectl graceful
yourdomain.com {
# Proxy EdgeViz files
@edgeviz path /edgeviz-sw.js /edgeviz-core.js /edgeviz.js
reverse_proxy @edgeviz https://edgeviz.net {
header_up Host edgeviz.net
}
# Your other config...
root * /var/www/html
file_server
}
If your site is behind Cloudflare, you can use a Worker to proxy the files:
export default {
async fetch(request) {
const url = new URL(request.url);
if (url.pathname === '/edgeviz-sw.js' ||
url.pathname === '/edgeviz-core.js' ||
url.pathname === '/edgeviz.js') {
const edgevizUrl = 'https://edgeviz.net' + url.pathname + url.search;
return fetch(edgevizUrl);
}
// Pass through to origin
return fetch(request);
}
}
Deploy with route pattern: yourdomain.com/edgeviz* (no hyphen, or the route misses /edgeviz.js)
Add to your vercel.json or next.config.js:
{
"rewrites": [
{ "source": "/edgeviz.js", "destination": "https://edgeviz.net/edgeviz.js" },
{ "source": "/edgeviz-sw.js", "destination": "https://edgeviz.net/edgeviz-sw.js" },
{ "source": "/edgeviz-core.js", "destination": "https://edgeviz.net/edgeviz-core.js" }
]
}
Once the proxy is configured, add this to your HTML (before </body> or in <head>):
<script async src="https://yourdomain.com/edgeviz.js?id=YOUR_CLIENT_ID"></script>
The service worker registers when a visitor loads a page carrying the tag, and starts intercepting from their next navigation on. A visitor who lands on an untagged page is never monitored — and any URL can be the entry point: a search result, a shared link, a deep link to one tool. Put the tag in your shared layout or template so every page carries it.
No shared template? Inject it at build time over your output directory, or let the server do it — Apache mod_substitute, nginx sub_filter, or a Cloudflare Worker HTMLRewriter can append the tag to every text/html response.
The async attribute is critical. Without it, if the EdgeViz origin is unreachable, the script tag will block your page load until the proxy times out.
Log into your dashboard and hover over your name in the top right. Your Client ID will be shown in the tooltip.
1 Open your site in a browser
2 Open DevTools → Application → Service Workers
3 You should see edgeviz-sw.js registered
4 Check the Console for any errors
If the service worker fails to register, check that:
The tag is async, so a broken proxy fails silently. Test the proxy directly:
curl -s "https://yourdomain.com/edgeviz.js?id=YOUR_CLIENT_ID"
It must print one line that registers /edgeviz-sw.js?id=YOUR_CLIENT_ID. A 421 from nginx means proxy_ssl_server_name is missing. A 500 from Apache means SSLProxyEngine is missing, or ProxyPreserveHost is on for these paths.
For beacons to be accepted, your domain must be registered and verified on your account. Add it in the dashboard. This does not happen on its own, deliberately — your client ID is public, it ships in the script tag on every page, so auto-registering whatever origin turned up would let anyone attach their site to your account.
To verify, serve the token the dashboard shows as a plain-text file at https://yourdomain.com/.well-known/edgeviz-verify.txt. Each hostname has its own token. If an app proxy owns every path on the host, exclude this path from it and serve the file directly.
Until the domain is registered, ingest answers every beacon with 403 Origin not authorized for this client. The tag still loads and the worker still registers, so the site looks correctly instrumented while nothing reaches your dashboard. If you are seeing no beacons at all, check this first.
Beacons fan out to four endpoints in parallel so an outage can still be reported when the direct path is down. Two are ours (*.4.edgeviz.net, *.6.edgeviz.net); two are relays we do not run, on Cloudflare Workers and Fastly Compute. Beacon payloads are sealed before they leave the browser — the failed URL, referrer, reason and diagnostics are encrypted to a key that never leaves our monitor, so a relay can route but cannot read them.
What sealing cannot hide is the connection. Your visitor's IP, and the Origin header the browser attaches to every cross-origin request, are visible to any endpoint on the path. If that matters to you, decline the relays:
| policy | beacons | hourly checkins |
|---|---|---|
all (default) | v4, v6, both relays | direct, both relays |
beacon-only | v4, v6, both relays | direct only |
none | v4, v6 | direct only |
beacon-only is the useful middle. The hourly checkin reports healthy traffic, so relaying it benefits us — it tells us our ingest is unreachable for someone — and does nothing for you. Turning it off is the single change that stops a third party seeing your visitors outside an actual outage.
none costs you two of four beacon delivery routes. The remaining two are ours, and every attempt on them emits a DNS query our authoritative nameserver records even when the POST never lands — so beacons still arrive, with fewer ways around a broken network.
Ask us to set it on your account. To verify it rather than take our word for it, /edgeviz-policy.json?id=YOUR_CLIENT_ID reports your effective policy, which fields are sealed, and what a relay can still observe on each path.
EdgeViz monitors the full path between your users and your origin. The service worker intercepts navigation requests and detects failures at any layer:
When a failure is detected, the service worker sends a beacon to EdgeViz. Beacons carry diagnostics about the failure — what broke, where the user is, what network they're on, and what the edge saw.
The service worker sends different beacon types depending on the situation:
Beacons are sent over multiple paths simultaneously — IPv4, IPv6, DNS, and relay workers — to maximize the chance of reaching EdgeViz even when parts of the internet are broken. The dashboard shows which paths each beacon arrived on.
When failure beacons arrive, EdgeViz groups them into incidents by domain and failure type. An incident tracks:
When all affected sessions send recovery beacons, the incident is marked as recovered and a recovery alert is triggered. Incidents without new beacons expire after 12 hours.
DNS-only incidents start with sparse data — no geo, no browser, no edge PoP — because DNS beacons are minimal signals. When a recovery beacon arrives over HTTP, EdgeViz automatically backfills the missing details (location, ISP, browser, device) from the richer recovery data.
EdgeViz can send alerts when incidents are detected or recover. Configure alert destinations in your dashboard settings — webhook URLs, email, or Slack. Each alert includes the incident type, affected domain, session count, and a link to the dashboard.