Frameworks & Code Snippets

Connect any web stack in 30 seconds.

Formtruck works seamlessly with every frontend framework, static site generator, and plain HTML. Browse copy-paste examples below.

React / Next.jsMost Popular

Next.js 15+ (App Router & Server Actions)

Use React 19 Server Actions or client-side fetch with Zod validation and loading states.

Ready-to-use endpoint: https://api.formtruck.com/f/{id}
Built-in spam honeypot (_gotcha) support
Works with JSON & Multipart payload formats
View Interactive Sandbox & Full Guide
nextjs-example.tsx
1234567891011121314151617181920212223242526272829303132333435
// app/contact/page.tsx
'use client';
import { useState } from 'react';
export default function Contact() {
const [status, setStatus] = useState<'idle' | 'loading' | 'success'>('idle');
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
setStatus('loading');
const formData = new FormData(e.currentTarget);
const res = await fetch('https://api.formtruck.com/f/ft_YOUR_FORM_ID', {
method: 'POST',
body: formData,
headers: { Accept: 'application/json' },
});
if (res.ok) setStatus('success');
}
return (
<form onSubmit={handleSubmit} className="space-y-4">
<input type="text" name="name" placeholder="Your Name" required />
<input type="email" name="email" placeholder="Email Address" required />
<textarea name="message" placeholder="Your Message" required />
{/* Anti-spam honeypot */}
<input type="text" name="_gotcha" className="hidden" tabIndex={-1} />
<button type="submit" disabled={status === 'loading'}>
{status === 'loading' ? 'Sending...' : 'Send Message'}
</button>
{status === 'success' && <p>Thank you! We received your message.</p>}
</form>
);
}
React / Next.jsPopular

React (Vite / CRA / React Hook Form)

Clean asynchronous JSON submission with React Hook Form and optimistic toast feedback.

Ready-to-use endpoint: https://api.formtruck.com/f/{id}
Built-in spam honeypot (_gotcha) support
Works with JSON & Multipart payload formats
View Interactive Sandbox & Full Guide
react-example.tsx
1234567891011121314151617181920212223242526
import { useForm } from 'react-hook-form';
export function ContactForm() {
const { register, handleSubmit, reset, formState: { isSubmitting, isSubmitSuccessful } } = useForm();
const onSubmit = async (data) => {
await fetch('https://api.formtruck.com/f/ft_YOUR_FORM_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body: JSON.stringify(data),
});
reset();
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('name', { required: true })} placeholder="Full Name" />
<input {...register('email', { required: true })} type="email" placeholder="Work Email" />
<textarea {...register('message', { required: true })} placeholder="How can we help?" />
<button type="submit" disabled={isSubmitting}>
{isSubmitting ? 'Submitting...' : 'Submit Form'}
</button>
{isSubmitSuccessful && <p className="success">Message received!</p>}
</form>
);
}
Plain HTMLSimplest

Plain HTML5 (Zero JavaScript)

Native HTML POST submission with automatic redirects and no build step required.

Ready-to-use endpoint: https://api.formtruck.com/f/{id}
Built-in spam honeypot (_gotcha) support
Works with JSON & Multipart payload formats
View Interactive Sandbox & Full Guide
html5-example.html
12345678910111213141516171819
<!-- Standard HTML5 Native Form -->
<form action="https://api.formtruck.com/f/ft_YOUR_FORM_ID" method="POST">
<label for="name">Your Name</label>
<input type="text" id="name" name="name" required />
<label for="email">Email Address</label>
<input type="email" id="email" name="email" required />
<label for="message">Your Message</label>
<textarea id="message" name="message" rows="4" required></textarea>
<!-- Optional custom redirect URL -->
<input type="hidden" name="_next" value="https://yoursite.com/thanks" />
<!-- Hidden Honeypot Field for Spam Defense -->
<input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off" />
<button type="submit">Submit Form</button>
</form>
Vue & Nuxt

Vue 3 & Nuxt 3 (Composition API)

Reactive form state with Vue ref, fetch API, and instant validation handling.

Ready-to-use endpoint: https://api.formtruck.com/f/{id}
Built-in spam honeypot (_gotcha) support
Works with JSON & Multipart payload formats
View Interactive Sandbox & Full Guide
vue-example.tsx
12345678910111213141516171819202122232425262728
<script setup>
import { ref } from 'vue';
const form = ref({ name: '', email: '', message: '', _gotcha: '' });
const loading = ref(false);
const submitted = ref(false);
async function submitForm() {
loading.value = true;
const res = await fetch('https://api.formtruck.com/f/ft_YOUR_FORM_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body: JSON.stringify(form.value),
});
loading.value = false;
if (res.ok) submitted.value = true;
}
</script>
<template>
<form @submit.prevent="submitForm">
<input v-model="form.name" placeholder="Your Name" required />
<input v-model="form.email" type="email" placeholder="Email" required />
<textarea v-model="form.message" placeholder="Message" required />
<button :disabled="loading">{{ loading ? 'Sending...' : 'Send' }}</button>
<p v-if="submitted">Thank you! Your submission was recorded.</p>
</form>
</template>
Svelte

