A lightweight, dependency-free script that intercepts external (outbound) links and shows a confirmation modal before navigating away from your site. This pattern helps meet compliance by alerting users before they leave your site for a third-party page—especially important in regulated industries.
Features include:
- Single delegated event listener (high performance)
- Intercepts external
http/httpslinks only - Respects user intent (Ctrl/Cmd/middle click still works)
- Uses native
<dialog>element for built-in accessibility - Blocks dangerous URL schemes (javascript:, data:, etc.)
- Works with dynamically added links
- Keyboard accessible (Enter triggers interception automatically)
Visit the live URL and click the blue external link to trigger the modal.
Access the Designer through the read-only/sandbox link.
The script:
- Attaches one document.click listener (event delegation)
- Detects clicks on:
<a href="...">
<button formaction="...">- Resolves the URL safely using
new URL() - Skips:
- Internal links (same origin)
- Hash-only links (
#section) - Non-http(s) schemes
- Allowlisted domains
- Prevents navigation
- Shows a
<dialog>modal - Opens the destination safely when the user confirms
See the index.js file for the detailed script with comments.
Note: This project leverages the native behavior of <dialog> combined with <form method="dialog">. When a button inside this form is clicked, the dialog closes automatically, streamlining keyboard accessibility and semantic support without extra scripting. The "Continue" button that actually exits the site is set to type="button", ensuring it doesn't trigger the dialog's native close behavior—allowing custom JavaScript to control the external navigation.
- Create your
<dialog>HTML structure and apply the appropriate attributes (see the live Webflow demo above for reference). - Place the dialog markup near the bottom of the page.
- Insert the script after the dialog element so it can properly reference the DOM nodes.
For easier management, consider placing both the dialog and script inside a prominent reusable component (such as a Footer wrapper). If using this approach, ensure the structure remains semantically correct — for example, wrap the actual <footer> inside a parent element that also contains the <dialog> and script.
You may alternatively place the script in:
Project Settings → Custom Code → Before </body>
However, note that:
- Scripts added via Project Settings will not execute in Designer Preview mode
- They only run on the published site
If you need the functionality to work in Preview mode, place the script directly in the Designer via a custom code embed instead.
To prevent specific domains from triggering the confirmation modal (e.g., your own domain), update the IGNORED_DOMAINS set in the script:
const IGNORED_DOMAINS = new Set([
"example.com",
"trusted-partner.org",
]);Use bare hostnames (no protocol).
Any domain included in this set will bypass the confirmation modal, even if it is external to your site.
This implementation relies on the native <dialog> element.
The <dialog> API is supported in all modern browsers, including:
- Chromium-based browsers (Chrome, Edge, Brave)
- Firefox
- Safari (modern versions)
If support for older or legacy browsers is required, consider including polyfills where required.
No special keyboard code is needed.
Pressing Enter on a focused <a> or <button> triggers a click event automatically in browsers — and this script listens for click.
So it works for:
- Mouse
- Touch
- Keyboard (Enter)
- Keyboard (Space on buttons)
This script includes multiple hardening measures:
Only allows:
http:
https:
Blocks:
javascript:data:file:mailto:- etc.
The script does NOT intercept:
- Ctrl + Click
- Cmd + Click
- Shift + Click
- Middle mouse button
These normally open new tabs/windows — and we preserve that behavior.
If you want to intercept those too, remove the modifier checks.
- Compliance-heavy industries (finance, healthcare, gov)
- External resource disclaimers
- Affiliate link warnings
- Outbound tracking control
- Preventing accidental site exits