# Stepper Studio

> Stepper Studio (https://stepperize.com/studio) designs a multi-step React flow and generates its source on `@stepperize/react` and shadcn/ui. A flow is one JSON config. Encode it to get a share link and a shadcn registry item that installs the generated files with the shadcn CLI.

Use this guide to create flows for a user without the visual editor: write a config, encode it, and hand over the install command or the Studio link. The full Stepperize docs are at https://stepperize.com/llms.txt.

## Workflow for agents

1. Write a config object (reference below; JSON Schema at https://stepperize.com/r/studio/schema.json).
2. Encode it: base64url of the UTF-8 JSON, without `=` padding.
3. Install it in the user's project: `npx shadcn@latest add https://stepperize.com/r/studio/<encoded>.json`. The project needs shadcn/ui set up (`components.json`); the CLI adds the generated files, the npm packages and the shadcn/ui components they import.
4. Or let the user see and tweak it first: `https://stepperize.com/studio?c=<encoded>`.
5. To read the generated code without installing, GET the registry URL: it returns a shadcn `registry:block` item whose `files[].content` holds every file, plus `dependencies` and `registryDependencies`.

An invalid config returns HTTP 400 with a JSON `error`. Out-of-range or impossible combinations are repaired, not rejected (see Compatibility).

### Encoding

```ts
const encoded = btoa(String.fromCharCode(...new TextEncoder().encode(JSON.stringify(config))))
	.replace(/\+/g, "-")
	.replace(/\//g, "_")
	.replace(/=+$/, "");
```

```python
import base64, json
encoded = base64.urlsafe_b64encode(json.dumps(config).encode("utf-8")).decode().rstrip("=")
```

```bash
printf '%s' "$CONFIG_JSON" | base64 | tr '+/' '-_' | tr -d '=\n'
```

## Config reference

| Key | Values |
| --- | --- |
| `name` | string, 1 to 40 characters. Becomes the folder (`kebab-case`), the definition variable (`camelCase`) and the component prefix (`PascalCase`). |
| `base` | `radix` (Radix UI: radix-ui), `base` (Base UI: @base-ui/react), `aria` (React Aria: react-aria-components). Match the `base` of the project's shadcn/ui components (the `style` in components.json starts with it, e.g. `radix-nova`). Defaults to `radix`. |
| `framework` | `nextjs` (Next.js: App Router), `tanstack-start` (TanStack Start: File routes), `react-router` (React Router: Framework mode), `vite` (Vite: No router) |
| `navigation` | `component` (Component: Drop it anywhere. State lives in memory.), `search-params` (Search params: One page. The step lives in ?step=.), `routes` (Routes: One URL per step. A layout keeps the data.) |
| `layout` | `horizontal` (Horizontal: Numbered steps in a row), `vertical` (Vertical: A rail beside the content), `progress` (Progress: One bar, no step list), `segmented` (Segmented: Tabs for short flows), `circular` (Circular: A ring with the count), `breadcrumb` (Breadcrumb: A trail with chevrons) |
| `indicator` | `number` (Number: Every marker shows its step number, done or not.), `check` (Check: Numbers until a step is complete, then a check. You see it after moving past a step.), `dot` (Dot: A dot instead of a number. Color alone tells done, current and next apart.) |
| `form` | `react-hook-form` (React Hook Form: react-hook-form), `tanstack-form` (TanStack Form: @tanstack/react-form), `conform` (Conform: @conform-to/react), `native` (Native form: FormData + validate()) |
| `validation` | `zod` (Zod: zod), `valibot` (Valibot: valibot), `arktype` (ArkType: arktype), `none` (None: Untyped data). Any Standard Schema library works with Stepperize. |
| `behavior` | object with booleans `linear`, `guard`, `persist`, `keepMounted`: linear navigation, validate before moving forward (`beforeStepChange`), save a draft to localStorage, keep every step mounted (`Stepper.Content forceMount`). |
| `steps` | 2 to 8 steps: `{ title, description, fields }`. |

### Steps

- `title`: 1 to 60 characters. Becomes the step id in `camelCase` (duplicates get a numeric suffix).
- `description`: up to 120 characters, may be empty.
- `fields`: up to 8 fields. A step without fields renders your own content; the last step without fields becomes a summary of every answer with Edit links.

### Fields

Each field is `{ label, type, required, options?, min?, max? }`. `label` is 1 to 60 characters and becomes the field name in `camelCase`. `options` (1 to 8 strings, up to 40 characters each) applies to choice types; `min`/`max` (integers) apply to `slider`. Extras on other types are dropped.

| type | Group | shadcn/ui control | Value when required |
| --- | --- | --- | --- |
| `text` | Text | Input | non-empty string |
| `email` | Text | Input type=email | string, valid email |
| `password` | Text | Input type=password | non-empty string |
| `tel` | Text | Input type=tel | string matching `/^\+?[\d\s().-]{7,20}$/` |
| `url` | Text | Input type=url | string, valid url |
| `textarea` | Text | Textarea | non-empty string |
| `number` | Number | Input type=number | number above 0 |
| `slider` | Number | Slider | number within `min`..`max` (always required) |
| `select` | Choice | Select | one of `options` |
| `radio` | Choice | RadioGroup | one of `options` |
| `checkboxes` | Choice | Checkbox per option | array of `options`, at least one when required |
| `checkbox` | Toggle | Checkbox | boolean; required means it must be on |
| `switch` | Toggle | Switch | boolean; required means it must be on |
| `date` | Date & time | DatePicker (Popover + Calendar) | ISO date string `YYYY-MM-DD` |
| `time` | Date & time | Input type=time | string matching `/^([01]\d\|2[0-3]):[0-5]\d$/` |
| `otp` | Text | InputOTP (6 slots) | string matching `/^\d{6}$/` |

Optional text-like fields also accept an empty string; optional choices accept `""` or no value.

## Compatibility

Some combinations are unavailable. The Studio disables them, and the registry endpoint repairs a config that asks for one (routes fall back to search params, validation to Zod, impossible behaviors turn off):

- `navigation: "routes"` with `framework: "vite"`: Plain Vite has no router. Use search params or a component.
- `validation: "arktype"` with `form: "conform"`: Conform has no ArkType adapter.
- `validation: "none"` with `form: "conform"`: Conform parses submissions with a schema.
- `behavior.guard: true` with `validation: "none"`: Needs a validation library.
- `behavior.keepMounted: true` with `navigation: "routes"`: Each step is its own route.

## Generated files

Every flow lives in `components/stepperize/<slug>/`: the flow component, its navigation (`<slug>-nav.tsx`), the step switcher (`<slug>-step-content.tsx`), `definition.ts` (`defineStepper`), `steps.ts` (plain step data, safe to import from server code), `schemas.ts` when validated, and one component per step in `steps/`. Optional helpers appear when needed: `date-picker.tsx`, `progress-ring.tsx`, `use-saved-draft.ts`, `use-step-param.ts`.

The flow component is router-agnostic. In URL modes it takes `step`, `onStepChange` and `onInvalidStep`, and only the route files below import a router:

| Framework | Navigation | Route files |
| --- | --- | --- |
| Next.js | Component | none: render the flow component |
| Next.js | Search params | `app/checkout/page.tsx`, `app/checkout/checkout-client.tsx` |
| Next.js | Routes | `app/checkout/layout.tsx`, `app/checkout/page.tsx`, `app/checkout/[step]/page.tsx` |
| TanStack Start | Component | none: render the flow component |
| TanStack Start | Search params | `src/routes/checkout.tsx` |
| TanStack Start | Routes | `src/routes/checkout.tsx`, `src/routes/checkout.index.tsx`, `src/routes/checkout.$step.tsx` |
| React Router | Component | none: render the flow component |
| React Router | Search params | `app/routes/checkout.tsx` |
| React Router | Routes | `app/routes/checkout.tsx`, `app/routes/checkout._index.tsx`, `app/routes/checkout.$step.tsx` |
| Vite | Component | none: render the flow component |
| Vite | Search params | `components/stepperize/checkout/checkout-page.tsx` |
| Vite | Routes | Plain Vite has no router. Use search params or a component. |

## Example

A flow written from scratch:

```json
{
  "name": "Team signup",
  "base": "radix",
  "framework": "nextjs",
  "navigation": "search-params",
  "layout": "horizontal",
  "form": "react-hook-form",
  "validation": "zod",
  "indicator": "check",
  "behavior": {
    "linear": true,
    "guard": true,
    "persist": true,
    "keepMounted": false
  },
  "steps": [
    {
      "title": "Account",
      "description": "Who is signing up?",
      "fields": [
        {
          "label": "Full name",
          "type": "text",
          "required": true
        },
        {
          "label": "Work email",
          "type": "email",
          "required": true
        },
        {
          "label": "Password",
          "type": "password",
          "required": true
        }
      ]
    },
    {
      "title": "Team",
      "description": "Tell us about your team.",
      "fields": [
        {
          "label": "Plan",
          "type": "radio",
          "required": true,
          "options": [
            "Starter",
            "Team",
            "Enterprise"
          ]
        },
        {
          "label": "Seats",
          "type": "slider",
          "required": true,
          "min": 1,
          "max": 50
        },
        {
          "label": "Notify me about product updates",
          "type": "switch",
          "required": false
        }
      ]
    },
    {
      "title": "Review",
      "description": "Confirm and create the team.",
      "fields": []
    }
  ]
}
```

- Studio: https://stepperize.com/studio?c=eyJuYW1lIjoiVGVhbSBzaWdudXAiLCJiYXNlIjoicmFkaXgiLCJmcmFtZXdvcmsiOiJuZXh0anMiLCJuYXZpZ2F0aW9uIjoic2VhcmNoLXBhcmFtcyIsImxheW91dCI6Imhvcml6b250YWwiLCJmb3JtIjoicmVhY3QtaG9vay1mb3JtIiwidmFsaWRhdGlvbiI6InpvZCIsImluZGljYXRvciI6ImNoZWNrIiwiYmVoYXZpb3IiOnsibGluZWFyIjp0cnVlLCJndWFyZCI6dHJ1ZSwicGVyc2lzdCI6dHJ1ZSwia2VlcE1vdW50ZWQiOmZhbHNlfSwic3RlcHMiOlt7InRpdGxlIjoiQWNjb3VudCIsImRlc2NyaXB0aW9uIjoiV2hvIGlzIHNpZ25pbmcgdXA_IiwiZmllbGRzIjpbeyJsYWJlbCI6IkZ1bGwgbmFtZSIsInR5cGUiOiJ0ZXh0IiwicmVxdWlyZWQiOnRydWV9LHsibGFiZWwiOiJXb3JrIGVtYWlsIiwidHlwZSI6ImVtYWlsIiwicmVxdWlyZWQiOnRydWV9LHsibGFiZWwiOiJQYXNzd29yZCIsInR5cGUiOiJwYXNzd29yZCIsInJlcXVpcmVkIjp0cnVlfV19LHsidGl0bGUiOiJUZWFtIiwiZGVzY3JpcHRpb24iOiJUZWxsIHVzIGFib3V0IHlvdXIgdGVhbS4iLCJmaWVsZHMiOlt7ImxhYmVsIjoiUGxhbiIsInR5cGUiOiJyYWRpbyIsInJlcXVpcmVkIjp0cnVlLCJvcHRpb25zIjpbIlN0YXJ0ZXIiLCJUZWFtIiwiRW50ZXJwcmlzZSJdfSx7ImxhYmVsIjoiU2VhdHMiLCJ0eXBlIjoic2xpZGVyIiwicmVxdWlyZWQiOnRydWUsIm1pbiI6MSwibWF4Ijo1MH0seyJsYWJlbCI6Ik5vdGlmeSBtZSBhYm91dCBwcm9kdWN0IHVwZGF0ZXMiLCJ0eXBlIjoic3dpdGNoIiwicmVxdWlyZWQiOmZhbHNlfV19LHsidGl0bGUiOiJSZXZpZXciLCJkZXNjcmlwdGlvbiI6IkNvbmZpcm0gYW5kIGNyZWF0ZSB0aGUgdGVhbS4iLCJmaWVsZHMiOltdfV19
- Install: `npx shadcn@latest add https://stepperize.com/r/studio/eyJuYW1lIjoiVGVhbSBzaWdudXAiLCJiYXNlIjoicmFkaXgiLCJmcmFtZXdvcmsiOiJuZXh0anMiLCJuYXZpZ2F0aW9uIjoic2VhcmNoLXBhcmFtcyIsImxheW91dCI6Imhvcml6b250YWwiLCJmb3JtIjoicmVhY3QtaG9vay1mb3JtIiwidmFsaWRhdGlvbiI6InpvZCIsImluZGljYXRvciI6ImNoZWNrIiwiYmVoYXZpb3IiOnsibGluZWFyIjp0cnVlLCJndWFyZCI6dHJ1ZSwicGVyc2lzdCI6dHJ1ZSwia2VlcE1vdW50ZWQiOmZhbHNlfSwic3RlcHMiOlt7InRpdGxlIjoiQWNjb3VudCIsImRlc2NyaXB0aW9uIjoiV2hvIGlzIHNpZ25pbmcgdXA_IiwiZmllbGRzIjpbeyJsYWJlbCI6IkZ1bGwgbmFtZSIsInR5cGUiOiJ0ZXh0IiwicmVxdWlyZWQiOnRydWV9LHsibGFiZWwiOiJXb3JrIGVtYWlsIiwidHlwZSI6ImVtYWlsIiwicmVxdWlyZWQiOnRydWV9LHsibGFiZWwiOiJQYXNzd29yZCIsInR5cGUiOiJwYXNzd29yZCIsInJlcXVpcmVkIjp0cnVlfV19LHsidGl0bGUiOiJUZWFtIiwiZGVzY3JpcHRpb24iOiJUZWxsIHVzIGFib3V0IHlvdXIgdGVhbS4iLCJmaWVsZHMiOlt7ImxhYmVsIjoiUGxhbiIsInR5cGUiOiJyYWRpbyIsInJlcXVpcmVkIjp0cnVlLCJvcHRpb25zIjpbIlN0YXJ0ZXIiLCJUZWFtIiwiRW50ZXJwcmlzZSJdfSx7ImxhYmVsIjoiU2VhdHMiLCJ0eXBlIjoic2xpZGVyIiwicmVxdWlyZWQiOnRydWUsIm1pbiI6MSwibWF4Ijo1MH0seyJsYWJlbCI6Ik5vdGlmeSBtZSBhYm91dCBwcm9kdWN0IHVwZGF0ZXMiLCJ0eXBlIjoic3dpdGNoIiwicmVxdWlyZWQiOmZhbHNlfV19LHsidGl0bGUiOiJSZXZpZXciLCJkZXNjcmlwdGlvbiI6IkNvbmZpcm0gYW5kIGNyZWF0ZSB0aGUgdGVhbS4iLCJmaWVsZHMiOltdfV19.json`
- Packages: `@stepperize/react@^8.0.0`, `react-hook-form`, `@hookform/resolvers`, `zod@^4`, `lucide-react`
- shadcn/ui components: `button`, `field`, `input`, `radio-group`, `slider`, `switch`
- Files: `components/stepperize/team-signup/team-signup-flow.tsx`, `components/stepperize/team-signup/team-signup-nav.tsx`, `components/stepperize/team-signup/team-signup-step-content.tsx`, `components/stepperize/team-signup/definition.ts`, `components/stepperize/team-signup/steps.ts`, `components/stepperize/team-signup/schemas.ts`, `components/stepperize/team-signup/steps/account.tsx`, `components/stepperize/team-signup/steps/team.tsx`, `components/stepperize/team-signup/steps/review.tsx`, `components/stepperize/team-signup/use-saved-draft.ts`, `app/team-signup/page.tsx`, `app/team-signup/team-signup-client.tsx`
- Usage: Open /team-signup?step=account. Back and forward move between steps.

Encoded, the config is 1152 characters; links stay well under the 12000-character limit for flows of any allowed size.

## Presets

Ready-made flows the Studio starts from. Each link opens it in the Studio; each command installs it as is.

### Checkout

Shipping (Full name: text, Email: email, Address: text, Country: select, Delivery: radio) → Payment (Cardholder: text, Card number: text, Save card for next time: switch) → Review.

- Studio: https://stepperize.com/studio?preset=checkout
- Install: `npx shadcn@latest add https://stepperize.com/r/studio/eyJiYXNlIjoicmFkaXgiLCJmcmFtZXdvcmsiOiJuZXh0anMiLCJuYXZpZ2F0aW9uIjoic2VhcmNoLXBhcmFtcyIsImxheW91dCI6Imhvcml6b250YWwiLCJmb3JtIjoicmVhY3QtaG9vay1mb3JtIiwidmFsaWRhdGlvbiI6InpvZCIsImluZGljYXRvciI6ImNoZWNrIiwiYmVoYXZpb3IiOnsibGluZWFyIjp0cnVlLCJndWFyZCI6dHJ1ZSwicGVyc2lzdCI6ZmFsc2UsImtlZXBNb3VudGVkIjpmYWxzZX0sIm5hbWUiOiJDaGVja291dCIsInN0ZXBzIjpbeyJ0aXRsZSI6IlNoaXBwaW5nIiwiZGVzY3JpcHRpb24iOiJXaGVyZSBzaG91bGQgd2Ugc2VuZCB5b3VyIG9yZGVyPyIsImZpZWxkcyI6W3sibGFiZWwiOiJGdWxsIG5hbWUiLCJ0eXBlIjoidGV4dCIsInJlcXVpcmVkIjp0cnVlfSx7ImxhYmVsIjoiRW1haWwiLCJ0eXBlIjoiZW1haWwiLCJyZXF1aXJlZCI6dHJ1ZX0seyJsYWJlbCI6IkFkZHJlc3MiLCJ0eXBlIjoidGV4dCIsInJlcXVpcmVkIjp0cnVlfSx7ImxhYmVsIjoiQ291bnRyeSIsInR5cGUiOiJzZWxlY3QiLCJyZXF1aXJlZCI6dHJ1ZSwib3B0aW9ucyI6WyJBcmdlbnRpbmEiLCJTcGFpbiIsIk1leGljbyIsIlVuaXRlZCBTdGF0ZXMiXX0seyJsYWJlbCI6IkRlbGl2ZXJ5IiwidHlwZSI6InJhZGlvIiwicmVxdWlyZWQiOnRydWUsIm9wdGlvbnMiOlsiU3RhbmRhcmQiLCJFeHByZXNzIl19XX0seyJ0aXRsZSI6IlBheW1lbnQiLCJkZXNjcmlwdGlvbiI6IkNhcmRzIGFyZSBjaGFyZ2VkIHdoZW4gdGhlIG9yZGVyIHNoaXBzLiIsImZpZWxkcyI6W3sibGFiZWwiOiJDYXJkaG9sZGVyIiwidHlwZSI6InRleHQiLCJyZXF1aXJlZCI6dHJ1ZX0seyJsYWJlbCI6IkNhcmQgbnVtYmVyIiwidHlwZSI6InRleHQiLCJyZXF1aXJlZCI6dHJ1ZX0seyJsYWJlbCI6IlNhdmUgY2FyZCBmb3IgbmV4dCB0aW1lIiwidHlwZSI6InN3aXRjaCIsInJlcXVpcmVkIjpmYWxzZX1dfSx7InRpdGxlIjoiUmV2aWV3IiwiZGVzY3JpcHRpb24iOiJDaGVjayBldmVyeXRoaW5nIGJlZm9yZSB5b3UgcGxhY2UgdGhlIG9yZGVyLiIsImZpZWxkcyI6W119XX0.json`

### Onboarding

Profile (Name: text, Role: select) → Workspace (Workspace name: text, Team size: slider, Use cases: checkboxes) → Invite (Teammate email: email, Message: textarea) → Done.

- Studio: https://stepperize.com/studio?preset=onboarding
- Install: `npx shadcn@latest add https://stepperize.com/r/studio/eyJiYXNlIjoicmFkaXgiLCJmcmFtZXdvcmsiOiJuZXh0anMiLCJuYXZpZ2F0aW9uIjoic2VhcmNoLXBhcmFtcyIsImxheW91dCI6InZlcnRpY2FsIiwiZm9ybSI6InJlYWN0LWhvb2stZm9ybSIsInZhbGlkYXRpb24iOiJ6b2QiLCJpbmRpY2F0b3IiOiJjaGVjayIsImJlaGF2aW9yIjp7ImxpbmVhciI6dHJ1ZSwiZ3VhcmQiOnRydWUsInBlcnNpc3QiOmZhbHNlLCJrZWVwTW91bnRlZCI6ZmFsc2V9LCJuYW1lIjoiT25ib2FyZGluZyIsInN0ZXBzIjpbeyJ0aXRsZSI6IlByb2ZpbGUiLCJkZXNjcmlwdGlvbiI6IlRlbGwgeW91ciB0ZWFtbWF0ZXMgd2hvIHlvdSBhcmUuIiwiZmllbGRzIjpbeyJsYWJlbCI6Ik5hbWUiLCJ0eXBlIjoidGV4dCIsInJlcXVpcmVkIjp0cnVlfSx7ImxhYmVsIjoiUm9sZSIsInR5cGUiOiJzZWxlY3QiLCJyZXF1aXJlZCI6dHJ1ZSwib3B0aW9ucyI6WyJFbmdpbmVlcmluZyIsIkRlc2lnbiIsIlByb2R1Y3QiLCJPdGhlciJdfV19LHsidGl0bGUiOiJXb3Jrc3BhY2UiLCJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgd2hlcmUgeW91ciB0ZWFtIHdpbGwgd29yay4iLCJmaWVsZHMiOlt7ImxhYmVsIjoiV29ya3NwYWNlIG5hbWUiLCJ0eXBlIjoidGV4dCIsInJlcXVpcmVkIjp0cnVlfSx7ImxhYmVsIjoiVGVhbSBzaXplIiwidHlwZSI6InNsaWRlciIsInJlcXVpcmVkIjp0cnVlLCJtaW4iOjEsIm1heCI6NTB9LHsibGFiZWwiOiJVc2UgY2FzZXMiLCJ0eXBlIjoiY2hlY2tib3hlcyIsInJlcXVpcmVkIjp0cnVlLCJvcHRpb25zIjpbIlBsYW5uaW5nIiwiRGVzaWduIiwiRW5naW5lZXJpbmciLCJTdXBwb3J0Il19XX0seyJ0aXRsZSI6Ikludml0ZSIsImRlc2NyaXB0aW9uIjoiQnJpbmcgYSB0ZWFtbWF0ZSBhbG9uZy4gWW91IGNhbiBza2lwIHRoaXMuIiwiZmllbGRzIjpbeyJsYWJlbCI6IlRlYW1tYXRlIGVtYWlsIiwidHlwZSI6ImVtYWlsIiwicmVxdWlyZWQiOmZhbHNlfSx7ImxhYmVsIjoiTWVzc2FnZSIsInR5cGUiOiJ0ZXh0YXJlYSIsInJlcXVpcmVkIjpmYWxzZX1dfSx7InRpdGxlIjoiRG9uZSIsImRlc2NyaXB0aW9uIjoiUmV2aWV3IHlvdXIgYW5zd2VycyBhbmQgZW50ZXIgdGhlIHdvcmtzcGFjZS4iLCJmaWVsZHMiOltdfV19.json`

### Identity check

Personal (Legal name: text, Date of birth: date, Phone: tel) → Document (Document type: radio, Document number: text) → Verify (Verification code: otp, I confirm the data above is correct: checkbox) → Submit.

- Studio: https://stepperize.com/studio?preset=kyc
- Install: `npx shadcn@latest add https://stepperize.com/r/studio/eyJiYXNlIjoicmFkaXgiLCJmcmFtZXdvcmsiOiJuZXh0anMiLCJuYXZpZ2F0aW9uIjoicm91dGVzIiwibGF5b3V0IjoicHJvZ3Jlc3MiLCJmb3JtIjoicmVhY3QtaG9vay1mb3JtIiwidmFsaWRhdGlvbiI6InpvZCIsImluZGljYXRvciI6ImNoZWNrIiwiYmVoYXZpb3IiOnsibGluZWFyIjp0cnVlLCJndWFyZCI6dHJ1ZSwicGVyc2lzdCI6ZmFsc2UsImtlZXBNb3VudGVkIjpmYWxzZX0sIm5hbWUiOiJJZGVudGl0eSBjaGVjayIsInN0ZXBzIjpbeyJ0aXRsZSI6IlBlcnNvbmFsIiwiZGVzY3JpcHRpb24iOiJBcyBpdCBhcHBlYXJzIG9uIHlvdXIgSUQuIiwiZmllbGRzIjpbeyJsYWJlbCI6IkxlZ2FsIG5hbWUiLCJ0eXBlIjoidGV4dCIsInJlcXVpcmVkIjp0cnVlfSx7ImxhYmVsIjoiRGF0ZSBvZiBiaXJ0aCIsInR5cGUiOiJkYXRlIiwicmVxdWlyZWQiOnRydWV9LHsibGFiZWwiOiJQaG9uZSIsInR5cGUiOiJ0ZWwiLCJyZXF1aXJlZCI6dHJ1ZX1dfSx7InRpdGxlIjoiRG9jdW1lbnQiLCJkZXNjcmlwdGlvbiI6IldlIGFjY2VwdCBwYXNzcG9ydHMgYW5kIG5hdGlvbmFsIElEcy4iLCJmaWVsZHMiOlt7ImxhYmVsIjoiRG9jdW1lbnQgdHlwZSIsInR5cGUiOiJyYWRpbyIsInJlcXVpcmVkIjp0cnVlLCJvcHRpb25zIjpbIlBhc3Nwb3J0IiwiTmF0aW9uYWwgSUQiLCJEcml2ZXIgbGljZW5zZSJdfSx7ImxhYmVsIjoiRG9jdW1lbnQgbnVtYmVyIiwidHlwZSI6InRleHQiLCJyZXF1aXJlZCI6dHJ1ZX1dfSx7InRpdGxlIjoiVmVyaWZ5IiwiZGVzY3JpcHRpb24iOiJFbnRlciB0aGUgY29kZSB3ZSBzZW50IHRvIHlvdXIgcGhvbmUuIiwiZmllbGRzIjpbeyJsYWJlbCI6IlZlcmlmaWNhdGlvbiBjb2RlIiwidHlwZSI6Im90cCIsInJlcXVpcmVkIjp0cnVlfSx7ImxhYmVsIjoiSSBjb25maXJtIHRoZSBkYXRhIGFib3ZlIGlzIGNvcnJlY3QiLCJ0eXBlIjoiY2hlY2tib3giLCJyZXF1aXJlZCI6dHJ1ZX1dfSx7InRpdGxlIjoiU3VibWl0IiwiZGVzY3JpcHRpb24iOiJWZXJpZmljYXRpb24gdXN1YWxseSB0YWtlcyB1bmRlciAyIG1pbnV0ZXMuIiwiZmllbGRzIjpbXX1dfQ.json`

### Blank

First step (Name: text) → Second step → Third step.

- Studio: https://stepperize.com/studio?preset=blank
- Install: `npx shadcn@latest add https://stepperize.com/r/studio/eyJiYXNlIjoicmFkaXgiLCJmcmFtZXdvcmsiOiJuZXh0anMiLCJuYXZpZ2F0aW9uIjoiY29tcG9uZW50IiwibGF5b3V0IjoiaG9yaXpvbnRhbCIsImZvcm0iOiJyZWFjdC1ob29rLWZvcm0iLCJ2YWxpZGF0aW9uIjoiem9kIiwiaW5kaWNhdG9yIjoiY2hlY2siLCJiZWhhdmlvciI6eyJsaW5lYXIiOnRydWUsImd1YXJkIjp0cnVlLCJwZXJzaXN0IjpmYWxzZSwia2VlcE1vdW50ZWQiOmZhbHNlfSwibmFtZSI6Ik15IGZsb3ciLCJzdGVwcyI6W3sidGl0bGUiOiJGaXJzdCBzdGVwIiwiZGVzY3JpcHRpb24iOiIiLCJmaWVsZHMiOlt7ImxhYmVsIjoiTmFtZSIsInR5cGUiOiJ0ZXh0IiwicmVxdWlyZWQiOnRydWV9XX0seyJ0aXRsZSI6IlNlY29uZCBzdGVwIiwiZGVzY3JpcHRpb24iOiIiLCJmaWVsZHMiOltdfSx7InRpdGxlIjoiVGhpcmQgc3RlcCIsImRlc2NyaXB0aW9uIjoiIiwiZmllbGRzIjpbXX1dfQ.json`

## After installing

- Every file is plain source in the user's project; edit it freely.
- Send the collected data to an API in the summary step's Finish handler (or the last step's submit). `stepper.data.get(stepId)` returns each step's values.
- To change the flow's shape later, regenerate from the Studio link and reinstall, or edit `steps.ts`, `schemas.ts` and the step components by hand.
- Stepperize docs for the APIs used: https://stepperize.com/llms.mdx/docs/v8/api/react/define-stepper, https://stepperize.com/llms.mdx/docs/v8/forms/index, https://stepperize.com/llms.mdx/docs/v8/guides/navigation.
