The default WooCommerce registration form is intentionally minimal, it only collects a username, email address, and password. For many online store owners, this level of information is simply not enough. Whether you run a wholesale shop that needs a business name, a service-based store that requires a phone number, or a membership site that asks for specific preferences, collecting the right data at the point of registration can make a significant difference in how you manage customers and personalize their experience.
This guide covers three proven methods to add custom fields to your WooCommerce registration form, using PHP code with action hooks, using the built-in woocommerce_form_field() function, and using a dedicated plugin, along with best practices and common troubleshooting tips.

Adding custom fields to the WooCommerce registration form goes beyond simple data collection. Here are the key benefits:
Before adding any custom fields, make sure the registration form is actually visible on your store. By default, it may be disabled.
Once this is done, a registration form will appear on the My Account page at the front end of your store.
This method involves adding code directly to your theme’s functions.php file (or a custom plugin). It gives you full control and doesn’t require installing any additional plugins.
Important: Always use a child theme when editing functions.php. Modifying the parent theme file means your changes will be lost when the theme updates.
WooCommerce provides several action hooks that let you inject HTML fields at different positions in the registration form:
woocommerce_register_form_start: Adds fields at the very beginning of the formwoocommerce_register_form: Adds fields just before the Register buttonwoocommerce_register_form_end: Adds content after the Register buttonHere’s an example that adds First Name, Last Name, and Phone Number fields:
function custom_woocommerce_registration_fields() {
?>
<p class="form-row form-row-first">
abel for="reg_billing_first_name">
<?php _e( 'First name', 'woocommerce' ); ?> <span class="required">*</span>
</label>
<input type="text" class="input-text" name="billing_first_name" id="reg_billing_first_name"
value="<?php if ( ! empty( $_POST['billing_first_name'] ) ) esc_attr_e( $_POST['billing_first_name'] ); ?>" />
</p>
<p class="form-row form-row-last">
abel for="reg_billing_last_name">
<?php _e( 'Last name', 'woocommerce' ); ?> <span class="required">*</span>
</label>
<input type="text" class="input-text" name="billing_last_name" id="reg_billing_last_name"
value="<?php if ( ! empty( $_POST['billing_last_name'] ) ) esc_attr_e( $_POST['billing_last_name'] ); ?>" />
</p>
<p class="form-row form-row-wide">
abel for="reg_billing_phone">
<?php _e( 'Phone number', 'woocommerce' ); ?>
</label>
<input type="text" class="input-text" name="billing_phone" id="reg_billing_phone"
value="<?php esc_attr_e( $_POST['billing_phone'] ); ?>" />
</p>
<div class="clear"></div>
<?php
}
add_action( 'woocommerce_register_form_start', 'custom_woocommerce_registration_fields' );
Fields prefixed with billing_ are automatically linked to the WooCommerce billing address system. The following standard billing fields are available:
| Field Name | Description |
| billing_first_name | Customer first name |
| billing_last_name | Customer’s last name |
| billing_company | Company name |
| billing_address_1 | Primary street address |
| billing_address_2 | Apartment, suite, etc. |
| billing_city | City |
| billing_postcode | Postal / ZIP code |
| billing_country | Country |
| billing_state | State or province |
| billing_email | Email address |
| billing_phone | Phone number |
After adding the fields, add validation logic to ensure users submit correct data. The woocommerce_register_post hook is designed for this purpose:
function custom_validate_registration_fields( $username, $email, $validation_errors ) {
if ( isset( $_POST['billing_first_name'] ) && empty( $_POST['billing_first_name'] ) ) {
$validation_errors->add(
'billing_first_name_error',
__( '<strong>Error</strong>: First name is required!', 'woocommerce' )
);
}
if ( isset( $_POST['billing_last_name'] ) && empty( $_POST['billing_last_name'] ) ) {
$validation_errors->add(
'billing_last_name_error',
__( '<strong>Error</strong>: Last name is required!', 'woocommerce' )
);
}
return $validation_errors;
}
add_action( 'woocommerce_register_post', 'custom_validate_registration_fields', 10, 3 );
This code checks the $_POST array for empty required values and returns a WP_Error object with a descriptive message if validation fails.
Step 3: Save the Values to the Database
Once validated, the custom field values must be saved to the database using the woocommerce_created_customer hook, which fires after a new customer account is successfully created:
function custom_save_registration_fields( $customer_id ) {
if ( isset( $_POST['billing_first_name'] ) ) {
update_user_meta( $customer_id, 'first_name', sanitize_text_field( $_POST['billing_first_name'] ) );
update_user_meta( $customer_id, 'billing_first_name', sanitize_text_field( $_POST['billing_first_name'] ) );
}
if ( isset( $_POST['billing_last_name'] ) ) {
update_user_meta( $customer_id, 'last_name', sanitize_text_field( $_POST['billing_last_name'] ) );
update_user_meta( $customer_id, 'billing_last_name', sanitize_text_field( $_POST['billing_last_name'] ) );
}
if ( isset( $_POST['billing_phone'] ) ) {
update_user_meta( $customer_id, 'billing_phone', sanitize_text_field( $_POST['billing_phone'] ) );
}
}
add_action( 'woocommerce_created_customer', 'custom_save_registration_fields' );
Note that sanitize_text_field() is used on all input values, this is a critical security step to prevent malicious data from being stored in your database.
WooCommerce includes a built-in helper function, woocommerce_form_field(), that generates properly styled form fields without writing raw HTML. This approach is cleaner, more maintainable, and automatically respects your theme WooCommerce styles.
function custom_woocommerce_hook_fields() {
$fields = array(
'social_media_profile' => array(
'type' => 'text',
'label' => __( 'Social Media Profile URL', 'your-text-domain' ),
'placeholder' => __( 'https://example.com/yourprofile', 'your-text-domain' ),
'required' => false,
),
);
foreach ( $fields as $key => $field_args ) {
woocommerce_form_field( $key, $field_args, isset( $_POST[$key] ) ? $_POST[$key] : '' );
}
}
add_action( 'woocommerce_register_form', 'custom_woocommerce_hook_fields', 15 );
This approach supports a wide range of field types that you can define inside the array:
'type' => 'text',
'label' => __( 'Company Name', 'your-text-domain' ),
'required' => true,
'type' => 'textarea',
'label' => __( 'Tell us about yourself', 'your-text-domain' ),
'required' => false,
Checkbox:
'type' => 'checkbox',
'label' => __( 'I agree to receive marketing emails', 'your-text-domain' ),
'type' => 'select',
'label' => __( 'How did you hear about us?', 'your-text-domain' ),
'options' => array(
'' => __( 'Select an option', 'your-text-domain' ),
'google' => __( 'Google Search', 'your-text-domain' ),
'social' => __( 'Social Media', 'your-text-domain' ),
'friend' => __( 'Friend or Colleague', 'your-text-domain' ),
),
The values collected this way can be saved to the database using the same wooc_save_extra_register_fields() function described in Method 1.
If you prefer a no-code approach or need advanced field types and conditional logic, several plugins make it straightforward to build and manage custom registration forms.
This is a popular drag-and-drop form builder that integrates seamlessly with WooCommerce. Here’s how to set it up:
e.g., [user_registration_form id="123"]).The official WooCommerce extension for custom registration fields offers:
Several third-party plugins offer similar or extended functionality:
| Feature | User Registration (WP Everest) | WooCommerce Extension (Official) | Extendons / Addify |
| Field types | Standard + custom | 17 types | 17 types |
| Drag & drop builder | ✅ | ✅ | ✅ |
| Conditional logic | Limited | ✅ | ✅ |
| User role management | ❌ | ✅ | ✅ |
| Free version available | ✅ (basic) | ❌ | ❌ |
| Checkout page fields | ❌ | ✅ | ✅ |
Following these guidelines ensures a smooth experience for both users and store administrators:
sanitize_text_field(), is_email(), and wc_clean() as appropriate before saving to the database.Registration Form Not Displaying
If the form is not visible on the My Account page, check that registration is enabled:
Custom Fields Not Appearing
If fields added via functions.php don’t show up:
woocommerce_register_form_start or woocommerce_register_form).Field Values Not Being Saved
If user data isn’t being stored after registration:
woocommerce_created_customer action is properly hooked to your save function.$_POST key names in your save function exactly match the name attributes in the HTML input fields.Email or Username Already in Use Errors
If this error appears with unique credentials:
Registration Form Styling Issues
If the form doesn’t match your store’s design:

Hassan Tahir wrote this article, drawing on his experience to clarify WordPress concepts and enhance developer understanding. Through his work, he aims to help both beginners and professionals refine their skills and tackle WordPress projects with greater confidence.