---
title: useOn() / useOnDocument() / useOnWindow() | Tutorial
contributors:
  - manucorporat
  - adamdbradley
  - mrhoodz
  - iancharlesdouglas
updated_at: '2023-06-25T19:43:33Z'
created_at: '2022-08-02T12:07:45Z'
---

Use `useOn()` / `useOnDocument()` / `useOnWindow()` to programmatically set up listeners on host elements. This is useful when you are creating custom APIs and don't have access to place these events in the JSX or if the events are not known ahead of time, such as if they are created based on component props.

Each hook also accepts an optional third argument for listener options:

- `{ passive: true }` for passive listeners such as `touchmove` or `scroll` when the callback does not need to call `preventDefault()`.
- `{ capture: true }` to run the listener in the capture phase.
- `{ preventdefault: true }` to have Qwik call `event.preventDefault()` before your handler runs.
- `{ stoppropagation: true }` to have Qwik call `event.stopPropagation()` before your handler runs.

`preventdefault` and `stoppropagation` mirror the JSX `preventdefault:event` and `stoppropagation:event` attributes. Avoid combining `passive: true` with `preventdefault: true`, since passive listeners cannot prevent the browser default.

Most of the time, JSX event handlers are still the best choice:

```tsx
<button onClick$={() => count.value++}>Increment</button>
```

Reach for `useOn()` when the event registration should live inside a reusable hook or helper instead of inside the template. In that case, `useOn()` lets you keep the listener lazy and colocated with the logic that needs it.

### When To Use Each Hook

- `useOn()` attaches to the current component's host element.
- `useOnDocument()` listens on `document`.
- `useOnWindow()` listens on `window`.

This means `useOn()` is a good fit for component-local behavior, while `useOnDocument()` and `useOnWindow()` are better for global concerns like keyboard shortcuts, resize handling, or document-level pointer tracking.

### Example

This custom hook adds a keyboard shortcut without rendering any markup of its own:

```tsx
import { $, useOnDocument } from '@qwik.dev/core';

export function useEscape(onEscape$: () => void) {
  useOnDocument(
    'keydown',
    $((event) => {
      if ((event as KeyboardEvent).key === 'Escape') {
        onEscape$();
      }
    })
  );
}
```

That is the kind of scenario where `useOn*()` is usually clearer than passing event handlers through several layers of JSX.

### Event Modifiers

The same options work with `useOnDocument()` and `useOnWindow()`:

```tsx
useOn(
  'click',
  $(() => {
    // Runs during capture and stops later bubbling handlers.
  }),
  { capture: true, stoppropagation: true }
);
```

### Example

The example on the right shows how to use `useOn()` method. Duplicate the code to explore how to use `useOnDocument()` / `useOnWindow()` and how they behave differently.
