Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To add a custom field to WordPress registration, render an input in the form your site actually uses, validate it on the server before the account is created, and save the cleaned value as user metadata after successful registration. A registration field does not automatically appear on a later profile screen; profile display and editing are separate integrations.

Understand the WordPress user-data model

Do not add a column to WordPress’s core users table for an extra registration value. Core account fields remain there, while arbitrary additional values belong in the usermeta table. WordPress describes this model in Working with User Metadata.

Choose a stable metadata key, such as company_department, and define its contract before writing code:

  • Whether the field is required or optional.
  • The accepted format and value type.
  • Whether one value or multiple values are stored.
  • Who may view or change it.
  • Whether it should be exposed through the REST API.

Collect only information that the site needs, particularly when the value could identify or profile a person.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Identify the registration form first

WordPress sites commonly use the core login-page registration, a custom theme template, a membership plugin, WooCommerce, or a custom endpoint. The register_new_user() reference documents the core login-page path. Its hooks should not be assumed to process every third-party form.

Registration surface What to verify Where the field must be handled
Core WordPress registration That the site uses the standard login-page registration flow The form’s rendering extension point, registration_errors for validation, and user_register for post-creation persistence
Theme or custom form Which template or endpoint receives the POST request That form’s rendering, request validation, and user-creation code
Membership, commerce, or profile plugin The plugin’s documented field and validation hooks The plugin’s integration API; core hooks may not run
REST or other custom endpoint How the endpoint authenticates and creates users The endpoint’s schema, authorization, validation, and metadata update logic

Core registration implementation

The following pattern applies when the site uses WordPress’s core registration flow. Replace the example key and field rules with the contract for your site.

1. Render the input in the actual registration form

Add a labeled input to the form that users submit. The markup must be present in the same request that creates the account; adding a field to an unrelated page will not capture it.

<p>
  <label for="company_department">Department<br>
    <input
      type="text"
      name="company_department"
      id="company_department"
      value="<?php echo esc_attr( wp_unslash( $_POST['company_department'] ?? '' ) ); ?>"
      autocomplete="organization-title"
    >
  </label>
</p>

For the standard login-page form, attach this output through the form extension point provided by the active WordPress version and theme. For a plugin or custom form, use that product’s documented rendering mechanism instead.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

2. Validate before account creation

registration_errors filters the WP_Error object before WordPress saves user information. WordPress’s reference says, “This filter can be used to create custom validation rules on user registration.” Return the error object on every path; an error added to it aborts account creation.

add_filter( 'registration_errors', function ( $errors, $sanitized_user_login, $user_email ) {
    $value = isset( $_POST['company_department'] )
        ? sanitize_text_field( wp_unslash( $_POST['company_department'] ) )
        : '';

    if ( '' === $value ) {
        $errors->add(
            'company_department_required',
            __( '<strong>Error:</strong> Please enter your department.' )
        );
    } elseif ( mb_strlen( $value ) > 100 ) {
        $errors->add(
            'company_department_too_long',
            __( '<strong>Error:</strong> Your department must be 100 characters or fewer.' )
        );
    }

    return $errors;
}, 10, 3 );

Server-side validation is mandatory even if JavaScript checks the field in the browser. Match the sanitizer to the data: plain text should not be treated as HTML, and an email, URL, number, date, or controlled choice needs rules appropriate to that type.

3. Save the value after successful registration

Use the new user ID to store the cleaned value as metadata only after WordPress has created the account. The user_register action fires immediately after registration and is commonly used for additional metadata passed by custom forms, as documented at the hook reference.

add_action( 'user_register', function ( $user_id ) {
    if ( ! isset( $_POST['company_department'] ) ) {
        return;
    }

    $value = sanitize_text_field( wp_unslash( $_POST['company_department'] ) );

    if ( '' !== $value ) {
        update_user_meta( $user_id, 'company_department', $value );
    }
} );

The hook documentation cautions that not all user metadata has necessarily been stored when this action fires. Treat your own field as an explicit update and do not assume every other profile property is already populated.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make the field editable on profile screens

Saving a signup value does not create a profile editor. If users or administrators must change it later in wp-admin, output the control and save it on the profile-update workflow. WordPress provides show_user_profile when a user edits their own profile and edit_user_profile when an administrator edits another user.

