Form Handler

Full control over form protection -- feedback display, severity colors, dynamic form detection, and submission callbacks.

Feedback Modes

Inline (Default)

A message appears below the form when content is blocked. This is the default mode.

BabelShield.init({
  apiToken: 'YOUR_API_TOKEN',
  feedback: {mode: 'inline'}
});

Modal

A dialog overlay appears with the blocked message and a severity-colored header. The modal includes accessibility features: focus trap, Escape key to close, and Tab cycles through focusable elements.

BabelShield.init({
  apiToken: 'YOUR_API_TOKEN',
  feedback: {
    mode: 'modal',
    showDetails: true,
    showSummary: true
  }
});

Silent

No visible feedback. The form submission is blocked, but no message is shown. Combine with callbacks or event handlers for a fully custom UI.

BabelShield.init({
  apiToken: 'YOUR_API_TOKEN',
  feedback: {
    mode: 'silent',
    onBlocked: (result, form) => {
      // Build your own feedback UI
      console.log('Blocked for:', result.maxCategory);
    }
  }
});

Per-Form and Per-Field Exclusion

Excluding Entire Forms

Add data-babel-shield-ignore to skip a form entirely:


<form data-babel-shield-ignore
      action="/internal">
  <!-- This form is NOT moderated -->
</form>

Or use the excludeForms config option to exclude forms by CSS selector:

BabelShield.init({
  apiToken: 'YOUR_API_TOKEN',
  excludeForms: '[data-babel-shield-ignore], #admin-form, .internal-form'
});

Excluding Specific Fields

Add data-babel-shield-ignore to individual inputs. The rest of the form is still moderated.


<form>
  <input type="text"
         name="username">          <!-- Moderated -->
  <input type="text"
         name="coupon"
         data-babel-shield-ignore>             <!-- NOT moderated -->
  <textarea name="message"></textarea>          <!-- Moderated -->
</form>

This is useful for coupon codes, reference numbers, or other structured data that should not be sent for moderation.

Severity Color Customization

Feedback messages are color-coded by severity. The default colors are:

Severity Score Range Default Color
Low 0-25 #ffc107 (yellow)
Medium 26-50 #fd7e14 (orange)
High 51-75 #dc3545 (red)
Critical 76-100 #721c24 (dark red)

Setting Colors at Init

BabelShield.init({
  apiToken: 'YOUR_API_TOKEN',
  feedback: {
    mode: 'inline',
    colors: {
      low: '#17a2b8',
      medium: '#ffc107',
      high: '#fd7e14',
      critical: '#dc3545'
    }
  }
});

Updating Colors at Runtime

const {ValidationUI} = BabelShield.getModule('form-handler');

ValidationUI.setColors({
  low: '#17a2b8',
  medium: '#ffc107',
  high: '#fd7e14',
  critical: '#dc3545'
});

// Reset to defaults
const defaults = ValidationUI.getDefaultColors();
ValidationUI.setColors(defaults);

Submission Callbacks

The onBlocked and onApproved callbacks fire for all feedback modes -- not just silent. This means you can show inline feedback and also run custom logic.

BabelShield.init({
  apiToken: 'YOUR_API_TOKEN',
  feedback: {
    mode: 'inline',
    onBlocked: (result, form) => {
      // result contains: flagged, scores, maxScore, maxCategory, maxSeverity, summary
      analytics.track('form_blocked', {
        category: result.maxCategory,
        score: result.maxScore
      });
    },
    onApproved: (result, form) => {
      // result contains: flagged, scores, maxScore, maxCategory
      analytics.track('form_approved', {
        score: result.maxScore
      });
    }
  }
});

Dynamic Forms and SPA Support

Babel Shield uses a MutationObserver to detect forms added to the DOM after page load. New forms are automatically protected with a ~50ms debounce delay.

// Adding a form dynamically -- it is detected and protected automatically
const newForm = document.createElement('form');
const textarea = document.createElement('textarea');
textarea.name = 'message';
textarea.placeholder = 'Your message';
const button = document.createElement('button');
button.type = 'submit';
button.textContent = 'Send';
newForm.appendChild(textarea);
newForm.appendChild(button);
document.body.appendChild(newForm);
// Protection attaches automatically (~50ms delay)

To force a re-scan after major DOM changes, call refresh():

const formHandler = BabelShield.getModule('form-handler');
formHandler.refresh();

Full Event Reference

Event Payload Description
ready -- Form handler initialized, all initial forms protected
form:detected { form } New form detected (initial scan or DOM mutation)
form:submit { form, payload } Submission intercepted, moderation pending
form:validated { form, result } Moderation result received
form:blocked { form, result, category } Submission blocked (content flagged)
form:approved { form, result } Submission approved (content clean)
api:request { url, categories } API request sent (skipped on a local cache hit)
api:response the parsed result object API response received (cached: true on a local cache hit)
api:error { error } API request failed

Note: Use once('ready') for one-time initialization. Use on('form:detected') for per-form logging or stats updates.

Showing Moderation Details

Control how much information the feedback message shows:

BabelShield.init({
  apiToken: 'YOUR_API_TOKEN',
  feedback: {
    mode: 'inline',
    showDetails: true,   // Show per-category scores
    showSummary: true    // Show AI-generated summary (if available)
  }
});
  • showDetails: true -- displays the individual category scores that triggered the flag
  • showSummary: true -- displays the AI-generated response summary (only present when the API returns one)

Next Steps