React Form Wizard
Feature demos

Persistence & URL Sync

Type a note and reload this page — both the answer and the step come back.

Data goes to sessionStorage["docs-persist"], and the active step is mirrored into ?docs-step=. Reload this page to see both restored.

Form wizard with 3 steps. Currently on step 1.

Resumable wizard

Step 1 of 3: Write

Code

PersistedWizard.tsx
"use client";

import React from "react";
import FormWizard, {
  type FormWizardMethods,
  type FormWizardSchema,
} from "react-form-wizard-component";
import "react-form-wizard-component/styles.css";

export default function PersistedWizard() {
  const wizardRef = React.useRef<FormWizardMethods>(null);

  const schema: FormWizardSchema = {
    initialData: { note: "" },
    steps: [
      {
        id: "write",
        title: "Write",
        content: ({ data }) => (
          <label className="pw-field">
            Note
            <input
              value={String(data.note ?? "")}
              onChange={(e) =>
                wizardRef.current?.updateData({ note: e.target.value })
              }
              placeholder="Type, then reload the page"
            />
          </label>
        ),
      },
      {
        id: "confirm",
        title: "Confirm",
        content: ({ data }) => <p>Saved note: “{String(data.note ?? "")}”</p>,
      },
      {
        id: "done",
        title: "Done",
        content: <p>Still here after a refresh.</p>,
      },
    ],
  };

  return (
    <>
      <p className="pw-note">
        Data goes to <code>sessionStorage["docs-persist"]</code>, and the active
        step is mirrored into <code>?docs-step=</code>.{" "}
        <strong>Reload this page to see both restored.</strong>
      </p>

      <FormWizard
        ref={wizardRef}
        title="Resumable wizard"
        schema={schema}
        persist={{ key: "docs-persist", storage: "session" }}
        syncToUrl={{ param: "docs-step" }}
        onComplete={() => {
          // reset() returns to the start and clears the persisted payload.
          wizardRef.current?.reset();
        }}
      />

      <style>{`
        .pw-note { color: #5c6968; font-size: 14px; }
        .pw-field { display: flex; flex-direction: column; gap: 4px; max-width: 320px; }
      `}</style>
    </>
  );
}

On this page