function itech_department_profile_field( $user ) {
    ?>
    <table class="form-table" role="presentation">
      <tr>
        <th><label for="company_department">Department</label></th>
        <td>
          <input type="text" class="regular-text" name="company_department"
                 id="company_department"
                 value="<?php echo esc_attr( get_user_meta( $user->ID, 'company_department', true ) ); ?>">
        </td>
      </tr>
    </table>
    <?php
}
add_action( 'show_user_profile', 'itech_department_profile_field' );
add_action( 'edit_user_profile', 'itech_department_profile_field' );

function itech_save_department_profile_field( $user_id ) {
    if ( ! current_user_can( 'edit_user', $user_id ) ) {
        return;
    }

    if ( ! isset( $_POST['company_department'] ) ) {
        return;
    }

    update_user_meta(
        $user_id,
        'company_department',
        sanitize_text_field( wp_unslash( $_POST['company_department'] ) )
    );
}
add_action( 'personal_options_update', 'itech_save_department_profile_field' );
add_action( 'edit_user_profile_update', 'itech_save_department_profile_field' );

For a front-end account page, implement the same authorization, validation, sanitization, and update_user_meta() flow in that page’s handler. Do not require wp-admin access when the site’s users are not meant to have it.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Register metadata and control REST exposure

register_meta( 'user', ... ) documents a metadata value’s type, whether it is single or multiple, sanitization callback, authorization callback, and REST behavior. Registering a value with show_in_rest => true makes it available through the REST API, so enable that only when the exposure is intentional.

register_meta( 'user', 'company_department', array(
    'type'              => 'string',
    'single'            => true,
    'sanitize_callback' => 'sanitize_text_field',
    'auth_callback'     => function ( $allowed, $meta_key, $object_id ) {
        return current_user_can( 'edit_user', $object_id );
    },
    'show_in_rest'      => false,
) );

If a REST response needs a computed field, custom callbacks, or a bespoke schema rather than a value under a user resource’s meta, use register_rest_field. Keep both read and update authorization deliberately narrow; profile data should not become public or writable merely because an API client requests it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Test the complete lifecycle

  1. Open the exact registration surface used by the site and confirm the field renders with a label and sensible autocomplete/type.
  2. Submit the form with the field empty, malformed, and over its permitted length. Confirm that the account is not created and a useful error is shown.
  3. Submit a valid value and confirm that the account is created.
  4. Inspect the new user’s metadata and verify the stored value is cleaned, not raw request data.
  5. Open the relevant self-edit and administrator-edit profile screens and confirm the value appears only where intended.
  6. Edit the value, save the profile, and verify authorization prevents an unauthorized update.
  7. If REST exposure is enabled, test authenticated and unauthenticated responses and update attempts separately.
  8. Repeat after switching themes or disabling the registration plugin to ensure you are testing the form that production users actually submit.

Common failure modes

  • The field displays but is always blank in metadata: the input name, submitted form, and save handler do not match, or the handler is attached to a different registration flow.
  • Invalid values still create accounts: validation is running after creation or its WP_Error object is not returned. Move the rule to the pre-creation integration point.
  • The value appears at signup but not in wp-admin: persistence and profile rendering are separate features; add the profile hooks.
  • A plugin form ignores the code: that form may use its own endpoint and extension API rather than the core registration path.
  • Sensitive data appears in REST: disable unintended show_in_rest exposure and review the metadata authorization callback.
  • The field disappears after a theme change: rendering was placed in a theme template instead of a stable plugin or site-specific integration.

Choosing the right implementation

Requirement Recommended approach
Capture one value during core signup Render the core form field, validate with registration_errors, and save on user_register.
Let administrators edit it in wp-admin Add both profile display hooks and both profile-update save hooks.
Let users edit it in a front-end account area Build a protected front-end metadata form with capability checks and server-side validation.
Use a membership or commerce registration form Follow that product’s documented field, validation, and account-profile extension points.
Expose the value to an API Register user meta with an explicit schema and authorization policy, or use register_rest_field for custom callbacks.

The durable design is the lifecycle, not a particular form: collect the value where signup occurs, reject bad data before user creation, store it as user metadata after creation, and implement later editing or API exposure as separate, permission-checked features.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.