View on GitHub

React Hook Form Plus

(RHF+)

JSX Error Messages

Purpose

The JSX error messages enhancement allows developers to use React elements (ReactElement) as error messages instead of being limited to plain strings. This enables rich and interactive formatted error displays while maintaining full backward compatibility with existing string-based error messages.

Benefits

API Changes

Property updates

// Enhanced: now accepts React elements
export type Message = string | React.ReactElement;

All existing methods that work with error messages now support React elements:

Description

The JSX error messages enhancement allows developers to use React elements (ReactElement) as error messages instead of being limited to plain strings while maintaining full backward compatibility with existing string-based error messages.

Behavior

JSX error messages work seamlessly with all existing validation patterns and render in the same React context as your form component.

Examples

Basic JSX error messages

import { useForm } from '@bombillazo/rhf-plus';

function BasicExample() {
  const {
    register,
    formState: { errors },
  } = useForm();

  return (
    <form>
      <input
        {...register('username', {
          required: (
            <span style=>
              <strong>Username is required</strong> 📝
            </span>
          ),
          minLength: {
            value: 3,
            message: (
              <div>
                Username must be at least <em>3 characters</em> long
                <br />
                <small>Choose something memorable!</small>
              </div>
            ),
          },
        })}
      />
      {errors.username && <div>{errors.username.message}</div>}
    </form>
  );
}

Dynamic error messages with setError

import { useForm } from '@bombillazo/rhf-plus';

function DynamicErrorExample() {
  const {
    register,
    setError,
    formState: { errors },
  } = useForm();

  const handleUsernameCheck = async (username) => {
    const isAvailable = await checkUsernameAvailability(username);

    if (!isAvailable) {
      setError('username', {
        type: 'availability',
        message: (
          <div
            style=
          >
            <strong>❌ Username "{username}" is not available</strong>
            <div style=>
              Try one of these suggestions:
              <ul style=>
                <li>{username}123</li>
                <li>{username}_user</li>
                <li>the_{username}</li>
              </ul>
            </div>
          </div>
        ),
      });
    }
  };

  return (
    <form>
      <input
        {...register('username')}
        onBlur={(e) => handleUsernameCheck(e.target.value)}
      />
      {errors.username && <div>{errors.username.message}</div>}
    </form>
  );
}

Limitations

1. ReactElement only

Only React elements are supported, not all ReactNode types:

// ✅ Supported: React elements
message: <div>Error message</div>;
message: <ErrorComponent />;

// ❌ Not supported: Primitives
message: null;
message: 42;
message: undefined;

2. Synchronous only

Error messages must be synchronous React elements:

// ✅ Supported: Synchronous elements
message: <div>Immediate error</div>;

// ❌ Not supported: Promises or async components
message: Promise.resolve(<div>Async error</div>);

3. Context limitations

JSX error messages render in the same React context as your form component. If you need different context (like themes, i18n), ensure providers are available at the form level.

Backward Compatibility

This enhancement is fully backward compatible: