The Block Accessibility Checks Validation API makes it easy to test and validate block attributes directly within the WordPress editor. This guide walks you through building your first custom validation and integrating it into your block development workflow β from registration in PHP to real-time feedback in JavaScript.
Overview
Adding custom accessibility checks or block validation involves three key steps:
- Register the check (PHP) β Define what should be validated and where it applies.
 - Implement validation logic (JavaScript) β Define how your blockβs attributes are evaluated and what conditions trigger warnings or errors.
 - Enqueue your script β Load your validation in the block editor so it runs automatically.
 
Want to see it in action? Explore the Block Check Integration Example repository for a complete, ready-to-use multi-block plugin showing how everything fits together, and use it as a starting point for your own custom block validation.
Step 1: Register a Check in PHP
Use function_exists( 'ba11yc_init_plugin' ) to check if the Block Accessibility Checks plugin is active before registering your validations. If the function exists, hook into ba11yc_ready to register your external block checks. This ensures your code only runs when the plugin is available, prevents fatal errors for users who donβt have it installed, and keeps your integration fully compatible with other plugins.
// Check if Block Accessibility Checks plugin is available
if ( function_exists( 'ba11yc_init_plugin' ) ) {
    add_action( 'ba11yc_ready', 'my_plugin_register_checks' );
}
function my_plugin_register_checks( $registry ) {
    $registry->register_check(
        'my-plugin/custom-block', // Block type
        'content_length',         // Check name
        array(
            'error_msg'   => __( 'Content is too long for optimal readability', 'my-plugin' ),
            'warning_msg' => __( 'Content is long but still allowed (warning)', 'my-plugin' ),
            'description' => __( 'Long content can be difficult to read', 'my-plugin' ),
            'type'        => 'settings', // 'error', 'warning', or 'settings'
            'category'    => 'validation', // 'accessibility' or 'validation'
            'priority'    => 10,
        )
    );
}
Configuration Options
- error_msg (required, string) β The message displayed when the validation fails as an error. This should clearly describe what went wrong and how to fix it.
 - warning_msg (optional, string) β The message displayed when the validation fails as a warning. Use this for issues that donβt block publishing but still need attention.
 - description (optional, string) β A brief explanation of the check, shown in the settings interface. Useful for describing the rule or its purpose.
 - type (optional, string) β Determines how the validation behaves and whether it can be configured in the settings:
