@lub-crm/forms
v1.0.2
Published
Embeddable form library for Lub CRM
Downloads
18
Readme
@lub-crm/forms
Embeddable form library for Lub CRM. Render dynamic forms that integrate with Lub CRM for lead capture and data collection.
Features
- Multiple deployment options: React component, UMD script, or standalone bundle
- Multi-step form support with progress indicators
- Conditional field visibility and requirements
- Dynamic validation with Zod schemas
- CRM field mapping for automatic lead creation
- UTM parameter tracking
- Customizable styling via CSS variables
- 17+ field types including country/state selectors
Installation
NPM Package (React Apps)
npm install @lub-crm/forms
# or
bun add @lub-crm/formsScript Tag (Standalone)
No build step required. Includes React and all dependencies:
<script src="https://forms.lub.marketing/v1/lub-forms.standalone.js"></script>Script Tag (UMD)
For pages that already have React loaded:
<script src="https://unpkg.com/react@19/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@19/umd/react-dom.production.min.js"></script>
<script src="https://forms.lub.marketing/v1/lub-forms.umd.js"></script>
<link rel="stylesheet" href="https://forms.lub.marketing/v1/lub-forms.css" />Usage
React Component
import { LubForm } from "@lub-crm/forms";
import "@lub-crm/forms/styles";
function ContactPage() {
return (
<LubForm
formId="abc123"
baseUrl="https://api.lub.marketing"
onSuccess={(data) => {
console.log("Submission ID:", data.submission_id);
window.location.href = "/thank-you";
}}
onError={(error) => {
console.error("Submission failed:", error.message);
}}
/>
);
}Script Tag (Auto-mount)
Forms automatically mount to elements with data-lub-form-id:
<div
data-lub-form-id="abc123"
data-lub-base-url="https://api.lub.marketing"
data-lub-class="my-custom-class"
data-lub-on-success="handleSuccess"
data-lub-on-error="handleError"
></div>
<script>
function handleSuccess(data) {
window.location.href = "/thank-you";
}
function handleError(error) {
alert("Something went wrong");
}
</script>Script Tag (Manual Render)
<div id="my-form"></div>
<script>
LubForms.render("abc123", "my-form", {
baseUrl: "https://api.lub.marketing",
onSuccess: (data) => {
console.log("Success!", data);
},
onError: (err) => {
console.error("Error:", err);
},
designOverrides: {
primary_color: "#8b5cf6",
},
});
</script>Props / Options
| Prop | Type | Description |
| ------------------- | ------------------------------------------ | ------------------------------------------- |
| formId | string | Form ID from Lub CRM (required) |
| baseUrl | string | API base URL |
| onSuccess | (data: SubmitFormResponse) => void | Called on successful submission |
| onError | (error: ApiError) => void | Called on submission error |
| onValidationError | (errors: Record<string, string>) => void | Called when validation fails |
| onStepChange | (step: number, total: number) => void | Called when multi-step form changes step |
| className | string | Additional CSS class for the form container |
| style | CSSProperties | Inline styles |
| designOverrides | Partial<FormDesign> | Override form design settings |
Field Types
| Type | Description |
| ---------------- | --------------------------- |
| text | Single-line text input |
| textarea | Multi-line text input |
| email | Email input with validation |
| phone | Phone number input |
| number | Numeric input with min/max |
| url | URL input with validation |
| date | Date picker |
| time | Time picker |
| datetime | Date and time picker |
| select | Dropdown select |
| radio | Radio button group |
| checkbox | Single checkbox |
| checkbox_group | Multiple checkboxes |
| file | File upload |
| hidden | Hidden field |
| country | Country selector |
| state | State/province selector |
| html | Static HTML content |
| divider | Visual divider |
| recaptcha | reCAPTCHA v2/v3 |
Styling
Forms are styled using CSS variables. Override them via designOverrides or CSS:
.lub-form {
--lub-primary-color: #3b82f6;
--lub-background-color: #ffffff;
--lub-text-color: #1f2937;
--lub-border-color: #e5e7eb;
--lub-font-family: system-ui, sans-serif;
--lub-font-size: 14px;
--lub-padding: 24px;
--lub-field-spacing: 16px;
}Or via JavaScript:
<LubForm
formId="abc123"
designOverrides={{
primary_color: "#8b5cf6",
background_color: "#fafafa",
font_family: "Inter, sans-serif",
button_style: {
border_radius: "9999px",
full_width: true,
},
}}
/>Conditional Logic
Fields support conditional visibility and requirements based on other field values:
// Show field when another field equals a value
conditional_logic: {
show_if: {
field_name: 'interest',
operator: 'equals',
value: 'other'
}
}
// Make field required based on condition
conditional_logic: {
required_if: {
field_name: 'newsletter',
operator: 'equals',
value: true
}
}Operators: equals, not_equals, contains, not_contains, greater_than, less_than, is_empty, is_not_empty
Custom Field Components
Register custom field types for advanced use cases:
import { registerFieldComponent } from "@lub-crm/forms";
registerFieldComponent("rating", ({ field, register, error }) => (
<div className="rating-field">
{[1, 2, 3, 4, 5].map((value) => (
<label key={value}>
<input type="radio" value={value} {...register(field.name)} />
{"⭐".repeat(value)}
</label>
))}
{error && <span className="error">{error}</span>}
</div>
));API Client
Use the client directly for custom integrations:
import { LubFormsClient } from "@lub-crm/forms";
const client = new LubFormsClient("https://api.lub.marketing");
// Fetch form definition
const form = await client.getForm("abc123");
// Submit form data
const response = await client.submitForm("abc123", {
data: { email: "[email protected]", name: "John" },
utm_parameters: { source: "landing-page" },
referrer: window.location.href,
});
// Confirm double opt-in
const confirmation = await client.confirmOptIn("token123");Global API (Script Tag)
When using the standalone or UMD build:
// Render a form
LubForms.render(formId, containerIdOrElement, options);
// Auto-mount all forms with data-lub-form-id
LubForms.autoMount();
// Unmount a specific form
LubForms.unmount(containerId);
// Unmount all forms
LubForms.unmountAll();
// Initialize (called automatically)
LubForms.init();Development
bun install
bun run dev # Start dev server on :5174
bun run build # Build all formats
bun run lint # Run ESLint
bun run typecheck # TypeScript checkBuild Outputs
| File | Format | Use Case |
| ------------------------------ | ------ | ------------------------------ |
| dist/lub-forms.es.js | ESM | NPM package for React apps |
| dist/lub-forms.umd.js | UMD | Script tag with React on page |
| dist/lub-forms.standalone.js | IIFE | Drop-in script, bundles React |
| dist/lub-forms.css | CSS | Shared styles (UMD/ESM builds) |
License
MIT
