How to Create a Complex Form with Vue.js and Headlessforms

If you have a website for a business or hobby, one of your goals will always be to connect with visitors. Whether it’s getting a quote inquiry or simply for support, forms are one of the best ways to connect with website visitors.

Vue.js is one of the newer ways to build JavaScript-enabled forms, but you still need a reliable backend to create your forms, process messages and more. So let’s take a closer look at building complex forms with Vue.js and Headlessforms.

What is Headlessforms?

Headlessforms is a tool that allows content creators to receive visitor submissions in real time. Whether you’re a web developer or just someone who owns and operates your website (or websites), you’re probably always on the lookout for low and no-code solutions that allow you to do complex things on your website. Since forms are one of the most common dynamic elements on any website, there’s a good chance you’ve tried a few options to build and manage them.

However, many form builders are limited, and some don’t work on every platform. This means you might spend a lot of time figuring them out, only to find that they won’t work on the site.

Headlessforms is a form backend that allows you to create complex forms and then gives you easy-to-implement HTML code that you can use on any website. It’s a quick and easy, often drag-and-drop solution that offers much more than most form builders, with a super simple user interface.

So whether you only need to build one form or dozens for different things, you can build them all on Headlessforms.

How to Use Vue.js with Headlessforms

Now that we’ve briefly considered why you might want to use Headlessforms and why Vue.js makes sense for many forms you might want to build, it’s time to look at how you could do that in more detail. You can manage this process in three ways, so let’s look at all of them.

Option 1: Use the HTML Provided

The simplest option (and one that’s ideal for non-developers) is to use the HTML provided by Headlessforms to create your form. The steps, in this case, would be:

  1. Copy the HTML provided by Headlessforms
  2. Paste it onto the setup tab
  3. Add fields as needed

This is best for simple forms, but you can expand to include complex processes, particularly if you are familiar with coding for forms. This option is best suited for forms that don’t require validation, but there are options to redirect if you need that functionality.

Option 2: Send Data Directly to the Headlessforms API

Headlessforms has an easy-to-use API that allows you to send data directly from your Vue.js form to your Headlessforms client interface. Again, the steps are simple:

  1. Build your form using Vue.js
  2. Send data directly to Header Forms using the platform API

This option gives you full control of your data and how you present data errors to your users.

Option 3: Send Data to Your Server and Then to Headlessforms AP

The last option on the list of implementation methods for Vue.js and Headlessforms is to send your data to your server and then to Headlessforms using the API.

This is the most complex option and requires a higher level of technical skill, but it can ensure that your form looks like a native part of your site/application since it sends data to your domain, which is a big plus for many developers and site owners.

How to Get Started with Headlessforms and Vue.js

If you think that Headlessforms and Vue.js might be the form solution you’re looking for for your site, the best way to be sure is to dive right in and try them out. Let’s look at how you can do just that.

Step 1: Get a Headlessforms Account

The first thing you need to do to start using Headlessforms as your forms’ backend is to get an account. Several paid packages are affordable, but you can also opt for the free / dev option if you’re just testing things out. Choose your package and register your account, and you’ll be ready to start testing the system.

Step 2: Get Vue.js

Vue.js has a vast website with tutorials, support options, and more. If you plan to use Vue.js to build your Headlessforms, you should download and install the Quick Start package, so you can start using and learning the code and system.

Step 3: Start with a Sample Code

The easiest way to start with any kind of code is to start with a template. Fortunately, Headlessforms has created a very easy-to-modify ready-to-go Vue.js component.

