> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://www.openfort.io/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

# `useUI`

Control the Openfort modal: open/close and navigate between views. `open()` picks the screen from the current session — the login screen when there is no user, the wallet-loading screen when a user has no connected wallet yet, and the connected wallet overview otherwise.

## Usage

```tsx
import { useUI } from '@openfort/react';

function Header() {
  const { isOpen, open, close, openProfile, openProviders } = useUI();

  return (
    <>
      <button onClick={openProviders}>Sign in</button>
      <button onClick={openProfile}>Profile</button>
      {isOpen && <button onClick={close}>Close</button>}
    </>
  );
}
```

## Return value

| Property | Type | Description |
| :--- | :--- | :--- |
| `isOpen` | `boolean` | Whether the modal is currently open. |
| `open` | `() => void` | Opens the modal on the screen that matches the session state. |
| `close` | `() => void` | Closes the modal. |
| `setIsOpen` | `(open: boolean) => void` | Opens the modal, or closes it through the same path as `close`. |
| `openProfile` | `() => void` | Connected wallet overview. |
| `openSettings` | `() => void` | Profile screen. |
| `openProviders` | `() => void` | Login screen with the configured auth providers. |
| `openWallets` | `() => void` | External wallet connectors — links to the current user, or connects when there is none. |
| `openSwitchNetworks` | `() => void` | Ethereum network switcher. |
| `openSend` | `(tx?: { to: string; amount: string; asset?: Asset }) => void` | Send flow for the active chain. |
| `openReceive` | `() => void` | Receive screen for the active chain. |
| `openFunding` | `() => void` | Deposit hub. |
| `openBuy` | `() => void` | Buy screen. |
| `openExportKey` | `() => void` | Private key export screen. |

## Prefill the send flow

Pass `to` and `amount` to `openSend` to skip asset, amount, and recipient entry and land straight on the confirmation screen. The prefilled form uses the chain's native token, and on a Solana chain the modal opens the Solana confirmation screen instead of the Ethereum one. Called with no argument, `openSend` opens the full send flow.

```tsx
const { openSend } = useUI();

openSend({ to: '0x2111111111111111111111111111111111111111', amount: '0.01' });
```

## Navigation falls back instead of failing

The `open*` helpers target connected-only screens, and each one is checked against an allowlist for the current connection state. Called while the user is not connected, they route to the login screen rather than throwing — so a "Send" button can call `openSend()` directly and let the modal take the user through auth first.

## Pending signature requests

Opening, closing, or navigating the modal cancels a signature request that is waiting on it. The pending [`useSignMessage`](https://www.openfort.io/docs/products/embedded-wallet/react/wallet/actions/sign-message) call then resolves with a `WalletError` whose `shortMessage` is `Signature request was cancelled.` — branch on it instead of leaving the promise hanging.

```tsx
const result = await signMessage('Hello World');
if ('error' in result) {
  console.error(result.error.shortMessage);
  return;
}
```

## Related

* [UI configuration](https://www.openfort.io/docs/products/embedded-wallet/react/ui/configuration)
* [Sign message](https://www.openfort.io/docs/products/embedded-wallet/react/wallet/actions/sign-message)
* [useOpenfort](https://www.openfort.io/docs/products/embedded-wallet/react/hooks/useOpenfort)
