Copy-paste Bootstrap 5 contact form
Here's the full template. Include Bootstrap 5 CSS/JS, add your splitforms access key, and ship.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Contact Us</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-md-8 col-lg-6">
<h1 class="mb-4">Contact Us</h1>
<form
action="https://splitforms.com/api/submit"
method="POST"
class="needs-validation"
novalidate
>
<!-- splitforms config -->
<input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
<input type="hidden" name="subject" value="New contact from yoursite.com" />
<input type="hidden" name="redirect" value="https://yoursite.com/thanks" />
<!-- Honeypot spam trap -->
<input name="botcheck" type="checkbox" style="display:none" tabindex="-1" />
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input
type="text"
class="form-control"
id="name"
name="name"
required
minlength="2"
/>
<div class="invalid-feedback">Please enter your name.</div>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input
type="email"
class="form-control"
id="email"
name="email"
required
/>
<div class="invalid-feedback">Please enter a valid email address.</div>
</div>
<div class="mb-3">
<label for="subject" class="form-label">Subject</label>
<select class="form-select" id="subject" name="subject_type">
<option value="general">General inquiry</option>
<option value="sales">Sales question</option>
<option value="support">Technical support</option>
<option value="partnership">Partnership</option>
</select>
</div>
<div class="mb-3">
<label for="message" class="form-label">Message</label>
<textarea
class="form-control"
id="message"
name="message"
rows="5"
required
minlength="10"
></textarea>
<div class="invalid-feedback">Please enter a message (at least 10 characters).</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="consent" name="consent" required />
<label class="form-check-label" for="consent">
I agree to be contacted regarding my inquiry.
</label>
<div class="invalid-feedback">You must agree to be contacted.</div>
</div>
<button type="submit" class="btn btn-primary btn-lg w-100">
Send Message
</button>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Bootstrap 5 custom validation
(function() {
'use strict';
var form = document.querySelector('.needs-validation');
form.addEventListener('submit', function(event) {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
})();
</script>
</body>
</html>How it works
The form uses Bootstrap's needs-validation class for client-side validation. When the user clicks submit:
- JavaScript checks form validity with
form.checkValidity() - If invalid, Bootstrap shows red error messages via
invalid-feedbackdivs - If valid, the browser POSTs the form to
https://splitforms.com/api/submit - splitforms filters spam (honeypot + AI classifier), sends the email, and redirects to your thank-you page
No server-side code. No PHP. No SMTP. Works on GitHub Pages, S3, Vercel, Netlify, or any static host.
AJAX version (no page reload)
Want to submit without a page reload? Add a fetch handler:
<form id="contact-form" class="needs-validation" novalidate>
<!-- same fields as above -->
</form>
<script>
var form = document.getElementById('contact-form');
var button = form.querySelector('button[type="submit"]');
form.addEventListener('submit', async function(e) {
e.preventDefault();
if (!form.checkValidity()) {
form.classList.add('was-validated');
return;
}
button.disabled = true;
button.innerHTML = '<span class="spinner-border spinner-border-sm" role="status"></span> Sending...';
try {
var response = await fetch('https://splitforms.com/api/submit', {
method: 'POST',
body: new FormData(form),
});
if (response.ok) {
form.reset();
form.classList.remove('was-validated');
form.insertAdjacentHTML('beforebegin',
'<div class="alert alert-success">Thanks! We\'ll get back to you within 24 hours.</div>'
);
} else {
throw new Error('Server error');
}
} catch (error) {
form.insertAdjacentHTML('beforebegin',
'<div class="alert alert-danger">Something went wrong. Please try again or email hello@splitforms.com</div>'
);
} finally {
button.disabled = false;
button.innerHTML = 'Send Message';
}
});
</script>This version uses Bootstrap's spinner component for the loading state and Bootstrap alerts for success/error messages.
React-Bootstrap version
Using react-bootstrap? Here's the same form as a React component:
'use client';
import { useState } from 'react';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import Alert from 'react-bootstrap/Alert';
export default function BootstrapContactForm() {
const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle');
const [validated, setValidated] = useState(false);
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const form = e.currentTarget;
if (!form.checkValidity()) {
setValidated(true);
return;
}
setStatus('loading');
try {
const res = await fetch('https://splitforms.com/api/submit', {
method: 'POST',
body: new FormData(form),
});
if (!res.ok) throw new Error();
setStatus('success');
setValidated(false);
form.reset();
} catch {
setStatus('error');
}
}
return (
<>
{status === 'success' && (
<Alert variant="success">Thanks! We'll be in touch within 24 hours.</Alert>
)}
{status === 'error' && (
<Alert variant="danger">Something went wrong. Please try again.</Alert>
)}
<Form noValidate validated={validated} onSubmit={handleSubmit}>
<input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
<Form.Group className="mb-3">
<Form.Label>Name</Form.Label>
<Form.Control name="name" required type="text" />
<Form.Control.Feedback type="invalid">Please enter your name.</Form.Control.Feedback>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Email</Form.Label>
<Form.Control name="email" required type="email" />
<Form.Control.Feedback type="invalid">Please enter a valid email.</Form.Control.Feedback>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Message</Form.Label>
<Form.Control name="message" required as="textarea" rows={5} />
<Form.Control.Feedback type="invalid">Please enter a message.</Form.Control.Feedback>
</Form.Group>
<Button type="submit" variant="primary" size="lg" className="w-100"
disabled={status === 'loading'}>
{status === 'loading' ? 'Sending...' : 'Send Message'}
</Button>
</Form>
</>
);
}Customizing the form
Common modifications:
- Two-column layout: Wrap name and email in
<div class="row"><div class="col-md-6 mb-3"> - File upload: Add
<input type="file" name="attachment" class="form-control" />— splitforms handles file attachments - Floating labels: Use
form-floatingclass for modern floating-label inputs - Dark mode: Add
data-bs-theme="dark"to the<html>tag - Inline form: Use
row g-3 align-items-centerfor horizontal layouts
Spam protection (no CAPTCHA needed)
The hidden botcheck honeypot field catches most bots. splitforms adds AI spam scoring on top — analyzing content patterns, IP reputation, and submission velocity to catch 99.2% of spam without any CAPTCHA.
No reCAPTCHA. No hCaptcha. No Turnstile. No annoying puzzles. Just clean protection that's GDPR-compliant and invisible to real users.
Frequently asked questions
How do I create a Bootstrap contact form?
Use Bootstrap 5 form classes (mb-3, form-label, form-control, btn btn-primary) for styling, then point the form's action attribute at a hosted backend like splitforms (https://splitforms.com/api/submit) for email delivery. No PHP or server-side code required. The full template is ready in 5 minutes.
Does Bootstrap 5 have a built-in contact form component?
Bootstrap 5 provides form styling classes (form-control, form-select, input-group) but does not include a backend for processing submissions. You need a form backend — splitforms is free for 500 submissions/month and works seamlessly with Bootstrap-styled forms.
How do I validate a Bootstrap contact form?
Use Bootstrap 5's built-in validation classes (was-validated, invalid-feedback, valid-feedback) combined with HTML5 constraints (required, type=email, pattern). Add the novalidate attribute to the form tag and use JavaScript to toggle the was-validated class on submit.
Can I use a Bootstrap contact form without PHP?
Yes. Point your form's action at https://splitforms.com/api/submit with your access key. splitforms handles email delivery, spam filtering, and storage. No PHP, no SMTP, no server required — works on any static host.
How do I make a Bootstrap contact form responsive?
Bootstrap 5 is responsive by default. Use the grid system (row, col-md-6) for side-by-side fields on desktop and stacked fields on mobile. The form-control class makes inputs full-width and touch-friendly automatically.
Ship your Bootstrap form today
Keep reading
- HTML contact form code templates (2026)
- AJAX contact form guide
- Tailwind CSS form validation
- Contact form without PHP
- Sign up for free — 500 submissions/month, Bootstrap-ready.