> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ollie.shop/llms.txt
> Use this file to discover all available pages before exploring further.

# useNavigation

Use this hook when your component must have the final say on whether the shopper can leave the current checkout step. It registers a **step validator**: a function the checkout calls right before it moves forward, including when the shopper clicks the place-order button. Return `true` to let the navigation happen, `false` to block it.

Typical uses are a custom form that has to be complete before shipping, a terms-and-conditions checkbox before payment, or a confirmation prompt before placing the order.

> [!TIP]
>
> **Let your agent build it.** The Ollie Shop skill ships with projects created by `npx create-ollie-shop` and knows how the templates call the validator.
>
> ```text title="Prompt" theme={"system"}
> Block the Continue button until my custom checkbox is checked.
> ```
>
> Don't have the skill yet? [Install it](/ollie-shop/skills.md).

## **Import**

```typescript theme={"system"}
import { useNavigation } from '@ollie-shop/sdk';
```

## **Parameters**

| Parameter | Type | Required | Description |
| - | - | - | - |
| `validator` | `() => boolean` | Yes | Called when the checkout is about to leave the current step. Return `true` to allow it, `false` to block it |

## **Return Value**

| Property | Type | Description |
| - | - | - |
| `unregisterStepValidator` | `() => void` | Removes the validator early. The hook also removes it automatically when the component unmounts |

## **Usage**

```typescript theme={"system"}
const { unregisterStepValidator } = useNavigation(validator);
```

Only **one** validator is active at a time. Registering a new one replaces the previous one, so keep a single gating component per step.

The validator is registered inside an effect that depends on the function you pass. Wrap it in `useCallback` so it is not re-registered on every render.

## **Example**

A terms checkbox that must be ticked before the shopper can continue. The validator reads the latest state through a ref, because the function registered with the checkout is only replaced when its identity changes.

**index.tsx**

```typescript theme={"system"}
import { useCallback, useRef, useState } from 'react';
import { useMessages, useNavigation } from '@ollie-shop/sdk';
import styles from './styles.module.css';

export default function TermsGate() {
  const [accepted, setAccepted] = useState(false);
  const acceptedRef = useRef(accepted);
  acceptedRef.current = accepted;

  const { addMessage } = useMessages();

  const validator = useCallback(() => {
    if (acceptedRef.current) return true;
    addMessage({ type: 'error', content: 'Please accept the terms to continue.' });
    return false;
  }, [addMessage]);

  useNavigation(validator);

  return (
    <label className={styles.gate}>
      <input
        type="checkbox"
        checked={accepted}
        onChange={(event) => setAccepted(event.target.checked)}
      />
      I accept the terms and conditions
    </label>
  );
}
```

**styles.module.css**

```css theme={"system"}
.gate {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 0;
  font-size: 14px;
  cursor: pointer;
}
```

## **Notes**

* The validator runs synchronously. If you need to wait on a request, block with `false`, run the request, and let the shopper continue once it resolves.
* Blocking is silent: the checkout simply does not move. Pair the `false` return with a [message](/ollie-shop/api/useMessages.md) so the shopper knows why.
* The templates' place-order button goes through the same validator, so this is the supported way to gate order placement from a custom component.

## **Related**

* [useMessages](/ollie-shop/api/useMessages.md): tell the shopper why the navigation was blocked
* [useCheckoutSession](/ollie-shop/api/useCheckoutSession.md): read `sessionValidity` when the rule is about missing session data
* [Steps](/ollie-shop/customization/steps.md): define the steps of your checkout


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.