# Registration Options

In Vue, the registration options are what you pass to the [`v-foresight`](/docs/vue/directive.md) directive or the [`useForesight`](/docs/vue/useForesight.md) composable. The directive or `elementRef` takes care of the element, so there is no `element` option. `callback` is the only required field.

```
<script setup lang="ts">
  import { useForesight } from "@foresightjs/vue"

  const { elementRef } = useForesight({
    callback: () => {
      // Required: Function that executes when interaction is predicted
      console.log("prefetching")
    },
    hitSlop: 50, // slop around the element, making its hitbox bigger
    name: "about-link", // name visible in the debug tools
    meta: {
      route: "/about",
    }, // your custom meta data for analytics
    reactivateAfter: 5 * 60 * 1000, // time for the element to reactivate after the callback has been hit
    enabled: true, // when false the element stays registered but inactive
  })
</script>

<template>
  <a :ref="elementRef" href="/about">About</a>
</template>
```

The directive takes the same options object:

```
<template>
  <button v-foresight="{ callback: handlePrefetch, hitSlop: 50, name: 'prefetch-button' }">
    Hover to prefetch
  </button>
</template>
```

When the options change, both the directive and the composable patch the existing registration in place.

## Registration Parameters[​](#registration-parameters "Direct link to Registration Parameters")

**TypeScript Type:** `ForesightRegisterOptions` or `ForesightRegisterOptionsWithoutElement` if you want to omit the `element`

### Required Parameters[​](#required-parameters "Direct link to Required Parameters")

#### `element`[​](#element "Direct link to element")

* **Type:** `element | NodeListOf<element>`
* **Required:** Yes
* **Description:** The DOM element (or a `NodeList` of elements) to monitor for user interactions. When a `NodeList` is passed, all elements are registered with the same callback and settings.

```
// Single element
const button = document.querySelector("#my-button")

ForesightManager.instance.register({
  element: button,
  callback: () => {
    /* prefetch logic */
  },
})

// Multiple elements via NodeList
const navLinks = document.querySelectorAll("nav a")

ForesightManager.instance.register({
  element: navLinks,
  callback: state => {
    /* state identifies which element triggered */
  },
})
```

***

#### `callback`[​](#callback "Direct link to callback")