Svelte 5 & SvelteKit

Leverage Svelte form actions with progressive enhancement or client-side fetch.

Ready-to-use endpoint: https://api.formtruck.com/f/{id}
Built-in spam honeypot (_gotcha) support
Works with JSON & Multipart payload formats
View Interactive Sandbox & Full Guide
svelte-example.tsx
1234567891011121314151617181920212223242526
<script>
let status = $state('idle');
async function handleSend(e) {
e.preventDefault();
status = 'loading';
const formData = new FormData(e.currentTarget);
const res = await fetch('https://api.formtruck.com/f/ft_YOUR_FORM_ID', {
method: 'POST',
body: formData,
headers: { Accept: 'application/json' }
});
if (res.ok) status = 'success';
}
</script>
<form onsubmit={handleSend}>
<input name="name" placeholder="Name" required />
<input name="email" type="email" placeholder="Email" required />
<textarea name="message" placeholder="Message"></textarea>
<button type="submit" disabled={status === 'loading'}>
{status === 'loading' ? 'Transmitting...' : 'Send Message'}
</button>
</form>
Static Site Generators

Astro (Static & SSR)

Integrate into Astro static pages with zero JavaScript payload or interactive island.

Ready-to-use endpoint: https://api.formtruck.com/f/{id}
Built-in spam honeypot (_gotcha) support
Works with JSON & Multipart payload formats
View Interactive Sandbox & Full Guide
astro-example.tsx
123456789101112
---
// src/components/ContactCard.astro
---
<form action="https://api.formtruck.com/f/ft_YOUR_FORM_ID" method="POST" class="contact-form">
<input type="text" name="name" placeholder="Name" required />
<input type="email" name="email" placeholder="Email" required />
<textarea name="message" placeholder="Message" required></textarea>
<input type="hidden" name="_next" value="/thank-you" />
<input type="text" name="_gotcha" style="display: none;" tabindex="-1" />
<button type="submit">Submit via Formtruck</button>
</form>
File UploadsAdvanced

File Uploads with Multipart Form Data

Accept resumes, PDFs, photos, and zip archives directly into cloud storage.

Ready-to-use endpoint: https://api.formtruck.com/f/{id}
Built-in spam honeypot (_gotcha) support
Works with JSON & Multipart payload formats
View Interactive Sandbox & Full Guide
file-upload-example.html
1234567891011121314
<!-- Multipart File Upload Form -->
<form
action="https://api.formtruck.com/f/ft_YOUR_FORM_ID"
method="POST"
enctype="multipart/form-data"
>
<input type="text" name="applicant_name" placeholder="Candidate Name" required />
<input type="email" name="applicant_email" placeholder="Candidate Email" required />
<label for="resume">Attach Resume (PDF, DOCX up to 15MB)</label>
<input type="file" id="resume" name="resume" accept=".pdf,.doc,.docx" required />
<button type="submit">Submit Application</button>
</form>
AJAX / Fetch

AJAX / Fetch API (Vanilla JavaScript)

Pure lightweight JavaScript with custom error handling, JSON responses, and no page reload.

Ready-to-use endpoint: https://api.formtruck.com/f/{id}
Built-in spam honeypot (_gotcha) support
Works with JSON & Multipart payload formats
View Interactive Sandbox & Full Guide
ajax-fetch-example.tsx
12345678910111213141516171819202122232425262728293031323334
// Vanilla JavaScript AJAX Submission
const form = document.getElementById('contact-form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const submitButton = form.querySelector('button[type="submit"]');
submitButton.disabled = true;
submitButton.innerText = 'Submitting...';
const formData = new FormData(form);
try {
const response = await fetch('https://api.formtruck.com/f/ft_YOUR_FORM_ID', {
method: 'POST',
body: formData,
headers: {
Accept: 'application/json',
},
});
if (response.ok) {
alert('Thank you! Your submission was successful.');
form.reset();
} else {
const errorData = await response.json();
alert('Error: ' + (errorData.message || 'Submission failed'));
}
} catch (err) {
alert('Network error occurred. Please try again.');
} finally {
submitButton.disabled = false;
submitButton.innerText = 'Submit';
}
});