Just create an empty .vue file in your “components” folder and simply copy and paste the following code to start adjusting and testing:

    <div class="form-wrapper">
        <form @submit.prevent="submit" id="my-form" v-if="!isSuccessfullySent">
            <input type="email" v-model="" required placeholder="Enter your email"
                   :class="{'has-error': validationErrors.last_name}">
            <span class="validation-error" v-if="">
                {{', ') }}
            <input type="text" maxlength="100" minlength="2" required v-model="form.first_name"
                   placeholder="Enter your name" :class="{'has-error': validationErrors.last_name}">
            <span class="validation-error" v-if="validationErrors.first_name">
                {{ validationErrors.first_name.join(', ') }}
            <input type="text" maxlength="100" minlength="2" required v-model="form.last_name"
                   placeholder="Enter your Surname" :class="{'has-error': validationErrors.last_name}">
            <span class="validation-error" v-if="validationErrors.last_name">
                {{ validationErrors.last_name.join(', ') }}
            <button type="submit" :disabled="isSending" :class="{busy:isSending}">
                {{ !isSending ? 'Submit' : 'Sending...' }}
            <div class="message error-message" v-if="error">
                {{ error }}
        <div class="message success-message" v-else>
            Thanks for your Submission!
            <button @click="resetForm">Send Again</button>
