# Survey Creator (https://survey.dimah.dev/docs/creator)



`useSurveyDraft()` connects a Creator instance to `saveSurvey`. Autosave
replaces `draftJson`; it never changes `publishedJson` or any response
definition.

<CodeBlockTabs defaultValue="npm">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="npm">
      npm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="pnpm">
      pnpm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="yarn">
      yarn
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="bun">
      bun
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="npm">
    ```bash
    npm i @dimah-survey/react survey-creator-core survey-creator-react
    ```
  </CodeBlockTab>

  <CodeBlockTab value="pnpm">
    ```bash
    pnpm add @dimah-survey/react survey-creator-core survey-creator-react
    ```
  </CodeBlockTab>

  <CodeBlockTab value="yarn">
    ```bash
    yarn add @dimah-survey/react survey-creator-core survey-creator-react
    ```
  </CodeBlockTab>

  <CodeBlockTab value="bun">
    ```bash
    bun add @dimah-survey/react survey-creator-core survey-creator-react
    ```
  </CodeBlockTab>
</CodeBlockTabs>

<Callout>
  Publishing is an explicit product action, not an autosave side effect. New
  responses see the draft only after `publishSurvey`.
</Callout>

```tsx title="components/design.tsx"
"use client";

import { useMemo } from "react";
import { createEditorClient, useSurveyDraft } from "@dimah-survey/react";
import { SurveyCreator, SurveyCreatorComponent } from "survey-creator-react";

const editorClient = createEditorClient({ baseURL: "/api/admin/survey" });

export function Design({
  surveyId,
  draftJson,
  updatedAt,
}: {
  surveyId: string;
  draftJson: object;
  updatedAt: string;
}) {
  const creator = useMemo(() => {
    const next = new SurveyCreator();
    next.JSON = draftJson;
    return next;
  }, [draftJson]);

  const { saveError, stale } = useSurveyDraft({
    client: editorClient,
    surveyId,
    creator,
    updatedAt,
  });

  return (
    <>
      {saveError ? <p>{saveError.message}</p> : null}
      {stale ? <p>This draft was saved somewhere else.</p> : null}
      <SurveyCreatorComponent creator={creator} />
    </>
  );
}
```

Load `draftJson` and `updatedAt` on the server with `editor.api.getSurvey`,
then pass both into the client component. `createEditorClient()` defaults to
`/api/admin/survey`.

```ts
import type { UseSurveyDraftOptions } from "@dimah-survey/react";
```

<AutoTypeTable path="packages/react/src/use-survey-draft.ts" name="UseSurveyDraftOptions" />

The hook sets `isAutoSave` and `saveSurveyFunc`. Each save sends
`expectedUpdatedAt` from the loaded survey, then from the last successful
write. A new `updatedAt` prop rebinds that token.

```ts
import type { SurveyDraftBinding } from "@dimah-survey/react";
```

<AutoTypeTable path="packages/react/src/use-survey-draft.ts" name="SurveyDraftBinding" />

Unlike the fill hook, `useSurveyDraft()` has no `reload()` method. Reload the
survey in your application before writing again.

## Publish explicitly [#publish-explicitly]

Autosave must not call `publishSurvey`. Publish copies the current draft onto
`publishedJson` and is an explicit action:

```ts
await editorClient.publishSurvey({ id: surveyId, expectedUpdatedAt });
```

On the server, the equivalent call is
`editor.api.publishSurvey({ body })`. Archive, resume, and settings are editor
calls too. See [Surveys](https://survey.dimah.dev/docs/surveys.md).

## Bind without React state [#bind-without-react-state]

`bindSurveyCreator()` exposes the same binding without React state. Pass
`initialUpdatedAt` from the load that produced the Creator instance. The app
still constructs, renders, and disposes Creator.

```ts
import type { SurveyCreatorActions } from "@dimah-survey/react";
```

<AutoTypeTable path="packages/react/src/bind-survey-creator.ts" name="SurveyCreatorActions" />

`survey-creator-core` and `survey-creator-react` stay in your application.
They are not dependencies of `@dimah-survey/react`.

See [Survey lifecycle](https://survey.dimah.dev/docs/surveys.md) for publish, archive, resume, and
compare-and-swap behavior.
