FORM INTELLIGENCE, EXPLAINED.
Your form. A small SDK.
Add Form Intelligence with a small JavaScript script. Any HTML form, with or without a framework.
Set up your project first.
Create a project in the FormLint app, save your rules and field mapping, add the exact allowed website origins, and create a public project key. Use your configured evaluation service URL for the endpoint.
The example uses one named field, description. Replace the example hosts and key with your own installation details, and match the field names to your saved configuration.
Connect your existing form.
Keep your original form’s action, method and submit logic. The widget adds suggestions directly below the mapped field after an edit. No separate results container is needed.
<form id="quote">
<label>
Describe your project
<textarea name="description"></textarea>
</label>
<button type="submit">Request a quote</button>
</form>
<script type="module">
import { attach, getProvider }
from 'https://YOUR_SITE_HOST/sdk/formlint.mjs';
const endpoint = 'https://YOUR_EVALUATION_HOST/evaluate';
const key = 'YOUR_PROJECT_PUBLIC_KEY';
try {
const provider = await getProvider(endpoint, key);
const widget = attach({
form: document.querySelector('#quote'),
endpoint,
key,
fields: ['description'],
locale: 'auto',
provider
});
// On component unmount, call widget.destroy().
} catch {
// Leave the host form usable and quiet when discovery is unavailable.
}
</script>The script is served from your public site at /sdk/formlint.mjs. Building the site exports the SDK; it does not depend on a third-party CDN.
Match the inputs your form already uses.
The array form, fields: ['description'], connects a saved project field to a supported input with the same name inside your form. If its existing name is different, map the project field ID to a CSS selector instead:
fields: {
description: 'textarea[name="project_brief"]',
delivery_method: 'select[name="delivery"]'
}Save both description and delivery_method in FormLint’s allowed field names. Each selector must match exactly one supported input belonging to the target form. Keep the native names so your existing submission continues to receive the fields it expects.
Map up to four fields, with at most 4,000 characters each. Supported controls are textareas, text and number inputs, single selects and individual checkboxes. Files, grouped controls, multiple selects, sensitive input types and disabled fields are excluded. Map only fields present together in the form; FormLint does not retain answers between form pages.
All mapped answers are evaluated together. Choose where each rule’s suggestion appears in the rule editor.
Using a JavaScript project?
Install the built package from your FormLint site:
npm install https://YOUR_SITE_HOST/sdk/formlint-widget-0.1.0.tgzThen import attach and getProvider from @formlint/widget. Keep asset and server versions compatible when upgrading. For components that mount and unmount, call widget.destroy() during cleanup.
Using Webflow?
Connect a form on your own Webflow page with the JavaScript SDK above. Give the form and its fields stable names. The SDK places feedback directly below mapped fields automatically. Add the module script before the closing body tag in your page’s custom code, using your project key and evaluation URL.
Your Webflow plan must support custom code. Test on the published page and allow that exact origin in FormLint. Keep Webflow’s existing form submission behavior. See Webflow’s custom code guide.
Using WordPress?
The same JavaScript SDK connects forms rendered on your WordPress page. Load the module through your theme or a site-specific plugin, then attach it after the form exists. Your installation must allow custom JavaScript. Follow WordPress’s script module guide to load modules through WordPress.
Using Elementor or Gravity Forms? Download the WordPress ZIP from either integration guide.
In both platforms, the script needs access to the form in the same page. It cannot reach fields inside a third-party iframe. Webflow and WordPress compatibility uses JavaScript; it is separate from the official plugins.
Follow your visitor’s language.
English and Italian are supported. The default locale: 'auto' follows <html lang="it-IT">, including runtime changes. Use locale: 'it' to override it, or call widget.setLocale('it') from your language switcher. Call widget.setLocale('auto') to follow the page again.
Set the default language in Form setup and add visitor-message translations under each rule’s Translations. Every rule must be translated before that language becomes available. Missing or unsupported languages use the project default for all messages. Translations are written by you; checks and thresholds stay the same.
Visible suggestions, loading, success and error messages switch without another evaluation. Auto uses the form’s own document language: an embedded cross-origin form cannot read the parent page’s language. Set an explicit locale inside that integration when needed.
It works around your form.
- Waits for a typing pause. Choose Slow (2 seconds), Medium (1.2 seconds), Fast (500 ms) or Custom in the project’s Form setup. Typing restarts the timer; leaving a field does not trigger an extra check. Reload the form after saving a timing change.
- Ignores stale results. An older response cannot replace suggestions for a newer answer.
- Respects disabled controls. Disabled fields are excluded from evaluation.
- Leaves submission alone. The SDK never registers a submit handler. Unavailable suggestions do not block the host form.
Not seeing a suggestion?
Check that the public key is active, the exact page origin is allowed, and your field names match the saved mapping. Confirm that the evaluation URL is reachable and the workspace quota has capacity.
In simulated mode, only supported exact synthetic examples return fixture results. Arbitrary text returning unavailable is expected. If the processing mode changes, reload or reconnect the SDK.