Registering Actions
registerFormAction(type, handler) adds your handler to the global control registry so Atlas Forms can find it by type key. Registration must happen before any form that uses the action type is rendered. This page covers timing, collision avoidance, and how to verify registration.
The Registration API
import { registerFormAction } from '@atlas-forms/control-registry-js';
// Register a handler
registerFormAction(
'my-org:send-email', // Type key (namespace:name recommended)
myEmailHandler // The FormActionHandler function
);
Naming Convention — Namespace Your Types
Built-in action types use simple names (submit, cancel). Custom action types should use a namespace prefix to avoid collisions with built-ins and other libraries:
| Pattern | Example | Use For |
|---|---|---|
orgname:action | bizfirst:approve-workflow | Internal company actions |
product:action | guardrails:activate-policy | Product-specific actions |
@package/action | @myorg/crm:link-account | Published library actions |
When to Register
Registration must happen before any form component renders. The correct place is application startup — typically main.tsx or the file imported first:
// main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { AtlasFormsClient } from '@atlas-forms/client-js';
import { registerMyActions } from '@myorg/my-action-library';
// 1. Initialise client
AtlasFormsClient.getInstance({ apiBaseUrl: '...' });
// 2. Register action libraries BEFORE rendering
registerMyActions();
registerOtherActions();
// 3. Now render the app
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode><App /></React.StrictMode>
);
Verifying Registration
import { getControlRegistry } from '@atlas-forms/control-registry-js';
const registry = getControlRegistry();
// Check if an action type is registered
const isRegistered = registry.hasAction('my-org:send-email');
console.log(isRegistered); // true
// List all registered action types
const allActions = registry.getActionTypes();
console.log(allActions); // ['submit', 'cancel', ..., 'my-org:send-email']
Overriding Built-In Actions
You can override a built-in action type by registering a handler with the same key. Use this sparingly — built-in overrides affect all forms in the application:
// Override the submit action globally
registerFormAction('submit', async (ctx) => {
// Custom pre-submit logic (e.g., analytics event)
analytics.track('form_submitted', { formId: ctx.formId });
// Still validate and call onSubmit
await ctx.validate();
ctx.complete();
});
// Warning: this replaces the built-in submit behavior entirely