[{"data":1,"prerenderedAt":527},["Reactive",2],{"$KyeTl6nybl":3,"page-data":4,"page-tree":506},[],{"_path":5,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9,"description":10,"body":11,"_type":501,"_id":502,"_source":503,"_file":504,"_extension":505},"/documentation/guides/mutli-step-forms","guides",false,"","Multi step forms","Utils to create stepper forms in multiple pages",{"type":12,"children":13,"toc":498},"root",[14,160,260,369,481],{"type":15,"tag":16,"props":17,"children":19},"element","doc-component-demo",{"title":18},"Create pages for the form",[20,27,38,56,85,114,118,123],{"type":15,"tag":21,"props":22,"children":23},"p",{},[24],{"type":25,"value":26},"text","Tairo provide helpers to build multiple page forms. This can be useful when you have a form that is too long to be displayed in a single page.",{"type":15,"tag":28,"props":29,"children":32},"doc-message",{"color":30,"icon":31},"muted-contrast","ph:question",[33],{"type":15,"tag":21,"props":34,"children":35},{},[36],{"type":25,"value":37},"This feature relies on nested routes and provide/inject to share data between the pages.",{"type":15,"tag":39,"props":40,"children":41},"code-group",{},[42],{"type":15,"tag":43,"props":44,"children":50},"pre",{"className":45,"code":47,"filename":48,"language":49,"meta":8},[46],"language-bash","├── .app/\n│   ├── pages/\n│   │   ├── my-form/\n│   │   │   ├── index.vue # First step\n│   │   │   ├── my-step-2.vue # Second step\n│   │   │   ├── my-step-3.vue # Thrid step\n│   │   │   └── review.vue # Final step\n│   │   └── my-form.vue # Parent page\n","pages structure overview","bash",[51],{"type":15,"tag":52,"props":53,"children":54},"code",{"__ignoreMap":8},[55],{"type":25,"value":47},{"type":15,"tag":21,"props":57,"children":58},{},[59,61,67,69,75,77,83],{"type":25,"value":60},"The parent page ",{"type":15,"tag":52,"props":62,"children":64},{"className":63},[],[65],{"type":25,"value":66},"my-form.vue",{"type":25,"value":68}," will contain the form definition and be responsible for the form state.\nIt also should contains a ",{"type":15,"tag":52,"props":70,"children":72},{"className":71},[],[73],{"type":25,"value":74},"\u003CNuxtPage />",{"type":25,"value":76}," component to render the current step and use ",{"type":15,"tag":52,"props":78,"children":80},{"className":79},[],[81],{"type":25,"value":82},"provideMultiStepForm",{"type":25,"value":84},".",{"type":15,"tag":21,"props":86,"children":87},{},[88,90,96,98,104,106,112],{"type":25,"value":89},"The ",{"type":15,"tag":52,"props":91,"children":93},{"className":92},[],[94],{"type":25,"value":95},"my-form/",{"type":25,"value":97}," folder contains the different steps of the form, ",{"type":15,"tag":52,"props":99,"children":101},{"className":100},[],[102],{"type":25,"value":103},"index.vue",{"type":25,"value":105}," being the first step. Each step can then use ",{"type":15,"tag":52,"props":107,"children":109},{"className":108},[],[110],{"type":25,"value":111},"useMultiStepForm",{"type":25,"value":113}," to access the form state and methods.",{"type":15,"tag":115,"props":116,"children":117},"hr",{},[],{"type":15,"tag":21,"props":119,"children":120},{},[121],{"type":25,"value":122},"Useful resources:",{"type":15,"tag":124,"props":125,"children":126},"ul",{},[127,140,150],{"type":15,"tag":128,"props":129,"children":130},"li",{},[131],{"type":15,"tag":132,"props":133,"children":137},"a",{"href":134,"rel":135},"https://nuxt.com/docs/guide/directory-structure/pages#nested-routes",[136],"nofollow",[138],{"type":25,"value":139},"Nested Routes on nuxt.com",{"type":15,"tag":128,"props":141,"children":142},{},[143],{"type":15,"tag":132,"props":144,"children":147},{"href":145,"rel":146},"https://router.vuejs.org/guide/essentials/nested-routes.html",[136],[148],{"type":25,"value":149},"Nested Routes on router.vuejs.org",{"type":15,"tag":128,"props":151,"children":152},{},[153],{"type":15,"tag":132,"props":154,"children":157},{"href":155,"rel":156},"https://vuejs.org/guide/components/provide-inject.html",[136],[158],{"type":25,"value":159},"Provide/Inject documentation on vuejs.org",{"type":15,"tag":16,"props":161,"children":163},{"title":162},"Define steps metadata and initial state",[164,169,184,196,225],{"type":15,"tag":21,"props":165,"children":166},{},[167],{"type":25,"value":168},"First we need to define types for the form data and the steps metadata, this is optional but can be useful to have better type checking.",{"type":15,"tag":39,"props":170,"children":171},{},[172],{"type":15,"tag":43,"props":173,"children":179},{"className":174,"code":176,"filename":177,"language":178,"meta":8},[175],"language-ts","// types for the form data\nexport interface MyFormData {\n  // step 1\n  email: string\n  password: string\n  passwordCheck: string\n  // step 2\n  firstName: string\n  lastName: string\n  // step 3\n  role: string | null\n}\n// types for steps metadata\nexport interface MyFormStepMeta {\n  name: string\n  description: string\n}\n","\u003Capp>/types/my-form.ts","ts",[180],{"type":15,"tag":52,"props":181,"children":182},{"__ignoreMap":8},[183],{"type":25,"value":176},{"type":15,"tag":21,"props":185,"children":186},{},[187,189,194],{"type":25,"value":188},"Then we can provide our form initial state, our submit method handler and steps definitions using the ",{"type":15,"tag":52,"props":190,"children":192},{"className":191},[],[193],{"type":25,"value":82},{"type":25,"value":195}," function in our parent page.",{"type":15,"tag":21,"props":197,"children":198},{},[199,201,207,209,215,217,223],{"type":25,"value":200},"Steps items requires a ",{"type":15,"tag":52,"props":202,"children":204},{"className":203},[],[205],{"type":25,"value":206},"to",{"type":25,"value":208}," property that should be the path to the step page.\nThe a ",{"type":15,"tag":52,"props":210,"children":212},{"className":211},[],[213],{"type":25,"value":214},"meta",{"type":25,"value":216}," property is optional but can be useful to render the steps in the UI.\nAnother optional property is ",{"type":15,"tag":52,"props":218,"children":220},{"className":219},[],[221],{"type":25,"value":222},"validate",{"type":25,"value":224}," that can be used to validate the form data before moving to the next step, we will see how to use it later.",{"type":15,"tag":39,"props":226,"children":228},{":expandable":227,"expandable":8},"true",[229,240,250],{"type":15,"tag":43,"props":230,"children":235},{"className":231,"code":233,"filename":66,"language":234,"meta":8},[232],"language-vue","\u003Cscript setup lang=\"ts\">\nimport type { MyFormData, MyFormStepMeta } from '~/types/my-form'\n\nconst initialState = ref\u003CMyFormData>({\n  // step 1\n  email: '',\n  password: '',\n  passwordCheck: '',\n  // step 2\n  firstName: '',\n  lastName: '',\n  // step 3\n  role: null,\n})\n\nconst {\n  reset,\n  handleSubmit,\n} = provideMultiStepForm\u003CMyFormData, MyFormStepMeta>({\n  initialState,\n\n  async onSubmit(values) {\n    console.log('Form submitted', values)\n  },\n\n  steps: [\n    {\n      to: '/my-form',\n      meta: {\n        name: 'Step 1', description: 'Login details'\n      },\n    },\n    {\n      to: '/my-form/my-step-2',\n      meta: {\n        name: 'Step 2', description: 'Account info'\n      },\n    },\n    {\n      to: '/my-form/my-step-3',\n      meta: {\n        name: 'Step 3', description: 'Account role'\n      },\n    },\n    {\n      to: '/my-form/review',\n      meta: { \n        name: 'Step 4', description: 'Review account creation'\n      },\n    },\n  ],\n})\n\n\n// you can fetch data here and provide it to the form, \n// as mutating the initialState won't trigger form state update, \n// unless you call reset()\nconst { data } = useFetch\u003CMyFormData>('/api/my-form-data')\nwatch(data, (value) => {\n  if (value) {\n    initialState.value = value\n    reset()\n  }\n}, { immediate: true })\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cmain>\n    \u003CMyFormHeader />\n\n    \u003Cform @submit.prevent=\"handleSubmit\">\n      \u003Cdiv class=\"mb-8\">\n        \u003CNuxtPage />\n      \u003C/div>\n\n      \u003CMyFormActions />\n    \u003C/form>\n  \u003C/main>\n\u003C/template>\n","vue",[236],{"type":15,"tag":52,"props":237,"children":238},{"__ignoreMap":8},[239],{"type":25,"value":233},{"type":15,"tag":43,"props":241,"children":245},{"className":242,"code":243,"filename":244,"language":234,"meta":8},[232],"\u003Cscript setup lang=\"ts\">\nimport type { MyFormData, MyFormStepMeta } from '~/types/my-form'\n\nconst { \n  steps,\n  progress,\n  currentStep,\n} = useMultiStepForm\u003CMyFormData, MyFormStepMeta>()\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CBaseHeading class=\"mb-4 flex items-center gap-1\">\n    \u003Cspan>My form:\u003C/span>\n\n    \u003CBaseDropdown\n      variant=\"text\"\n      :label=\"currentStep.meta.name\"\n    >\n      \u003CBaseDropdownItem\n        v-for=\"step in steps\"\n        :key=\"step.id\"\n        :to=\"step.id \u003C currentStep.id ? step.to : undefined\"\n        :disabled=\"step.id > currentStep.id\"\n      >\n        {{ step.meta.name }}\n\n        \u003Ctemplate #text>\n          {{ step.meta.description }}\n        \u003C/template>\n        \u003Ctemplate #end>\n          \u003CIcon\n            v-if=\"step.id \u003C currentStep.id\"\n            name=\"lucide:check-circle\"\n            class=\"text-success-500 size-4\"\n          />\n        \u003C/template>\n      \u003C/BaseDropdownItem>\n    \u003C/BaseDropdown>\n\n    \u003CBaseProgressCircle :value=\"progress\" :size=\"20\" />\n  \u003C/BaseHeading>\n\u003C/template>\n","MyFormHeader.vue",[246],{"type":15,"tag":52,"props":247,"children":248},{"__ignoreMap":8},[249],{"type":25,"value":243},{"type":15,"tag":43,"props":251,"children":255},{"className":252,"code":253,"filename":254,"language":234,"meta":8},[232],"\u003Cscript setup lang=\"ts\">\nimport type { MyFormData, MyFormStepMeta } from '~/types/my-form'\n\nconst {\n  loading,\n  complete,\n  isLastStep,\n  getPrevStep,\n} = useMultiStepForm\u003CMyFormData, MyFormStepMeta>()\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CBaseButtonGroup>\n    \u003CBaseButton\n      :to=\"getPrevStep()?.to\"\n      :disabled=\"!getPrevStep()?.to\"\n    >\n      Previous\n    \u003C/BaseButton>\n\n    \u003CBaseButton\n      type=\"submit\"\n      color=\"primary\"\n      :loading=\"loading\"\n      :disabled=\"loading || complete\"\n    >\n      {{ isLastStep ? 'Submit' : 'Continue' }}\n    \u003C/BaseButton>\n  \u003C/BaseButtonGroup>\n\u003C/template>\n","MyFormActions.vue",[256],{"type":15,"tag":52,"props":257,"children":258},{"__ignoreMap":8},[259],{"type":25,"value":253},{"type":15,"tag":16,"props":261,"children":263},{"title":262},"Create steps pages",[264,276,301,322,327],{"type":15,"tag":21,"props":265,"children":266},{},[267,269,274],{"type":25,"value":268},"Once we have our parent page setup, we can create the steps pages under the ",{"type":15,"tag":52,"props":270,"children":272},{"className":271},[],[273],{"type":25,"value":95},{"type":25,"value":275}," directory.",{"type":15,"tag":21,"props":277,"children":278},{},[279,281,286,288,293,295,300],{"type":25,"value":280},"We will be able to access form context with ",{"type":15,"tag":52,"props":282,"children":284},{"className":283},[],[285],{"type":25,"value":111},{"type":25,"value":287}," composable.\nIf you omit to call ",{"type":15,"tag":52,"props":289,"children":291},{"className":290},[],[292],{"type":25,"value":82},{"type":25,"value":294}," in the parent page, you will get an error when trying to use ",{"type":15,"tag":52,"props":296,"children":298},{"className":297},[],[299],{"type":25,"value":111},{"type":25,"value":84},{"type":15,"tag":28,"props":302,"children":303},{"color":30,"icon":31},[304],{"type":15,"tag":21,"props":305,"children":306},{},[307,309,314,316,321],{"type":25,"value":308},"Check the form context reference bellow to see all the available methods and properties returned by ",{"type":15,"tag":52,"props":310,"children":312},{"className":311},[],[313],{"type":25,"value":111},{"type":25,"value":315}," and ",{"type":15,"tag":52,"props":317,"children":319},{"className":318},[],[320],{"type":25,"value":82},{"type":25,"value":84},{"type":15,"tag":21,"props":323,"children":324},{},[325],{"type":25,"value":326},"And there are pages examples to use with our form:",{"type":15,"tag":39,"props":328,"children":329},{":expandable":227,"expandable":8},[330,339,349,359],{"type":15,"tag":43,"props":331,"children":334},{"className":332,"code":333,"filename":103,"language":234,"meta":8},[232],"\u003Cscript setup lang=\"ts\">\nimport type { MyFormData, MyFormStepMeta } from '~/types/my-form'\n\nconst { data } = useMultiStepForm\u003CMyFormData, MyFormStepMeta>()\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"max-w-sm space-y-2\">\n    \u003CBaseInput\n      v-model=\"data.email\"\n      icon=\"lucide:mail\"\n      label=\"ایمیل\"\n      type=\"email\"\n      placeholder=\"you@eltheme.ir\"\n    />\n    \u003CAddonInputPassword\n      v-model=\"data.password\"\n      icon=\"lucide:lock\"\n      label=\"Password\"\n    />\n    \u003CBaseInput\n      v-model=\"data.passwordCheck\"\n      icon=\"lucide:lock\"\n      label=\"Password verification\"\n      type=\"password\"\n    />\n  \u003C/div>\n\u003C/template>\n",[335],{"type":15,"tag":52,"props":336,"children":337},{"__ignoreMap":8},[338],{"type":25,"value":333},{"type":15,"tag":43,"props":340,"children":344},{"className":341,"code":342,"filename":343,"language":234,"meta":8},[232],"\u003Cscript setup lang=\"ts\">\nconst { data } = useMultiStepForm()\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"max-w-sm space-y-2\">\n    \u003CBaseInput\n      v-model=\"data.firstName\"\n      label=\"First name\"\n      icon=\"lucide:user\"\n      placeholder=\"جان\"\n    />\n    \u003CBaseInput\n      v-model=\"data.lastName\"\n      label=\"Last name\"\n      icon=\"lucide:user\"\n      placeholder=\"Doe\"\n    />\n  \u003C/div>\n\u003C/template>\n","step-2.vue",[345],{"type":15,"tag":52,"props":346,"children":347},{"__ignoreMap":8},[348],{"type":25,"value":342},{"type":15,"tag":43,"props":350,"children":354},{"className":351,"code":352,"filename":353,"language":234,"meta":8},[232],"\u003Cscript setup lang=\"ts\">\nconst { data } = useMultiStepForm()\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"max-w-sm space-y-2\">\n    \u003CBaseHeading size=\"md\" weight=\"medium\">\n      Select a role\n    \u003C/BaseHeading>\n    \u003Cdiv class=\"flex flex-col space-y-2\">\n      \u003CBaseRadio\n        v-model=\"data.role\"\n        value=\"user\"\n        label=\"User\"\n      />\n      \u003CBaseRadio\n        v-model=\"data.role\"\n        value=\"moderator\"\n        label=\"Moderator\"\n      />\n      \u003CBaseRadio\n        v-model=\"data.role\"\n        value=\"admin\"\n        label=\"Admin\"\n      />\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n","step-3.vue",[355],{"type":15,"tag":52,"props":356,"children":357},{"__ignoreMap":8},[358],{"type":25,"value":352},{"type":15,"tag":43,"props":360,"children":364},{"className":361,"code":362,"filename":363,"language":234,"meta":8},[232],"\u003Cscript setup lang=\"ts\">\nconst { data } = useMultiStepForm()\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"max-w-sm space-y-2\">\n    \u003CBaseCard class=\"p-4\">\n      \u003Cpre>{{ data }}\u003C/pre>\n    \u003C/BaseCard>\n  \u003C/div>\n\u003C/template>\n","review.vue",[365],{"type":15,"tag":52,"props":366,"children":367},{"__ignoreMap":8},[368],{"type":25,"value":362},{"type":15,"tag":16,"props":370,"children":372},{"title":371},"Errors and validation",[373,385,411,423,443,464,469],{"type":15,"tag":21,"props":374,"children":375},{},[376,378,383],{"type":25,"value":377},"By default, no validation is performed when moving to the next step. You can add a ",{"type":15,"tag":52,"props":379,"children":381},{"className":380},[],[382],{"type":25,"value":222},{"type":25,"value":384}," function to the step definition to perform validation before moving to the next step.",{"type":15,"tag":21,"props":386,"children":387},{},[388,389,394,396,402,404,409],{"type":25,"value":89},{"type":15,"tag":52,"props":390,"children":392},{"className":391},[],[393],{"type":25,"value":222},{"type":25,"value":395}," function get the current form context as argument, in which you can use the ",{"type":15,"tag":52,"props":397,"children":399},{"className":398},[],[400],{"type":25,"value":401},"setFieldError",{"type":25,"value":403}," method to set an error message for a specific field. If you set an error message for a field and don't return anything within ",{"type":15,"tag":52,"props":405,"children":407},{"className":406},[],[408],{"type":25,"value":222},{"type":25,"value":410}," function, the form won't move to the next step.",{"type":15,"tag":39,"props":412,"children":413},{":expandable":227,"expandable":8},[414],{"type":15,"tag":43,"props":415,"children":418},{"className":416,"code":417,"filename":66,"language":234,"meta":8},[232],"\u003Cscript setup lang=\"ts\">\nprovideMultiStepForm({\n  // global error handler,\n  // this will be called when an error is thrown \n  // in a validate function or in the onSubmit function\n  async onError(error, context) {\n    // \n  },\n\n  // ...\n\n  steps: [\n    {\n      // ...\n\n      async validate({ data, setFieldError, resetFieldError }) {\n        // reset current step errors\n        resetFieldError(['email', 'password', 'passwordCheck'])\n\n        // you can use a validation library like zod or yup\n        if (!data.value.email) {\n          setFieldError('email', 'Email is required')\n        }\n        else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(data.value.email)) {\n          setFieldError('email', 'Invalid email')\n        }\n        else {\n          // example of async validation\n          const available = await checkEmailAvailability(data.value.email)\n          if (!available) {\n            setFieldError('email', 'Email already used')\n          }\n        }\n\n        if (!data.value.password) {\n          setFieldError('password', 'Password is required')\n        }\n        else if (data.value.password.length \u003C 6) {\n          setFieldError('password', 'Password must be at least 6 characters')\n        }\n        else if (data.value.password !== data.value.passwordCheck) {\n          setFieldError('passwordCheck', 'Passwords do not match')\n        }\n\n        // return nothing to let form move only if no errors\n      },\n    },\n  ],\n})\n\u003C/script>\n",[419],{"type":15,"tag":52,"props":420,"children":421},{"__ignoreMap":8},[422],{"type":25,"value":417},{"type":15,"tag":21,"props":424,"children":425},{},[426,427,433,435,441],{"type":25,"value":89},{"type":15,"tag":52,"props":428,"children":430},{"className":429},[],[431],{"type":25,"value":432},"setFieldError(key, message)",{"type":25,"value":434}," method populate the ",{"type":15,"tag":52,"props":436,"children":438},{"className":437},[],[439],{"type":25,"value":440},"errors.fields[key]",{"type":25,"value":442}," object in the form context, which can be used to display errors in the UI.",{"type":15,"tag":21,"props":444,"children":445},{},[446,448,454,456,462],{"type":25,"value":447},"In addition, we need to ensure on page load that previous steps are valid, as the user can navigate directly to a step page. We can do this by calling the ",{"type":15,"tag":52,"props":449,"children":451},{"className":450},[],[452],{"type":25,"value":453},"checkPreviousSteps",{"type":25,"value":455}," method in the ",{"type":15,"tag":52,"props":457,"children":459},{"className":458},[],[460],{"type":25,"value":461},"onBeforeMount",{"type":25,"value":463}," hook inside our steps pages.",{"type":15,"tag":21,"props":465,"children":466},{},[467],{"type":25,"value":468},"We can update our form pages to display errors on the fields and check previous steps (only relevant parts are shown):",{"type":15,"tag":39,"props":470,"children":471},{},[472],{"type":15,"tag":43,"props":473,"children":476},{"className":474,"code":475,"filename":103,"language":234,"meta":8},[232],"\u003Cscript setup lang=\"ts\">\nconst { errors, checkPreviousSteps } = useMultiStepForm()\n\nonBeforeMount(checkPreviousSteps)\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"max-w-sm space-y-2\">\n    \u003CBaseInput\n      :error=\"errors.fields.email\"\n    />\n    \u003CAddonInputPassword\n      :error=\"errors.fields.password\"\n    />\n    \u003CBaseInput\n      :error=\"errors.fields.passwordCheck\"\n    />\n  \u003C/div>\n\u003C/template>\n",[477],{"type":15,"tag":52,"props":478,"children":479},{"__ignoreMap":8},[480],{"type":25,"value":475},{"type":15,"tag":16,"props":482,"children":484},{"title":483},"Form context reference",[485],{"type":15,"tag":39,"props":486,"children":487},{},[488],{"type":15,"tag":43,"props":489,"children":493},{"className":490,"code":491,"filename":492,"language":178,"meta":8},[175],"export interface MultiStepFormContext\u003C\n  DATA extends Record\u003Cstring, any> = Record\u003Cstring, any>,\n  META extends Record\u003Cstring, any> = Record\u003Cstring, any>,\n> {\n  steps: ComputedRef\u003CWithId\u003CStepForm\u003CDATA, META>>[]>\n  totalSteps: ComputedRef\u003Cnumber>\n  currentStepId: ComputedRef\u003Cnumber>\n  currentStep: ComputedRef\u003CWithId\u003CStepForm\u003CDATA, META>>>\n  progress: ComputedRef\u003Cnumber>\n  isLastStep: ComputedRef\u003Cboolean>\n  data: Ref\u003CUnwrapRef\u003CDATA>>\n  errors: Readonly\u003CRef\u003C{\n    message: string\n    fields: Record\u003Cstring, string | undefined>\n  }>>\n  loading: Readonly\u003CRef\u003Cboolean>>\n  complete: Readonly\u003CRef\u003Cboolean>>\n\n  getStep(id?: number): WithId\u003CStepForm\u003CDATA, META>> | undefined\n  getNextStep(id?: number): WithId\u003CStepForm\u003CDATA, META>> | null\n  getPrevStep(id?: number): WithId\u003CStepForm\u003CDATA, META>> | null\n  goToStep(step?: WithId\u003CStepForm\u003CDATA, META>>): Promise\u003Cvoid>\n  reset(initialState?: MaybeRefOrGetter\u003CDATA>): void\n  setErrorMessage(message?: string): void\n  setFieldError(field: string, message?: string): void\n  resetFieldError(field?: string | string[]): void\n\n  validateStep(step?: WithId\u003CStepForm\u003CDATA, META>>): Promise\u003Cboolean>\n  handleSubmit(): Promise\u003Cvoid>\n  checkPreviousSteps(): Promise\u003Cvoid>\n}\n","MultiStepFormContext",[494],{"type":15,"tag":52,"props":495,"children":496},{"__ignoreMap":8},[497],{"type":25,"value":491},{"title":8,"searchDepth":499,"depth":499,"links":500},2,[],"markdown","content:documentation:50.guides:4.mutli-step-forms.md","content","documentation/50.guides/4.mutli-step-forms.md","md",[507,513,520],{"_path":508,"_dir":8,"_draft":7,"_partial":7,"_locale":8,"title":509,"description":8,"toc":510,"_type":501,"_id":511,"_source":503,"_file":512,"_extension":505},"/documentation","مرکز مستندات",true,"content:documentation:1.index.md","documentation/1.index.md",{"_path":514,"_dir":6,"_draft":7,"_partial":510,"_locale":8,"title":515,"_id":516,"_type":517,"_source":503,"_file":518,"_extension":519},"/documentation/guides/_dir","Guides","content:documentation:50.guides:_dir.yml","yaml","documentation/50.guides/_dir.yml","yml",{"_path":521,"_dir":522,"_draft":7,"_partial":7,"_locale":8,"title":8,"description":523,"navigation":7,"redirect":524,"_type":501,"_id":525,"_source":503,"_file":526,"_extension":505},"/documentation/guides","documentation","Redirecting to panels...","/documentation/guides/panels","content:documentation:50.guides:1.index.md","documentation/50.guides/1.index.md",1779173533431]