dimah-survey
React bindings

Survey Creator

Bind Creator autosave to the editor draft while keeping publish explicit.

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

npm i @dimah-survey/react survey-creator-core survey-creator-react

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

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.

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

Prop

Type

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.

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

Prop

Type

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

Publish explicitly

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

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.

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.

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

Prop

Type

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

See Survey lifecycle for publish, archive, resume, and compare-and-swap behavior.

On this page