Build a Multi-Step Form in Vue in 5 minutes.
Tags: webdev, tutorial, vue, javascript
Published: 2023-02-06 19:15:00

---
title: Build a Multi-Step Form in Vue in 5 minutes.
published: true
description: Using FormKit we can easily spin up a multi-step form experience in less time than it takes to make a cup of coffee.
tags: webdev, tutorial, vue, javascript
cover_image: https://s3.amazonaws.com/cdn.formk.it/web-assets/articles/multi-step-5-mins-hero.png
# published_at: 2023-02-03 19:38 +0000
---

Few interactions on the web cause as much displeasure for a user as being confronted with a large, intimidating form. Multi-step forms can alleviate this pain by breaking a large form into smaller, approachable steps — but they can also be quite complicated to build.

In this guide, we'll walk through building a multi-step form with FormKit (a free and open-source form building framework) and see how we can provide an elevated user experience with minimal code. We'll be done in approximately 5 minutes. Let's get started!

> Not familiar with FormKit? It's a free and open-source framework for building forms in Vue and you can learn more about it [here](https://dev.to/justinschroeder/introducing-formkit-a-vue-3-form-building-framework-53ji).

## Installation

To get started we need to install FormKit, its supporting default theme, and the FormKit Multi-Step plugin into our project:

```sh
npm install @formkit/vue @formkit/addons @formkit/themes
```

Then we add FormKit to our Vue app, add the Multi-Step Plugin to our FormKit config, and ensure that we're including the necessary styles:

```js
// main.js
import { createApp } from 'vue'
import App from 'App.vue'
// FormKit imports
import { plugin as formKitPlugin, defaultConfig } from '@formkit/vue'
import { createMultiStepPlugin } from '@formkit/addons'
import '@formkit/themes/genesis'
import '@formkit/addons/css/multistep'

createApp(App)
  .use(formKitPlugin, defaultConfig({
    plugins: [createMultiStepPlugin()]
  }))
  .mount('#app')
```

## Usage 

Out-of-the-box, FormKit ships with every native HTML input available to you. Things like `text`, `select`, `checkbox`, etc.

`createMultiStepPlugin` registers two brand-new input types for you to use with FormKit — in exactly the same way you use any other input type.

- `multi-step`: The wrapping group for the entire multi-step input.
- `step`: The wrapping group for a given step within your multi-step input.

Using these inputs together is as simple as wrapping any markup you want to have present within a step in a multi-step form:

```html
<FormKit type="multi-step">
  <FormKit type="step" name="stepOne">
    <!-- content for stepOne goes here! -->
  </FormKit>
</FormKit>
```

So — let's build a quick form for users who want to submit a talk to our upcoming fake conference, VueUniverse.

We'll want to: 
- Collect some contact information for the user.
- Get a brief overview of the talk the user wants to give.
- Ask the user how they heard about VueUniverse. 

Those sound like good groupings for our steps — so let's get started:

```html
<FormKit type="form">
  <FormKit type="multi-step">
    <FormKit type="step" name="contactInformation">
      <!-- collect name, email, and company info -->
      <FormKit 
        type="text" 
        label="Your Name" 
        validation="required"
      />
      <FormKit 
        type="email" 
        label="Your Email" 
        validation="required|email" 
      />
      <FormKit 
        type="text" 
        label="Your Company (optional)"
        help="Are speaking on behalf of an organization?"
      />
    </FormKit>

    <FormKit type="step" name="talkDetails">
      <!-- Get talk title, brief, and track -->
      <FormKit 
        type="text" 
        label="Talk Title" 
        validation="required"
      />
      <FormKit 
        type="textarea" 
        label="Talk Brief" 
        validation="required|length:100"
        help="What is your talk about?"
      />
      <FormKit 
        type="radio" 
        label="Talk Track"
        help="Which track are you submitting for?"
        :options="['Development', 'Testing', 'Leadership']"
      />
    </FormKit>

    <FormKit type="step" name="referral">
      <!-- Ask the user to share how they heard about us -->
      <h2>Thank you for taking the time to submit your talk</h2>
      <p>If you don't mind we'd love to know how you heard about VueUniverse.</p>
      <FormKit 
        type="radio" 
        label="How did you hear about VueUniverse?" 
        :options="['Online Ad', 'Friend or Coworker', 'Search Results', 'Other']"
      />
    </FormKit>
  </FormKit>
</FormKit>
```

And there we go! One component, `FormKit`, with a consistent API and we've got ourselves a working multi-step form with validation! 

(for the best experience open this example in a new tab)
{% embed https://codesandbox.io/embed/eloquent-lewin-ef3evc?autoresize=1&fontsize=12&hidenavigation=1&module=%2Fsrc%2Fcomponents%2FMultiStepForm.vue&theme=dark&view=preview %}

That's great! But there's two things we can change to make it better.

- Since we're using the `multi-step` input as our entire form experience it would be great to have the submit button be inside the last step rather than external to the `multi-step` input.
- We're asking users to go through a set flow, so it would be great if our tabs indicated progress. Additionally it would be great if we prevented the user from navigating to the next step until the current step is completed.

Thankfully, these are both very easy changes to implement.

- First we need to set `:actions="false"` on our wrapping `form` type `FormKit` component to disable the default submit button. Then, using the `stepNext` slot we can insert our own submit button inside the last step in our multi-step form.
- Second, we need to use the `tab-style="progress"` and `allow-incomplete="false"` props to show progress-style tabs and prevent the user from freely navigating through steps until validation is passed.

Here are the relevant sections of our form with those changes implemented:

```html
<!-- remove default actions on the form -->
<FormKit 
  type="form"
  :actions="false"
>
  <!-- Set new props on our multi-step -->
  <FormKit 
    type="multi-step"
    tab-style="progress"
    :allow-incomplete="false"
  >
    ...
    <!-- In our last step, add a submit button -->
    <FormKit type="step" name="referral">
      ...
      <template #stepNext>
        <FormKit type="submit" />
      </template>
    </FormKit>
  </FormKit>
</FormKit>
```

And again, that's it! FormKit takes care of the rest for us. Here is our new and improved multi-step form experience after changing those 6 lines of code.

(for the best experience open this example in a new tab)
{% embed https://codesandbox.io/embed/formkit-multi-step-form-phase-2-7hiu6b?autoresize=1&fontsize=12&hidenavigation=1&module=%2Fsrc%2Fcomponents%2FMultiStepForm.vue&theme=dark %}

Best of all this form has accessible markup, built-in validation, and much more that we didn't have to worry about ourselves thanks to the underlying FormKit component architecture.

## Conclusion

Quick, easy, powerful. Implementing a multi-step form in your project has never been simpler.

By leveraging FormKit in your Vue projects you can supercharge your form development and build rich and complex user-experiences in a fraction of the time — for free.

![Developer after building a multi-step in 5 minutes](https://media.giphy.com/media/3ov9jWu7BuHufyLs7m/giphy.gif)

Want to learn more about FormKit and how it can help with form structure, validation, accessibility, and more? 
- Check out the multi-step docs at https://formkit.com/plugins/multi-step
- Join the FormKit Discord community for support and to meet others using FormKit in their own projects: https://discord.gg/2q3UZkUQbR