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

# React

> Writing a hug's page in React with useHug, HugRoot and DefaultView.

Hugs

`@getcliqio/hug-frontend/react` gives React the same answer state as [`mount_hug`](https://docs.getcliq.io/hugs/mount-hug): the same
starting answer, `set` and `replace`, checks, Submit label and summary. Scaffold one with:

```bash theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
cliq hug new review-batch --react
```

React is compiled into the bundle like any library (React 18 or later). [`review-batch-react`](https://github.com/getcliqio/cliq/tree/main/examples/hugs/review-batch-react)
is the tutorial's hug in React.

> [!NOTE]
>
> While `@getcliqio/hug-frontend` is linked from a checkout (`file:`) rather than installed from npm, the build can pick
> up two copies of React — the checkout's and yours ("Cannot read properties of null (reading 'useState')"). Alias React
> to yours in `build.mjs` (`alias: { react: …, 'react-dom': … }`) and dedupe it in tests (`resolve.dedupe`), as
> `review-batch-react` does. Installed from npm, React is a peer dependency and there is one copy.

***

## `<HugRoot>`

The whole page: it connects, then draws `edit` or `view` by mode, or an error panel. If drawing throws, the page
shows "This hug failed to draw" with the message (and logs the error) instead of going blank, as `mount_hug` does; the
panel clears when the mode or the answer shown changes.

```tsx src/main.tsx (abridged) theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
import { createRoot } from 'react-dom/client';
import { HugRoot } from '@getcliqio/hug-frontend/react';
import '@getcliqio/hug-frontend/ui';
import review_batch from '../hug';

createRoot(document.getElementById('app')!).render(
    <HugRoot
        definition={review_batch}
        initial={(p) => ({ verdicts: p.documents.map((d) => ({ id: d.id, ok: true })) })}
        submit={(v) => (v.verdicts.every((x) => x.ok) ? 'Approve all' : 'Send verdicts')}
        edit={(s) => <Editor state={s} />}
    />,
);
```

| Prop | |
| - | - |
| `definition` | **Required.** The hug's definition |
| `edit(state)` | **Required.** Draws the editor |
| `view(answer, state)` | Draws a submitted answer (default `<DefaultView>`) |
| `initial`, `submit`, `summary` | As for `mount_hug` |
| `loading` | Shown while connecting |

## `useHug`

For your own layout, `useHug(definition, { initial, submit, summary })` returns the state as it changes:

```tsx theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
import { DefaultView, useHug } from '@getcliqio/hug-frontend/react';

function Page() {
    const s = useHug(review_batch, { initial: (p) => ({ verdicts: p.documents.map((d) => ({ id: d.id, ok: true })) }) });
    if (s.status === 'connecting') return null;
    if (s.status === 'error') return <p role="alert">{s.error.message}</p>;
    if (s.mode === 'view') return <DefaultView definition={review_batch} state={s} />;
    return <Editor state={s} />;
}
```

`status` is `connecting`, `error` (with `error`), or `ready`, with:

| | |
| - | - |
| `params`, `value`, `mode` | What the Hug was asked, the answer so far, `answer` or `view` |
| `set(path, v)`, `replace(v)` | Change the answer ([how](https://docs.getcliq.io/hugs/mount-hug.md#changing-the-answer)) |
| `problems`, `problem_list`, `valid` | The definition's verdict |
| `viewing` | In view mode, the answer to draw |
| `params_problems` | Set when the Hug's params don't fit the definition |
| `hug` | The [runtime API](https://docs.getcliq.io/hugs/reference/runtime-api.md) |

## Controls

Use ordinary React controls and call `set` on change — this is what `cliq hug new --react` scaffolds:

```tsx theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
edit={({ params, value, set, problems }) => (
    <>
        <p>{params.question}</p>
        <label>
            <input type="checkbox" checked={value.ok} onChange={(e) => set('ok', e.target.checked)} /> Ready
        </label>
        {!value.ok && (
            <div>
                <textarea aria-label="Why not?" value={value.note ?? ''} onChange={(e) => set('note', e.target.value)} />
                {problems['note'] && <div role="alert">{problems['note']}</div>}
            </div>
        )}
    </>
)}
```

Import `@getcliqio/hug-frontend/ui` for the Hub's font and colours (`--cliq-*` variables) even without its elements.
The [UI kit](https://docs.getcliq.io/hugs/ui-kit.md)'s elements are web components: in React, set their properties (`.value`, `.choices`,
`.ref`) and listen for their `change` event through a ref.

## `<DefaultView>`

`<DefaultView definition state answer? />` draws an answer from the definition, as `mount_hug`'s default view does.
`answer` defaults to the one the host is showing, else the viewer's own.


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