Exit Intent

A protection system that detects when users attempt to leave the page and shows confirmation dialogs to prevent accidental navigation.

Preview

Exit Intent Protection Demo
Test the exit intent protection system with these examples

Protection Status

External Links
Active
Page Refresh/Close
Disabled

Link Protection Controls

Browser Refresh/Close Controls

How it works:

  • External links show a confirmation dialog before leaving
  • Page refresh/close shows browser confirmation (when enabled)
  • Links with data-no-confirm skip confirmation
  • Links opening in new tabs skip confirmation
  • All controls use the same global state

Installation

Use the CLI to add this component to your project.

npx shadcn@latest add https://ui.nyxhora.com/r/exit-intent.json

Provider Setup

tsx
21 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// In your layout.tsx
import { ExitIntentProvider } from "@/registry/providers/exit-intent-provider"

export const metadata = generateComponentMetadata({
    name: "Exit Intent",
    description: "A protection system that detects when users attempt to leave the page and shows confirmation dialogs to prevent accidental navigation.",
    category: "Overlay",
});


export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        <ExitIntentProvider>
          {children}
        </ExitIntentProvider>
      </body>
    </html>
  )
}

Basic Usage

tsx
25 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { useExitIntent } from "@/registry/providers/exit-intent-provider"

export default function MyComponent() {
  const { 
    isActive,                // Link protection status
    isBeforeUnloadActive,    // Browser refresh/close protection status
    enableExitIntent,        // Enable link protection
    disableExitIntent,       // Disable link protection
    temporaryDisable,        // Temporarily disable link protection
    enableBeforeUnload,      // Enable browser warning
    disableBeforeUnload,     // Disable browser warning
    setBeforeUnloadActive,   // Set browser warning state
  } = useExitIntent();

  return (
    <div>
      <p>Link protection: {isActive ? "active" : "disabled"}</p>
      <p>Browser warning: {isBeforeUnloadActive ? "active" : "disabled"}</p>
      <button onClick={enableExitIntent}>Enable Links</button>
      <button onClick={disableExitIntent}>Disable Links</button>
      <button onClick={enableBeforeUnload}>Enable Browser Warning</button>
      <button onClick={disableBeforeUnload}>Disable Browser Warning</button>
    </div>
  )
}

Examples

Status Indicator

Display the current protection status. Changes here reflect globally across all components.

Link protection is active
Refresh/close warning is disabled

Link Protection Controls

Control external link protection. Try enabling/disabling here and see the status update above.

Browser Refresh/Close Controls

Control the browser's native beforeunload warning. When enabled, users see a confirmation when trying to close or refresh the page.

Browser warning is disabled

External Links (with dialog)

Standard external links will show a confirmation dialog before navigating away.

Bypassing Confirmation

Use special attributes to bypass the confirmation dialog for trusted links.

Form Protection Pattern

A common pattern: enable protection when user starts editing, disable when they submit successfully.

UnprotectedSimulated form

API Reference

useExitIntent Hook

Props

PropTypeDefaultDescription
isActivebooleantrueCurrent state of external link protection
isBeforeUnloadActivebooleantrueCurrent state of browser refresh/close protection
enableExitIntent() => void-Enable external link protection
disableExitIntent() => void-Disable external link protection
temporaryDisable(duration: number) => void-Temporarily disable link protection for specified duration (in ms)
enableBeforeUnload() => void-Enable browser refresh/close warning
disableBeforeUnload() => void-Disable browser refresh/close warning
setBeforeUnloadActive(active: boolean) => void-Set browser warning state directly

Link Attributes

Props

PropTypeDefaultDescription
data-no-confirmattribute-Add this attribute to any link to bypass the exit confirmation dialog
target="_blank"attribute-Links opening in new tabs automatically bypass confirmation

Best Practices

Protect important workflows

Enable both link and browser protection on pages with unsaved changes, forms, or checkout flows.

Use separate controls wisely

You can enable link protection without browser warnings, or vice versa, depending on your UX needs.

Disable after successful actions

Always disable protection after the user has saved their work or completed the workflow.

Use data-no-confirm for trusted links

Add data-no-confirm to trusted external links like documentation or social media.

Global State

Note: All components using useExitIntent share the same global state. When you enable or disable protection from any component, it affects the entire application. This makes it perfect for coordinating protection across different parts of your app.