* **Type:** `(state: ForesightElementState) => void`
* **Required:** Yes
* **Description:** Function that executes when interaction is predicted or occurs. This is where your prefetching logic goes. The callback receives the [`ForesightElementState`](#registration-return-value) of the element that triggered it, which is especially useful when registering multiple elements with a shared callback.
* **Note:** If you await your prefetch logic the `callbackCompleted` event will show you how long your prefetch took to run.

```
ForesightManager.instance.register({
  element: myElement,
  callback: state => {
    console.log(`Triggered ${state.name}`)
    // prefetch logic
  },
})
```

***

### Optional Parameters[​](#optional-parameters "Direct link to Optional Parameters")

#### `hitSlop`[​](#hitslop "Direct link to hitslop")

* **Type:** `number | Rect`
* **Required:** No
* **Default:** Uses `defaultHitSlop` from global settings (which is 0 if not set)
* **Description:** Fully invisible "slop" around the element that increases the hover hitbox.

```
// Uniform hit slop (20px on all sides)
ForesightManager.instance.register({
  element: myElement,
  callback: () => {},
  hitSlop: 20,
})

// Custom hit slop for each side
ForesightManager.instance.register({
  element: myElement,
  callback: () => {},
  hitSlop: {
    top: 10,
    left: 50,
    right: 50,
    bottom: 100,
  },
})
```

***

#### `name`[​](#name "Direct link to name")

* **Type:** `string`
* **Required:** No
* **Default:** `element.id` or `"unnamed"` if no id
* **Description:** A descriptive name for the element, useful for development tools and debugging.

```
ForesightManager.instance.register({
  element: myElement,
  callback: () => {
    /* logic */
  },
  name: "Product Navigation Button", // Helpful for debugging
})
```

***

#### `reactivateAfter`[​](#reactivateafter "Direct link to reactivateafter")

* **Type:** `number`
* **Required:** No
* **Default:** `Infinity`
* **Description:** Time in milliseconds after which the callback can be fired again. Set to `Infinity` to prevent callback from firing again after first execution.
* **Note:** Even though `ForesightJS` doesn't store any data, you can set this to the same time as your data would become `stale` normally. In most cases you can just leave this on the default value, as it will get reset on page refresh/rerouting anyways.

```
ForesightManager.instance.register({
  element: myElement,
  callback: () => {},
  reactivateAfter: 5 * 60 * 1000, // 5 minutes
})
```

***

#### `meta`[​](#meta "Direct link to meta")

* **Type:** `Record<string, unknown>`
* **Required:** No
* **Default:** `{}`
* **Description:** Stores additional information about the registered element. Visible in all element-related events and in the devtools.

```
ForesightManager.instance.register({
  element: productLink,
  callback: () => {},
  meta: {
    route: "/about",
    section: "main",
    category: "content",
  },
})
```

***

#### `enabled`[​](#enabled "Direct link to enabled")

* **Type:** `boolean`
* **Required:** No
* **Default:** `true`
* **Description:** When `false` the element stays registered but inactive: it is excluded from prediction and never fires its callback.

```
ForesightManager.instance.register({
  element: myElement,
  callback: () => {},
  enabled: userWantsPrefetching, // toggle prediction without unregistering
})
```

## Registration Return Value[​](#registration-return-value "Direct link to Registration Return Value")

The `register()` method returns the full `ForesightElementState` snapshot of the element at registration time, plus five functions: `unregister()`, `subscribe(listener)`, `getSnapshot()`, `subscribeToBounds(listener)`, and `getBounds()`. When a single element is passed, it returns a `ForesightRegisterResult`. When a `NodeList` is passed, it returns `ForesightRegisterResult[]`.

**TypeScript Type:** `ForesightRegisterResult` or `ForesightRegisterResult[]`

```
// Single element returns ForesightRegisterResult
const { unregister, subscribe, getSnapshot, isLimitedConnection } =
  ForesightManager.instance.register({
    element: myElement,
    callback: () => {},
  })

// NodeList returns ForesightRegisterResult[]
const results = ForesightManager.instance.register({
  element: document.querySelectorAll(".my-elements"),
  callback: () => {},
})
```

***

### Returned Functions[​](#returned-functions "Direct link to Returned Functions")

#### `unregister()`[​](#unregister "Direct link to unregister")

Removes the element from `ForesightManager`'s tracking. Call this when you permanently remove the element from the DOM, see [unregister](/docs/debugging/static-properties.md#foresightmanagerinstanceunregisterelement-reason).

#### `subscribe(listener)`[​](#subscribelistener "Direct link to subscribelistener")

Subscribes to logical state changes for this element. The listener is called every time the state snapshot is replaced - never for geometry-only changes during scroll/resize, which live on the separate bounds channel (`subscribeToBounds`). Returns an unsubscribe function. Together with `getSnapshot` this makes the state usable as an external store without any scroll-induced re-renders.

#### `getSnapshot()`[​](#getsnapshot "Direct link to getsnapshot")

Returns the current immutable `ForesightElementState` snapshot for this element. The snapshot reference is replaced (never mutated) on every logical change, so the properties spread on the return value itself are only current as of registration; use `getSnapshot()` (optionally with `subscribe`) for the up-to-date state.

#### `subscribeToBounds(listener)`[​](#subscribetoboundslistener "Direct link to subscribetoboundslistener")

Subscribes to geometry changes for this element. The listener is called every time the element's position or size changes, which is every scroll/resize tick while the element is visible. Returns an unsubscribe function.

#### `getBounds()`[​](#getbounds "Direct link to getbounds")

Returns the current immutable `ElementBounds` snapshot for this element: its measured `originalRect` and the hitSlop-expanded `expandedRect` used for interaction detection.

***

### State Fields[​](#state-fields "Direct link to State Fields")

The `ForesightElementState` fields, also passed to your [`callback`](#callback):

| Field                        | Type                                | Description                                                                                                                                                                                                                                                             |
| ---------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                         | `string`                            | Unique identifier assigned during registration.                                                                                                                                                                                                                         |
| `name`                       | `string`                            | Human-readable name for debugging, set via the [`name`](#name) option.                                                                                                                                                                                                  |
| `meta`                       | `Record<string, unknown>`           | Arbitrary user-supplied metadata, set via the [`meta`](#meta) option.                                                                                                                                                                                                   |
| `hitSlop`                    | `Exclude<HitSlop, number>`          | The normalized hit slop applied to this element, set via the [`hitSlop`](#hitslop) option. The element's rects are not part of the state, read them via `getBounds()`.                                                                                                  |
| `isRegistered`               | `boolean`                           | Whether the element is currently tracked by the manager. Stays `true` from registration until it is explicitly unregistered. Detaching the element from the DOM does **not** unregister it: it is parked (kept registered but inactive) and resumes when it reconnects. |
| `isActive`                   | `boolean`                           | Whether the element is currently eligible to fire its callback. `false` when the element is disabled (`isEnabled: false`), on a limited connection, or parked (`isParked: true`).                                                                                       |
| `isParked`                   | `boolean`                           | `true` while the element is detached from the DOM and parked: kept registered but inactive. Becomes `false` again when the element reconnects and resumes.                                                                                                              |
| `isEnabled`                  | `boolean`                           | Whether prediction is enabled for this element, set via the [`enabled`](#enabled) option. When `false` the element stays registered but inactive.                                                                                                                       |
| `isPredicted`                | `boolean`                           | `true` once the element's callback has been triggered by a prediction hit. Stays `true` until the element is reactivated or unregistered.                                                                                                                               |
| `isCallbackRunning`          | `boolean`                           | `true` while the callback is executing (between invocation and completion). The callback is awaited, so this stays `true` for async callbacks until they resolve or reject.                                                                                             |
| `isLimitedConnection`        | `boolean`                           | `true` when the user's connection is slower than the configured `minimumConnectionType` global setting (defaults to `"3g"`) or data saver is enabled. The element is still registered, but stays inactive so no data is consumed.                                       |
| `isIntersectingWithViewport` | `boolean`                           | Whether the element is currently intersecting the viewport.                                                                                                                                                                                                             |
| `hitCount`                   | `number`                            | Number of times the callback has fired for this element.                                                                                                                                                                                                                |
| `registerCount`              | `number`                            | Number of times this element has been (re)registered.                                                                                                                                                                                                                   |
| `durationMs`                 | `number \| undefined`               | Duration in ms of the most recent callback run.                                                                                                                                                                                                                         |
| `status`                     | `"success" \| "error" \| undefined` | Status of the most recently completed callback.                                                                                                                                                                                                                         |
| `error`                      | `string \| null`                    | Error message from the most recently completed callback.                                                                                                                                                                                                                |
| `reactivateAfter`            | `number`                            | Time in ms after which the callback can be fired again (`Infinity` = never), set via the [`reactivateAfter`](#reactivateafter) option.                                                                                                                                  |

note

The `isLimitedConnection` detection relies on the [Network Information API](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation) which is not supported in all major browsers. When the API is not available, ForesightJS treats the connection as unlimited.