const headlessFormUrl = ''; // Replace '0vppKuLVs0' with your form token
export default {
    name: 'MyForm',
    data() {
        return {
            form: {
                first_name: null,
                last_name: null,
                email: null,
                _validation: {
                    email: [
                    first_name: [
                    last_name: [
                _validation_messages: {
                    email: {
                        email: 'Please enter a valid email address',
                        min: 'Email address should contain at least :min characters',
                        max: 'Email address must be no longer that :max characters'
                    // Other fields or rules will use default messages
                // Possible values: 'validate_and_return', 'validate_and_save';
                // Default value: 'validate_and_return';
                // Ignored if no '_validation' object is passed
                _validation_behavior: 'validate_and_return'
            error: null,
            validationErrors: {},
            isSuccessfullySent: false,
            isSending: false
    methods: {
        submit() {
  , this.form, {withCredentials: false})
        successfullySent() {
            this.isSuccessfullySent = true;
        handleError(error) {
            // Handle request errors
            this.setError(error.message || 'Something went Wrong');
        handleResponse({data}) {
            switch (data.status) {
                case 200:
                    // Handle successful submit
                case 422:
                    // Handle validation errors
        sendingStarted() {
            this.isSending = true;
        sendingFinished() {
            this.isSending = false;
        clearErrors() {
            this.error = null;
            this.validationErrors = {};
        setError(message) {
            this.error = message;
        setValidationErrors(errors) {
            this.validationErrors = errors;
        resetForm() {
            Object.keys(this.form).forEach(key => {
                if (!key.startsWith('_')) {
                    this.form[key] = null;
            this.isSuccessfullySent = false;
div.form-wrapper {
    width: 50%;
    margin-left: auto;
    margin-right: auto;
    display: flex;
div.form-wrapper form#my-form {
    display: flex;
    flex-direction: column;
    width: 100%;
div.form-wrapper form#my-form input {
    border: 2px solid #9ca3af;
    border-radius: 10px;
    margin: 10px 0;
    padding: 10px;
div.form-wrapper form#my-form input.has-error {
    border: 2px solid #9ca3af;
div.form-wrapper form#my-form button {
    border-radius: 10px;
    background-color: #0a67d7;
    color: #fff;
    padding: 10px;
    margin: 10px 0;
    width: 100%;
div.form-wrapper form#my-form button.busy {
    opacity: 40%;
div.form-wrapper form#my-form span.validation-error {
    color: #c90e0e;
    padding: 0 5px;
    font-size: 80%;
div.form-wrapper div.message {
    margin-top: 15px;
    padding: 15px;
    color: #fff;
    font-weight: bold;
    width: 100%;
    text-align: center;
    border-radius: 10px;
    display: flex;
    flex-direction: column;
div.form-wrapper div.message.error-message {
    background-color: rgba(255, 0, 0, 0.5);
div.form-wrapper div.message.success-message {
    background-color: rgba(63, 165, 63, 0.8);

div.form-wrapper div.message button {
    border-radius: 10px;
    background-color: #eceaea;
    color: #000;
    padding: 10px;
    margin-top: 15px;

What’s in this Sample Code?

  • The above code will create a form that you can use to collect data. Then you can configure the endpoint on the form backend so you can set up spam filtering, input validation and much more. But you’ll want to use the Headlessforms backend tool.
  • This code features a space to input an email address and password.
  • This code features a space to enter a first and last name.
  • This code will trigger a warning message that prompts users when their email address is incorrect or their password requires specific characters.
  • This code has a space where you can implement the name you want to use for the form.
  • The code will prompt users when the information they enter into the form is successfully sent, or if there is an error (leaving out a required part of the form)
  • The code dictates the width and length of the border of the form, colors of the text, background and border.
  • The code dictates font size, spacing between text, and text alignment.

Step 4: Creating Forms with Headlessforms Backend Tool

Now that you can see a sample code, it’s time to get more specific and discuss how Headlessforms streamlines the process of creating forms. With Headlessforms, you don’t have to write a complex backend to receive form submissions or send auto responses to emails. Simply edit your form action with Headlessforms.

<form action="" method="POST">
    <input name="email" type="email" placeholder="Enter your email" required>
    <input name="name" type="text" placeholder="Enter your name">
    <button type="submit">Send</button>

Note: Note; Please change the unique URL endpoint in form ACTION to mention

This code uses the Headlessforms backend tool, making it easy to add a user-friendly form for entering name, email and submitting.

Now you can add even more form attributes using:

 <input type=”insert here” name=”insert here”>

Step 5: Configure the Endpoint on the Form Backend to add Spam Filtering, etc.

Of course, you could also use Vue.js without Headlessforms. It’s possible to implement your forms manually via the backend of your website. That requires much more coding and testing, though, and it doesn’t offer any of the features you can get using Headlessforms as your form backend.

Let’s look at everything you can customize for your form quickly and efficiently when you use Headlessforms instead of hard coding your forms.

Spam Filtering

Form spam has become the latest electronic scourge. Even if you’re using tools like ReCAPTCHA to limit spam, it’s probably still getting through. Headlessforms gives you advanced spam filtering tools to help cut form spam down.

Client Backend

If you’re building a form for a client, there’s a good chance you will need to hand over the backend management at some point. Headlessforms gives you and your clients an easy-to-use interface that makes changing individual forms and creating new ones much more manageable.


Getting website visitors to fill in a form is only the first step of the process. You still need to ensure that the forms are processed correctly, which means they land in the right inboxes.

Headlessforms makes it easy to ensure that all your forms go to the right people, so you can take action as soon as possible.

Email Confirmation

As much as preventing form spam is a priority, you must keep your nose clean. That means ensuring that all your form users opt-in to receive communications from you and confirming that their emails exist.

Easy-to-use email confirmation tools in the Headlessforms platform allow you to do all that and more. So it’s quick and easy to configure whether you need to ensure you’re getting contact from bona fide email addresses or that your web visitors opt-in to receive mail from you.

Zapier Integration

More and more businesses are using tools like Zapier to automate various parts of their companies, and sales funnels are certainly part of that. Headlessforms integrates seamlessly with Zapier, so you can route your form submissions to your CRM or something else.

To enable Zapier with Headlessforms:

1)    Create an API token on your profile.

  • Get your form token on Form Overview
  • Go to the Zapier app
  • Setup trigger by selecting “new submission” trigger, and signing into your account with the API token.
  • Enter your form token and setup action

Always remember the user experience

With these basics covered, the power to create complex and Headlessforms in Vue is yours. From these relatively simple beginnings, it’s fun to tinker and extrapolate on how best to give users a seamless and secure experience navigating websites of all kinds – all while ensuring in the background that every element of data is flowing to where it should.

Of course, true HTML and Javascript mastery comes from having the right tools on side – and that’s where the team at Headlessforms comes in. Our tools and integrations unlock powerful, streamlined and intuitive ways for coders to perfect their craft.