@vulform/react
v1.1.0
Published
React components for VulForm contact form management
Downloads
5
Maintainers
Readme
@vulform/react
React components for VulForm contact form management.
Installation
npm install @vulform/react
# or
yarn add @vulform/react
# or
bun add @vulform/reactQuick Start
import { VulForm } from '@vulform/react';
function ContactPage() {
return (
<VulForm
templateId='your-template-id'
apiKey='vf_your_api_key_here'
onSuccess={response => console.log('Form submitted!', response)}
onError={error => console.error('Submission failed:', error)}
/>
);
}URL Configuration
VulForm React supports flexible URL configuration for different deployment scenarios:
1. Using VulForm SaaS (Default)
No configuration needed - automatically uses https://api.vulform.dev:
<VulForm
templateId='your-template-id'
apiKey='vf_your_api_key_here'
// apiUrl is auto-detected
/>2. Self-Hosted VulForm
Use relative URLs for same-domain deployment:
<VulForm templateId='your-template-id' apiKey='vf_your_api_key_here' apiUrl='/api/v1' />3. Custom Domain
Point to your custom VulForm instance:
<VulForm
templateId='your-template-id'
apiKey='vf_your_api_key_here'
apiUrl='https://forms.mycompany.com/api'
/>4. Environment Variables
Set up environment variables for automatic configuration:
# Next.js
NEXT_PUBLIC_VULFORM_API_KEY=vf_your_key_here
NEXT_PUBLIC_VULFORM_BASE_URL=https://forms.mycompany.com/api
# Create React App
REACT_APP_VULFORM_API_KEY=vf_your_key_here
REACT_APP_VULFORM_BASE_URL=https://forms.mycompany.com/apiThen use without props:
<VulForm
templateId='your-template-id'
// apiKey and apiUrl are read from environment variables
/>URL Resolution Priority
VulForm resolves the API URL in this order:
apiUrlprop (highest priority)- Environment variables:
NEXT_PUBLIC_VULFORM_BASE_URLorREACT_APP_VULFORM_BASE_URL - Auto-detection:
- Development:
http://localhost:3000/api/v1 - Production:
https://api.vulform.dev(SaaS)
- Development:
Props
| Prop | Type | Default | Description |
| -------------------- | -------------------------------------- | ----------------------------------------- | ----------------------------------------- |
| templateId | string | Required | Your VulForm template ID |
| apiKey | string | process.env.NEXT_PUBLIC_VULFORM_API_KEY | Your VulForm API key |
| apiUrl | string | Auto-detected | VulForm API URL |
| theme | 'auto' \| 'light' \| 'dark' | 'auto' | Form theme |
| className | string | '' | CSS class for the form container |
| style | React.CSSProperties | {} | Inline styles for the form container |
| prefill | object | {} | Pre-fill form fields |
| onSuccess | (response: any) => void | undefined | Success callback |
| onError | (error: VulFormError) => void | undefined | Error callback |
| onValidationError | (errors: ValidationErrors) => void | undefined | Validation error callback |
| onFieldChange | (field: string, value: any) => void | undefined | Field change callback |
| enableAnalytics | boolean | true | Enable form analytics |
| spamProtection | boolean | true | Enable spam protection |
| loadingState | 'default' \| 'skeleton' \| 'spinner' | 'default' | Loading state style |
| resetOnSuccess | boolean | true | Reset form after successful submission |
| showSuccessMessage | boolean | true | Show success message after submission |
| autoRedirect | boolean | false | Auto-redirect after successful submission |
Advanced Usage
Custom Styling
<VulForm
templateId='your-template-id'
className='my-custom-form'
style={{
maxWidth: '600px',
margin: '0 auto',
padding: '2rem',
backgroundColor: '#f9fafb',
borderRadius: '0.5rem',
}}
/>Form Events
<VulForm
templateId='your-template-id'
onSuccess={response => {
console.log('Form submitted successfully:', response);
// Redirect to thank you page
window.location.href = '/thank-you';
}}
onError={error => {
console.error('Form submission failed:', error);
// Show custom error message
alert(`Error: ${error.message}`);
}}
onFieldChange={(fieldName, value) => {
console.log(`Field ${fieldName} changed to:`, value);
// Custom field validation or side effects
}}
/>Pre-filling Fields
<VulForm
templateId='your-template-id'
prefill={{
name: 'John Doe',
email: '[email protected]',
company: 'Acme Corp',
}}
/>Using the Hook Directly
For more control, use the useVulForm hook:
import { useVulForm } from '@vulform/react';
function CustomForm() {
const {
template,
loading,
error,
submitting,
submitted,
formData,
validationErrors,
updateField,
submitForm,
resetForm,
} = useVulForm({
templateId: 'your-template-id',
apiKey: 'vf_your_api_key_here',
apiUrl: 'https://forms.mycompany.com/api', // Optional
onSuccess: response => console.log('Success!', response),
onError: error => console.error('Error:', error),
});
if (loading) return <div>Loading form...</div>;
if (error) return <div>Error: {error.message}</div>;
if (submitted) return <div>Thank you for your submission!</div>;
return (
<form
onSubmit={e => {
e.preventDefault();
submitForm();
}}
>
{template?.fields.map(field => (
<div key={field.id}>
<label>{field.label}</label>
<input
type={field.type}
value={formData[field.name] || ''}
onChange={e => updateField(field.name, e.target.value)}
disabled={submitting}
/>
{validationErrors[field.name] && (
<span className='error'>{validationErrors[field.name]}</span>
)}
</div>
))}
<button type='submit' disabled={submitting}>
{submitting ? 'Submitting...' : 'Submit'}
</button>
</form>
);
}Deployment Examples
Next.js App Router
// app/contact/page.tsx
import { VulForm } from '@vulform/react';
export default function ContactPage() {
return (
<div className='container mx-auto py-8'>
<h1 className='text-3xl font-bold mb-8'>Contact Us</h1>
<VulForm
templateId={process.env.NEXT_PUBLIC_VULFORM_TEMPLATE_ID}
// API key and URL are read from environment variables
onSuccess={() => {
// Handle success (e.g., show thank you message, redirect)
}}
/>
</div>
);
}Create React App
// src/components/ContactForm.jsx
import { VulForm } from '@vulform/react';
function ContactForm() {
return (
<VulForm
templateId={process.env.REACT_APP_VULFORM_TEMPLATE_ID}
// Configuration is read from REACT_APP_* environment variables
className='max-w-md mx-auto'
onSuccess={response => {
console.log('Form submitted:', response);
}}
/>
);
}
export default ContactForm;Self-Hosted Setup
// For self-hosted VulForm instance
<VulForm
templateId='your-template-id'
apiKey='vf_your_api_key_here'
apiUrl='/api/v1' // Relative URL for same-domain deployment
/>TypeScript Support
Full TypeScript support with comprehensive type definitions:
import { VulForm, VulFormProps, useVulForm } from '@vulform/react';
import type { SubmissionResponse, VulFormError, ValidationErrors } from '@vulform/core';
const formProps: VulFormProps = {
templateId: 'your-template-id',
apiKey: 'vf_your_key_here',
onSuccess: (response: SubmissionResponse) => {
console.log('Success:', response);
},
onError: (error: VulFormError) => {
console.error('Error:', error);
},
onValidationError: (errors: ValidationErrors) => {
console.log('Validation errors:', errors);
},
};
export default function TypedForm() {
return <VulForm {...formProps} />;
}Components
VulForm
The main component that renders a complete form based on a template.
<VulForm
templateId='contact-form'
apiKey='vf_abc123' // Optional if set in env
apiUrl='/api/v1' // Optional, defaults to /api/v1
// Styling
theme='auto' // 'auto' | 'light' | 'dark' | custom theme object
className='my-form'
// Data
prefill={{ name: 'John Doe' }}
// Event handlers
onSuccess={response => console.log('Success!', response)}
onError={error => console.error('Error:', error)}
onValidationError={errors => console.log('Validation errors:', errors)}
onFieldChange={(fieldName, value) => console.log('Field changed:', fieldName, value)}
// Features
enableAnalytics={true}
spamProtection={true}
resetOnSuccess={true}
showSuccessMessage={true}
/>Individual Components
import { FormField, FormLoader, FormSuccess, FormErrorComponent } from '@vulform/react';
// Custom loading state
<FormLoader loadingState="custom" />
// Success message
<FormSuccess
message="Thank you!"
onReset={() => resetForm()}
/>
// Error display
<FormErrorComponent
error={{ code: 'NETWORK_ERROR', message: 'Connection failed' }}
onRetry={() => retrySubmission()}
/>Hooks
useVulForm
Custom hook for building your own form components:
import { useVulForm } from '@vulform/react';
function CustomForm() {
const {
template,
loading,
error,
submitting,
formData,
validationErrors,
updateField,
submitForm,
resetForm,
} = useVulForm({
templateId: 'contact-form',
onSuccess: response => console.log('Success!'),
onError: error => console.error('Error:', error),
});
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<form
onSubmit={e => {
e.preventDefault();
submitForm();
}}
>
{template?.fields.map(field => (
<input
key={field.id}
type={field.type}
value={formData[field.name] || ''}
onChange={e => updateField(field.name, e.target.value)}
/>
))}
<button type='submit' disabled={submitting}>
{submitting ? 'Sending...' : 'Submit'}
</button>
</form>
);
}useFieldValidation
Real-time field validation:
import { useFieldValidation } from '@vulform/react';
function EmailField({ field, apiClient }) {
const [value, setValue] = useState('');
const { error, isValidating } = useFieldValidation({
field,
value,
apiClient,
debounceMs: 300,
});
return (
<div>
<input
value={value}
onChange={e => setValue(e.target.value)}
style={{ borderColor: error ? 'red' : undefined }}
/>
{isValidating && <span>Validating...</span>}
{error && <span style={{ color: 'red' }}>{error}</span>}
</div>
);
}Styling
CSS Variables
VulForm components use CSS variables that you can customize:
.vulform-container {
--vulform-primary: #3b82f6;
--vulform-secondary: #1e40af;
--vulform-background: #ffffff;
--vulform-text: #374151;
--vulform-border: #d1d5db;
--vulform-border-radius: 0.5rem;
--vulform-font-family: 'Inter', sans-serif;
--vulform-font-size: 1rem;
--vulform-spacing: 1rem;
}Custom Themes
const customTheme = {
primaryColor: '#10b981',
secondaryColor: '#059669',
backgroundColor: '#f9fafb',
textColor: '#111827',
borderColor: '#d1d5db',
borderRadius: '0.75rem',
fontFamily: 'system-ui',
fontSize: '1rem',
spacing: '1.5rem',
};
<VulForm templateId='contact-form' theme={customTheme} />;Tailwind CSS
VulForm works great with Tailwind CSS. Components include sensible default classes:
<VulForm
templateId='contact-form'
className='max-w-2xl mx-auto p-6 bg-white rounded-lg shadow-lg'
/>Form Templates
Create form templates in the VulForm dashboard, then reference them by ID:
// Template ID from dashboard
<VulForm templateId='cmc2o5rpm0007ju0d4et2g97d' />Templates include:
- Field definitions (text, email, textarea, select, etc.)
- Validation rules
- Layout settings (vertical, horizontal, grid)
- Styling and themes
- Success/error messages
Error Handling
import { VulFormError } from '@vulform/react';
<VulForm
templateId='contact-form'
onError={(error: VulFormError) => {
switch (error.code) {
case 'MISSING_API_KEY':
console.error('API key not configured');
break;
case 'TEMPLATE_NOT_FOUND':
console.error('Form template not found');
break;
case 'RATE_LIMIT_EXCEEDED':
console.error('Too many requests');
break;
case 'NETWORK_ERROR':
console.error('Network connection failed');
break;
default:
console.error('Unknown error:', error.message);
}
}}
/>;📦 CDN Usage
Via unpkg.com:
<script src="https://unpkg.com/@vulform/react@latest/dist/index.js"></script>Via jsDelivr:
<script src="https://cdn.jsdelivr.net/npm/@vulform/react@latest/dist/index.js"></script>Note: For React applications, we recommend using the npm package for better tree-shaking and TypeScript support.
License
MIT
