ESM Import & Programmatic Use

Import Babel Shield as an ES module for full programmatic control -- direct moderation calls, cache monitoring, rate limit tracking, and manual form management.

Import and Initialize

Load Babel Shield as an ES module using the CDN:


<script type="module">
  import BabelShield from 'https://cdn.babelshield.ai/v1/babel-shield.mjs';

  const result = await BabelShield.init({
    apiToken: 'YOUR_API_TOKEN',
    debug: true,
    cache: {enabled: true},
    feedback: {
      mode: 'inline',
      messages: {
        spam: 'Spam content detected. Please revise.',
        default: 'Content blocked by moderation.'
      }
    }
  });

  if (result.success) {
    console.log('Babel Shield initialized');
  }
</script>

Forms are still protected automatically when using ESM imports. The difference is that you also get access to the full programmatic API.

Direct Moderation

Call BabelShield.moderate() to check content without a form submission:

String content:

const result = await BabelShield.moderate('Check this text for issues');

if (result.flagged) {
  console.log('Flagged for:', result.maxCategory);
  console.log('Score:', result.maxScore);
}
else {
  console.log('Content is clean');
}

Object payload:

const result = await BabelShield.moderate({
  name: 'John Doe',
  email: '[email protected]',
  message: 'I would like more information about your services.'
});

When you pass an object, all string values are concatenated and sent for moderation.

Response Structure

The moderate() method returns a result object with these fields:

const result = await BabelShield.moderate('Check this text');

// result contains:
{
  // Flagging
  flagged: true,                        // Whether content exceeded any threshold
  categoriesFlagged: ['spam'],          // Array of flagged category keys

  // Scores (0-100 integers)
  scores: {                             // Canonical category scores the API returned
    spam: 85, profanity: 10, sexual: 0, offensive: 5,
    violence: 0, hate: 0, harassment: 0, 'self-harm': 0,
    deception: 0, garbage: 0, crypto: 0, illicit: 0,
    injection: 0
  },
  totalScore: null,                     // Optional API aggregate -- often null; use maxScore/primaryScore

  // Highest-scoring category -- resolved two independent ways, so these can differ:
  primaryCategory: 'spam',              // Server primary_category, else client-computed maxCategory
  primaryScore: 85,                     // meta.primary_score, else scores[primaryCategory], else client maxScore
  maxCategory: 'spam',                  // Client-computed highest scorer across returned scores
  maxScore: 85,                         // Client-computed highest score
  maxSeverity: 'critical',             // 'low' | 'medium' | 'high' | 'critical'

  // Threshold info
  effectiveThresholds: { spam: 70 },    // Thresholds the server used for flagging (empty {} when none)

  // Optional fields
  summary: 'Content appears to be...',  // AI summary (only when the API returns one)

  // Cache status
  cached: true                          // Only present on client-side (browser LRU) cache hits
}

Note: meta (request metadata including reqId, responseTime, handlersExecuted, and the advisory relevanceFlag) is also available. meta.relevanceFlag is an off-topic-for-source signal (true/false/null) -- it is advisory only and never affects flagged. Use optional chaining when accessing meta fields, as they vary by API version.

Note: The API returns all 13 canonical categories in scores. The parser keeps only the finite numeric scores it receives, so as a defensive practice still default any missing key to 0 via optional chaining:

const spam = result.scores?.spam ?? 0;

Cache Statistics

Identical content within the cache TTL (30 minutes by default) is served from cache without an API call:

const stats = BabelShield.getCacheStats();
console.log('Cache hits:', stats.hits);
console.log('Cache misses:', stats.misses);
console.log('Hit rate:', Math.round(stats.hitRate * 100) + '%');
console.log('Cache size:', stats.size);

Rate Limit Monitoring

Client-side rate limits are 60 requests per minute and 1000 requests per hour. These limits reset on page reload. Server-side rate limits are separate and enforced by the API.

const status = BabelShield.getRateLimitStatus();
// status = {
//   used:      { minute, hour },   // requests made in each window
//   remaining: { minute, hour },   // requests still allowed
//   limits:    { perMinute, perHour },
//   resetIn:   { minute, hour }    // ms until each window resets (null when empty)
// }
console.log('Requests this minute:', status.used.minute);
console.log('Requests this hour:', status.used.hour);

Check before making a request:

if (BabelShield.isNearRateLimit()) {
  console.warn('Approaching rate limit -- consider batching requests');
  return;
}

await BabelShield.moderate(content);

Manual Form Control

Attaching and Detaching Forms

Use the form handler module to control which forms are protected:

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

// Check if a form is protected
const isProtected = formHandler.isProtected(myForm);

// Manually attach protection to a form
formHandler.attachForm(myForm);

// Remove protection from a form
formHandler.detachForm(myForm);

// Get total protected form count
console.log('Protected forms:', formHandler.getFormCount());

Pre-Validation

Validate a form's content without actually submitting it. This is useful for a "check content" button separate from the submit button:

const result = await formHandler.validateForm(myForm);

if (result.flagged) {
  console.log('Would be blocked for:', result.maxCategory, '(score:', result.maxScore + ')');
}
else {
  console.log('Would be approved (score:', result.maxScore + ')');
}

Event System

Listen to events for custom behavior. Use on() for persistent listeners and once() for one-time listeners:

Event Payload When Fired
ready -- Initialization complete, form handler loaded
form:detected { form } New form found and protected
form:submit { form, payload } Form submission intercepted
form:validated { form, result } Moderation result received
form:blocked { form, result, category } Submission blocked
form:approved { form, result } Submission approved
// One-time ready handler
BabelShield.once('ready', () => {
  const formHandler = BabelShield.getModule('form-handler');
  console.log('Protected forms:', formHandler.getFormCount());
});

// Log every form detection
BabelShield.on('form:detected', ({form}) => {
  console.log('Form protected:', form.id);
});

// Track blocked submissions
BabelShield.on('form:blocked', ({form, result, category}) => {
  console.log('Blocked:', form.id, 'for', category, '(score:', result.maxScore + ')');
});

// Track approved submissions
BabelShield.on('form:approved', ({form, result}) => {
  console.log('Approved:', form.id, '(score:', result.maxScore + ')');
});

Next Steps