Formtruck works seamlessly with every frontend framework, static site generator, and plain HTML. Browse copy-paste examples below.
Use React 19 Server Actions or client-side fetch with Zod validation and loading states.
https://api.formtruck.com/f/{id}_gotcha) support1234567891011121314151617181920212223242526272829303132333435// 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>);}
Clean asynchronous JSON submission with React Hook Form and optimistic toast feedback.
https://api.formtruck.com/f/{id}_gotcha) support1234567891011121314151617181920212223242526import { 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>);}
Native HTML POST submission with automatic redirects and no build step required.
https://api.formtruck.com/f/{id}_gotcha) support12345678910111213141516171819<!-- 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>
Reactive form state with Vue ref, fetch API, and instant validation handling.
https://api.formtruck.com/f/{id}_gotcha) support12345678910111213141516171819202122232425262728<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>
Leverage Svelte form actions with progressive enhancement or client-side fetch.
https://api.formtruck.com/f/{id}_gotcha) support1234567891011121314151617181920212223242526<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>
Integrate into Astro static pages with zero JavaScript payload or interactive island.
https://api.formtruck.com/f/{id}_gotcha) support123456789101112---// 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>
Accept resumes, PDFs, photos, and zip archives directly into cloud storage.
https://api.formtruck.com/f/{id}_gotcha) support1234567891011121314<!-- Multipart File Upload Form --><formaction="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>
Pure lightweight JavaScript with custom error handling, JSON responses, and no page reload.
https://api.formtruck.com/f/{id}_gotcha) support12345678910111213141516171819202122232425262728293031323334// Vanilla JavaScript AJAX Submissionconst 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';}});