Vev creates static websites, which means data storage/submissions will need to be sent to a third party. In this lesson, we will create a Form that submits data to a Formspree endpoint.

In the example code below we have taken the React sample code from{formId}/integration and created the following code from it:

import { useState } from 'react';

* Formspree and Vev example form.
* code from:{yourFormID}/integration
* rewritten to functional component since its shorter & prettier.
export default function ({ }: Props) {
const [status, setStatus] = useState<string>('');

const submitForm = ev => {
const form =;
const data = new FormData(form);
const xhr = new XMLHttpRequest();, form.action);
xhr.setRequestHeader("Accept", "application/json");
xhr.onreadystatechange = () => {
if (xhr.readyState !== XMLHttpRequest.DONE) return;
if (xhr.status === 200) {
} else {

return (
/** Important: Change the{id} with your Formspree URL **/
<input type="email" name="email" />
<input type="text" name="message" />
{status === "SUCCESS" ? <p>Thanks!</p> : <button>Submit</button>}
{status === "ERROR" && <p>Ooops! There was an error.</p>}

What does this code actually do? It writes out a <form> element with a third-party (Formspree) endpoint where the data is stored. When the user fills out this form in Vev and clicks submit, the data will be available in Formspree.

And while it may need some styling, the form is fully functional:

With Formspree adding another field is done by adding <input name=”yourExtraField /> to your markup. Other third-party providers may require a different implementation. Please see your third-party form provider's documentation.

Did this answer your question?