- settings β Appears in the settings page as a user-configurable option (
Error,Warning, orDisabled). - error β Always shows as an error (not user-configurable).
 - warning β Always shows as a warning (not user-configurable).
 - none β Disables the validation entirely.
 
 - settings β Appears in the settings page as a user-configurable option (
 - category (optional, string) β Defines the logical group this validation belongs to:
- accessibility β Related to WCAG or accessibility standards.
 - validation β General content or quality checks not tied to accessibility.
 
 - priority (optional, integer) β Controls the order in which multiple validations run within the same block. Lower numbers run earlier. (Default: 10).
 
Step 2: Implement Validation in JavaScript
All validation logic is handled in JavaScript, allowing instant feedback as users edit blocks. Hook into the ba11yc.validateBlock filter to inspect block attributes, perform your checks, and return validation results.
import { addFilter } from '@wordpress/hooks';
addFilter(
    'ba11yc.validateBlock',
    'my-plugin/validation',
    (isValid, blockType, attributes, checkName) => {
        // Only validate your block type
        if (blockType !== 'my-plugin/custom-block') {
            return isValid;
        }
        
        // Handle your specific check
        switch (checkName) {
            case 'content_length':
                const content = attributes.content || '';
                return content.length <= 500;
            default:
                return isValid;
        }
    }
);
Filter Parameters
- isValid (boolean) β The current validation state before your check runs. Return this unchanged if your check doesnβt apply to the current block or condition.
 - blockType (string) β The block name being validated (e.g. 
'my-plugin/custom-block'). Use this to limit checks to specific blocks. - attributes (object) β The blockβs current attributes from the editor. Access these to read and validate user input or block data.
 - checkName (string) β The unique name of the validation check as registered in PHP (e.g. 
'content_length'). This links your JavaScript logic to the corresponding PHP configuration and is especially useful when multiple validations run on the same block. - rule (optional, object) β The check configuration registered in PHP. Includes settings like 
error_msg,warning_msg,type, andcategory. 
Return Values
Your filter can return:
- true β The check passed successfully.
 - false β The check failed and should trigger the configured error or warning message.
 - isValid β Pass-through: use this when your validation does not apply to the current check.
 
Step 3: Enqueue Your JavaScript Validation Script
Your validation logic must be loaded in the block editor to run in real time. Enqueue your JavaScript file with the required dependencies, and use function_exists( 'ba11yc_init_plugin' ) to ensure the Block Accessibility Checks plugin is active before loading your script. This prevents errors and ensures your validation only runs when the plugin is available.
// Check if Block Accessibility Checks plugin is available
if ( function_exists( 'ba11yc_init_plugin' ) ) {
    add_action( 'enqueue_block_editor_assets', 'my_plugin_enqueue_assets' );
}
function my_plugin_enqueue_assets() {
    wp_enqueue_script(
        'my-plugin-accessibility-checks',
        plugins_url( 'build/accessibility-checks.js', __FILE__ ),
        array( 'wp-hooks', 'wp-i18n', 'block-accessibility-script' ),
        '1.0.0',
        true
    );
}
Important Dependencies
When enqueuing your validation script, make sure to include the following dependencies so it loads correctly in the block editor:
- wp-hooks β Required for using the 
addFilterfunction to register your validation logic. - wp-i18n β Required if your script includes translatable strings.
 - block-accessibility-script β Ensures your script loads after the Block Accessibility Checks plugin and can access its API.
 
Complete Example
Hereβs a complete working example that checks whether a custom card block includes a title. This demonstrates how to register your check in PHP and implement the corresponding JavaScript validation logic.
PHP Registration (in your plugin file):
if ( function_exists( 'ba11yc_init_plugin' ) ) {
    add_action( 'ba11yc_ready', 'my_card_register_checks' );
    add_action( 'enqueue_block_editor_assets', 'my_card_enqueue_checks' );
}
    
function my_card_register_checks( $registry ) {
    $registry->register_check(
        'my-plugin/card-block',
        'card_title_required',
        array(
            'error_msg'   => __( 'Card title is required for accessibility.', 'my-plugin' ),
            'warning_msg' => __( 'Consider adding a title to your card.', 'my-plugin' ),
            'description' => __( 'Cards should have descriptive titles.', 'my-plugin' ),
            'type'        => 'settings',
            'category'    => 'accessibility',
        )
    );
}
function my_card_enqueue_checks() {
    wp_enqueue_script(
        'my-card-checks',
        plugins_url( 'build/checks.js', __FILE__ ),
        array( 'wp-hooks', 'block-accessibility-script' ),
        '1.0.0',
        true
    );
}
JavaScript Validation (build/checks.js):
import { addFilter } from '@wordpress/hooks';
addFilter(
    'ba11yc.validateBlock',
    'my-plugin/card-validation',
    (isValid, blockType, attributes, checkName) => {
        if (blockType !== 'my-plugin/card-block') {
            return isValid;
        }
        
        if (checkName === 'card_title_required') {
            return !!(attributes.title && attributes.title.trim());
        }
        
        return isValid;
    }
);
Testing Your Integration
Follow these steps to verify that your custom validation is working correctly:
- Activate both plugins β Ensure your plugin and Block Accessibility Checks are both active.
 - Create a new post β Open the block editor and start a new post or page.
 - Add your custom block β Insert the block that includes your validation logic.
 - Check for visual feedback β Error or warning indicators should appear when validation fails.
 - Adjust settings β Go to Settings β Block Checks β [Your Plugin] to configure severity levels or disable specific checks.
 
Common First Steps
Multiple Checks for One Block
addFilter(
    'ba11yc.validateBlock',
    'my-plugin/validation',
    (isValid, blockType, attributes, checkName) => {
        if (blockType !== 'my-plugin/custom-block') {
            return isValid;
        }
        
        switch (checkName) {
            case 'title_required':
                return !!(attributes.title && attributes.title.trim());
            case 'content_length':
                return (attributes.content || '').length <= 500;
            case 'valid_url':
                return /^https?:\/\/.+/.test(attributes.url || '');
            default:
                return isValid;
        }
    }
);
Checks for Multiple Blocks
function my_plugin_register_checks( $registry ) {
    // Check for card block
    $registry->register_check(
        'my-plugin/card-block',
        'card_title_required',
        array(
            'error_msg' => __( 'Card title is required.', 'my-plugin' ),
            'type'      => 'error',
        )
    );
    
    // Check for banner block
    $registry->register_check(
        'my-plugin/banner-block',
        'banner_text_required',
        array(
            'error_msg' => __( 'Banner text is required.', 'my-plugin' ),
            'type'      => 'error',
        )
    );
}