Gatsby Integration
Integrating Kollect with Gatsby is straightforward. This guide shows you how to add forms to your Gatsby site.
Basic Setup
1. Create a Contact Form Component
// src/components/ContactForm.jsx
import React from 'react';
const ContactForm = () => {
return (
<form
action="https://kollect.app/f/YOUR_FORM_KEY"
method="POST"
style={{ maxWidth: '500px', margin: '0 auto' }}
>
<div style={{ marginBottom: '1rem' }}>
<label htmlFor="name" style={{ display: 'block', marginBottom: '0.5rem' }}>
Name
</label>
<input
type="text"
id="name"
name="name"
required
style={{ width: '100%', padding: '0.5rem', borderRadius: '4px', border: '1px solid #ccc' }}
/>
</div>
<div style={{ marginBottom: '1rem' }}>
<label htmlFor="email" style={{ display: 'block', marginBottom: '0.5rem' }}>
Email
</label>
<input
type="email"
id="email"
name="email"
required
style={{ width: '100%', padding: '0.5rem', borderRadius: '4px', border: '1px solid #ccc' }}
/>
</div>
<div style={{ marginBottom: '1rem' }}>
<label htmlFor="message" style={{ display: 'block', marginBottom: '0.5rem' }}>
Message
</label>
<textarea
id="message"
name="message"
rows="5"
required
style={{ width: '100%', padding: '0.5rem', borderRadius: '4px', border: '1px solid #ccc' }}
/>
</div>
<button
type="submit"
style={{
padding: '0.75rem 2rem',
background: '#8B5CF6',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '1rem'
}}
>
Send Message
</button>
</form>
);
};
export default ContactForm;2. Use the Component in a Page
// src/pages/contact.jsx
import React from 'react';
import Layout from '../components/Layout';
import ContactForm from '../components/ContactForm';
const ContactPage = () => {
return (
<Layout>
<h1>Contact Us</h1>
<p>We'd love to hear from you!</p>
<ContactForm />
</Layout>
);
};
export default ContactPage;AJAX Submission with State
For a better user experience, handle the submission with JavaScript:
// src/components/ContactFormAjax.jsx
import React, { useState } from 'react';
const ContactFormAjax = () => {
const [status, setStatus] = useState('idle'); // idle, submitting, success, error
const [message, setMessage] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
setStatus('submitting');
const formData = new FormData(e.target);
try {
const response = await fetch('https://kollect.app/f/YOUR_FORM_KEY', {
method: 'POST',
body: formData,
});
if (response.ok) {
setStatus('success');
setMessage('Thank you! Your message has been sent.');
e.target.reset();
} else {
throw new Error('Form submission failed');
}
} catch (error) {
setStatus('error');
setMessage('Oops! Something went wrong. Please try again.');
}
};
return (
<div>
<form onSubmit={handleSubmit} style={{ maxWidth: '500px', margin: '0 auto' }}>
<div style={{ marginBottom: '1rem' }}>
<label htmlFor="name">Name</label>
<input type="text" id="name" name="name" required />
</div>
<div style={{ marginBottom: '1rem' }}>
<label htmlFor="email">Email</label>
<input type="email" id="email" name="email" required />
</div>
<div style={{ marginBottom: '1rem' }}>
<label htmlFor="message">Message</label>
<textarea id="message" name="message" rows="5" required />
</div>
<button type="submit" disabled={status === 'submitting'}>
{status === 'submitting' ? 'Sending...' : 'Send Message'}
</button>
</form>
{status === 'success' && (
<div style={{ marginTop: '1rem', padding: '1rem', background: '#d4edda', borderRadius: '4px' }}>
{message}
</div>
)}
{status === 'error' && (
<div style={{ marginTop: '1rem', padding: '1rem', background: '#f8d7da', borderRadius: '4px' }}>
{message}
</div>
)}
</div>
);
};
export default ContactFormAjax;File Uploads
// src/components/FileUploadForm.jsx
import React from 'react';
const FileUploadForm = () => {
return (
<form
action="https://kollect.app/f/YOUR_FORM_KEY"
method="POST"
encType="multipart/form-data"
>
<div>
<label htmlFor="name">Name</label>
<input type="text" id="name" name="name" required />
</div>
<div>
<label htmlFor="resume">Upload Resume (PDF)</label>
<input
type="file"
id="resume"
name="resume"
accept=".pdf"
required
/>
</div>
<button type="submit">Submit Application</button>
</form>
);
};
export default FileUploadForm;Newsletter Signup
// src/components/NewsletterForm.jsx
import React, { useState } from 'react';
const NewsletterForm = () => {
const [email, setEmail] = useState('');
const [status, setStatus] = useState('idle');
const handleSubmit = async (e) => {
e.preventDefault();
setStatus('submitting');
const formData = new FormData();
formData.append('email', email);
try {
await fetch('https://kollect.app/f/YOUR_FORM_KEY', {
method: 'POST',
body: formData,
});
setStatus('success');
setEmail('');
} catch (error) {
setStatus('error');
}
};
return (
<form onSubmit={handleSubmit} style={{ display: 'flex', gap: '1rem' }}>
<input
type="email"
placeholder="Enter your email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
style={{ flex: 1, padding: '0.5rem' }}
/>
<button type="submit" disabled={status === 'submitting'}>
{status === 'submitting' ? 'Subscribing...' : 'Subscribe'}
</button>
{status === 'success' && <span>✓ Subscribed!</span>}
{status === 'error' && <span>✗ Error</span>}
</form>
);
};
export default NewsletterForm;Using with Gatsby Plugins
If you’re using styled-components or Emotion:
// src/components/StyledContactForm.jsx
import React from 'react';
import styled from 'styled-components';
const FormContainer = styled.form`
max-width: 500px;
margin: 0 auto;
`;
const FormGroup = styled.div`
margin-bottom: 1rem;
`;
const Label = styled.label`
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
`;
const Input = styled.input`
width: 100%;
padding: 0.75rem;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
`;
const TextArea = styled.textarea`
width: 100%;
padding: 0.75rem;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
`;
const SubmitButton = styled.button`
padding: 0.75rem 2rem;
background: #8B5CF6;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
transition: background 0.2s;
&:hover {
background: #7C3AED;
}
`;
const StyledContactForm = () => {
return (
<FormContainer action="https://kollect.app/f/YOUR_FORM_KEY" method="POST">
<FormGroup>
<Label htmlFor="name">Name</Label>
<Input type="text" id="name" name="name" required />
</FormGroup>
<FormGroup>
<Label htmlFor="email">Email</Label>
<Input type="email" id="email" name="email" required />
</FormGroup>
<FormGroup>
<Label htmlFor="message">Message</Label>
<TextArea id="message" name="message" rows="5" required />
</FormGroup>
<SubmitButton type="submit">Send Message</SubmitButton>
</FormContainer>
);
};
export default StyledContactForm;Environment Variables
Store your form key in environment variables:
# .env.development
GATSBY_KOLLECT_FORM_KEY=your_development_key
# .env.production
GATSBY_KOLLECT_FORM_KEY=your_production_keyUse in your component:
const ContactForm = () => {
const formEndpoint = `https://kollect.app/f/${process.env.GATSBY_KOLLECT_FORM_KEY}`;
return (
<form action={formEndpoint} method="POST">
{/* form fields */}
</form>
);
};TypeScript Support
// src/components/ContactForm.tsx
import React, { FormEvent, useState } from 'react';
interface FormData {
name: string;
email: string;
message: string;
}
const ContactForm: React.FC = () => {
const [formData, setFormData] = useState<FormData>({
name: '',
email: '',
message: '',
});
const [status, setStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
setStatus('submitting');
const data = new FormData();
Object.entries(formData).forEach(([key, value]) => {
data.append(key, value);
});
try {
const response = await fetch('https://kollect.app/f/YOUR_FORM_KEY', {
method: 'POST',
body: data,
});
if (response.ok) {
setStatus('success');
setFormData({ name: '', email: '', message: '' });
} else {
setStatus('error');
}
} catch (error) {
setStatus('error');
}
};
return (
<form onSubmit={handleSubmit}>
{/* form implementation */}
</form>
);
};
export default ContactForm;Next Steps
Last updated on