WooCommerce Tutorials

The Ultimate Guide to Adding Custom WooCommerce Registration Fields

The default WooCommerce registration fields are fairly limited; you simply enter an email address and a password and that’s it.

WooCommerce Registration Fields

In some ways this is great, as there’s little friction for your customers to create an account, but there are a number of cases where you may want to add some additional fields. For example, you could add fields to populate the rest of their profile, like their website address or social media information. Or perhaps you want to add some custom fields relevant only to your specific WooCommerce store to make it easier to purchase WooCommerce products.

In this tutorial, I’m going to show you how to add a number of different WooCommerce registration fields, and then save this information to the customer’s profile. As a bonus, I will also show you how to add these fields when your customers sign up for an account at the checkout page, and to their account page once logged in.

How to Add Custom WooCommerce Registration Fields

It might be a long one, so I’ll index the important sections:

Where do I add this code?

The code from this WooCommerce registration fields tutorial should be added to your WooCommerce website as a feature plugin. You can download an example plugin below or at the end of this post. Simply upload the files in Plugins > Add New, or to the wp-content/plugins directory. You can then modify the code to suit your needs.

Want to download the code from this tutorial as an example plugin?

Simply enter your name and email to receive the complete and formatted version of this code as a feature plugin for FREE.

You will receive occasional emails from Iconic, but you're more than welcome to unsubscribe at any time. I won't spam or share your details with anyone, ever.

Note: The code I provide here as an example plugin will not be supported or updated.

Enable the Account Registration Form

Firstly, you’ll want to ensure the registration form is enabled on the account login page.

Go to WooCommerce > Settings > Accounts and check Enable customer registration on the “My account” page as shown in the screenshot below.

Now the account login page should look like this:

WooCommerce registration fields basic

To ease ourselves into this, we’ll start by adding a single text field to the registration form. As it already exists in the WordPress user profile, let’s start with the Website field.

Overview of the woocommerce_form_field() Function

WooCommerce comes with a fantastic function for outputting form field HTML. The function is named woocommerce_form_field().

Rather than writing our own HTML (with a minor exception, explained shortly), we might as well use this function.

The function accepts 3 parameters:

  • $key
    String. This is your field key which will be used for the input field name parameter and ID. The ID can also be overridden in the $args parameter.
  • $args
    Array. This is an array of options for your field. It is here where you can set the field type, placeholder, options, class, and more. The available arguments are:
  • $value
    Mixed. This is the default value for the field.

This function sets us up nicely to be able to create custom WooCommerce account registration fields without repeating ourselves.

Setup Additional Registration Fields

We’re going to reference our WooCommerce custom fields in multiple functions; displaying the field names, saving the fields, and getting the saved field data.

As such, it makes sense for us to build an array of fields containing all the data we need for every scenario; then all of our data is easily accessible in a single place.

We’ll start by building the array with our single Website field.

There are a few things going on here. Firstly, we set up a function which we can then reference later on, iconic_get_account_fields().

Within this function, we’re returning a multi-dimensional array. You’ll notice we’re also running the array through a filter, iconic_account_fields. This means we can modify the array later on to update the field values.

Let’s strip it back a bit. The array contains one value (line 10) with a key of user_url (this is the key used for the Website field in WordPress). Its associated value is an array of data which we’ll be passing to the $args parameter of the woocommerce_form_field() function. We will also be adding some additional key/value pairs for use in our own functions.

Add Additional User Account Fields to WooCommerce

There are 4 areas where we want our additional user account fields to be displayed; the registration form, the edit account page, the checkout, and the WordPress admin area.

Add Custom Fields to the Registration Form

Now that we’ve set up our Website field, we want to add it to the registration form.

To do that, we’re going to hook into the registration form layout using the woocommerce_register_form hook. This will add our new field(s) just before the Register button.

I’ll walk you through what’s going on here. We’ve created a function named iconic_print_user_frontend_fields(). At the end of the code, we’re calling the function when the woocommerce_register_form hook is called.

Within the function, we firstly assign our fields to the $fields variable using the function we created previously. We know that this will return an array, so we jump straight in and loop through the array of fields.

We’re using the array key (which will be url) as the form key, and then passing the array value as our $field_args. Let’s take a look at the registration form now:

WooCommerce registration

Great! Our Website field has been added. However, currently, it won‘t do anything.

We’ll need to validate the input when the form is submitted, and then save it to the user profile. We’ll also want to display this field once the customer is logged in so they can edit it later on.

For the sake of keeping things together in this post, let’s take a look at how we can display this field once the customer has logged into their account.

Add Custom Fields to the Account Area

This is actually very simple. We can use exactly the same function we created before, iconic_print_user_frontend_fields(), and just call it on a different hook.

Again, this hook is triggered just before the form’s submit button. This particular form is located in My Account > Account Details, or /my-account/edit-account/ by default.

Add Custom WooCommerce Registration Fields to the Checkout

When a customer is checking out after purchasing WooCommerce products, they have the option to create an account (assuming you have that setting enabled). We probably want to show our additional fields there too.

We do this in a slightly different way. The checkout fields in WooCommerce are run through a filter; woocommerce_checkout_fields. They are split into groups, billing, shipping, and account. We want to add our fields to the account group.

Fortunately, the array of fields we built up earlier makes it easy for us to hook into the aforementioned filter and add our fields to the checkout.

woocommerce_checkout_fields provides one parameter. As with any filter in WordPress, the first parameter is also what any function that hooks in should be expected to return.

Note: It was pointed out that in WooCommerce 3.5.1 the fields require a priority parameter. As such, I’ve updated the code above to include a method of setting the default priority to 0. The password field in WooCommerce core has no priority either, so I’ve ensured it’s set in the above function too.

We fetch our fields array, loop through it, and assign each of our fields to the account group. Then we return the new $checkout_fields variable.

Add Custom Fields to the WordPress Admin Area

Finally, we want to add the WooCommerce custom fields to the WordPress admin area, when editing a user’s profile (or your own profile).

The layout is slightly different in the WordPress admin, as the fields are presented in tables. As such, we need a new function for displaying the fields in the admin area; but don’t forget, we can still use the same fields array we built earlier.

As usual, we fetch our custom fields right at the start. Then we jump into the HTML layout.

I’ve added a title of Additional Information so the fields are easily identifiable in the admin area. below that, we’re going to use a table layout to list the fields. It’s a 2 column table where the left cell is the field label, and the right cell is the field.

Before we output the field, we’re setting the label to false to prevent the label from showing in the right cell, as it already appears in the left.

We’re then using 2 actions to display the fields when editing a user profile. The first, show_user_profile, will add the custom fields to the current user’s profile, and the second, edit_user_profile, will add it to other users’ profiles.

Adding Conditionals to the Custom Fields

OK, so we’ve got our custom field showing in all the places we want it to. However, you may have noticed; we don’t really need to add it to the admin area, as the field already exists there. And what if we didn’t want to add it to the checkout, or the account area?

Well, because we used an array right at the start for building our custom fields list, we’ve made it super easy to add in some conditionals.

Let’s add some extra key/value pairs to our initial fields array to indicate the following conditions:

  • Hide in registration
  • Hide in account
  • Hide in admin
  • Hide in checkout

If any of these values are true, the field should not be displayed in that location. For the purpose of our Website field, we only want to hide it in admin, as it already exists there.

Now we need to modify the functions that display the fields on the registration form, account area, checkout, and WordPress admin area.

I’ve highlighted the modifications to those functions above. We’re essentially adding stoppers, so if any of our conditionals are not empty (i.e. they are “true”) then we skip that field.

As the registration form and account area use the same function to display the fields, we’re also checking whether the user is logged in. if the user is logged in, it’s the account area, if not, it’s the registration form.

Adding Other Field Types to the Fields Array

Now we have full control over where our fields appear; awesome! But what about adding other field types?

There are a number of fields available for us to add by default, and I’ll also add some modifications so we can add radios/checkboxes. Radio buttons are actually already available, but I wasn’t pleased with the way they were presented.

The fields available to add already are:

  • Text
  • Textarea
  • Select (or dropdown)
  • Country
  • Checkbox
  • Number
  • Password
  • Email
  • Tel

We’ll then add:

  • Radio
  • Checkboxes

Let’s update our fields array with an example of each field type.

Pretty straight forward, right?

It’s worth noting that multiple-choice fields like select, radio, and checkboxes, have an additional options key. Here we can set which options are available for the field.

How does this look on the registration form?

There you can see most of our WooCommerce registration fields working nicely. However, you’ll notice that the radio field (radio buttons) doesn’t look great, and the checkboxes field is completely missing. Let’s correct that by adding some of our own field types.

Add Custom Field Types to woocommerce_form_field()

The woocommerce_form_field() function has a hook within it that allows us to override or add new field types. Let’s take a look at how that’s done.

The hook we’re after is named woocommerce_form_field_{$field_type). So for our circumstances we want 2 filters named wocommerce_form_field_checkboxes and woocommerce_form_field_radio.

You know by now that I don‘t like to repeat code, so we’re going to call the same function for both of these filters.

The filter accepts 4 arguments:

  • $field
    This is the field HTML that is returned.
  • $key
    This is the field key. We set this in our fields array.
  • $args
    This is the field data we associated to the field key in our fields array.
  • $value
    This is the default value for the field.

Within the function, we’re using ob_start() and ob_get_clean(). This allows us to assign code that is usually echoed or printed to a variable for returning.

You can see we’re also calling a new function, iconic_print_list_field(). I’ve decided that checkboxes and radios follow the same format; a list.

This function is essentially replicating the format of other WooCommerce registration fields, however, we’re spitting our options out into a list ( <ul> ).

So how do those fields look now on the registration page?

That’s better!

Save the Additional Field Data to the User

There are a few situations where we want to save the data; during registration, during checkout, when editing your own profile via admin, when editing another users profile in admin, and editing your account via the WooCommerce “My Account” area.

Fortunately, we can save the data in all of these scenarios with 1 function. Let’s take a look.

Here we’re using a single function, iconic_save_account_fields(), and we’re calling it 4 times.

  • woocommerce_created_customer
    This hook is called when a user registers using the form on the login page, and also when a user registers during checkout.
  • personal_options_update
    This hook is called when you edit your own profile in the WordPress admin area.
  • edit_user_profile_update
    This hook is called when you edit another user’s profile in the WordPress admin area.
  • woocommerce_save_account_details
    This hook is called when a customer edits their profile via the WooCommerce “My Account” area.

Within the iconic_save_account_fields() function, we start off by fetching the field data.

We also create an array named $sanitized_data. We do this because there are 2 ways we can add data to a user; those that are predefined by WordPress, and our own custom fields. In a moment you’ll see which fields are predefined by WordPress.

We then loop through the fields and prepare the data for saving.

The first thing we do is check whether this field should be saved by seeing if it should be visible on the current page. This will prevent hidden fields from saving with blank data. To do this, we’re using iconic_is_field_visible().

This function could be used elsewhere in our code too. It will determine if a field should be visible or not based on the current page and the field arguments.

If the field is to be saved, we decide which sanitization method to use. We check if the field has one set in the main array, and if not, we use wc_clean; this works well for plain text fields. The sanitization method can be set for each field in the array, like this:

We then run the value through the sanitization function and assign it to the $value variable.

Next we run the key through iconic_is_userdata(). This function is going to determine whether this field is one that WordPress has predefined (like user_url).

In iconic_is_userdata() I’ve defined an array of field keys which WordPress has predefined. The function checks whether our $key is in that array and returns true or false.

If the $key was found in that array, we add it to the $sanitized_data array and use continue to proceed to the next field.

If the $key was not found, we use update_user_meta to assign that custom data to the user.

After the loop we check if our $sanitized_data array has any data. If it does, we assign the user ID and then use wp_update_user() to update the predefined user fields with our new values.

Validate Frontend Submission

It’s common to want some fields to be required fields. Or we may want to ensure a field meets a specific format. As such, we want to hook in just before the fields are saved and validate them.

Firstly, let’s add a required parameter to our fields array. We’ll use iconic-register-text as an example.

Now we can check against this before the field is saved. WooCommerce gives us 2 filters we can use; woocommerce_registration_errors and woocommerce_save_account_details_errors.

We’ll use woocommerce_registration_errors for the registration form and the checkout registration process. Then we’ll use woocommerce_save_account_details_errors for the WooCommerce “My Account” area.

Again, we can use the same function for both filters.

As usual, we start by fetching our fields array.

We loop through the array and then check whether required is empty. If it is, we skip it with continue as it requires no validation.

We also check if register isn’t set in the posted values and if hide_in_account is true for the specific field. Again, if this evaluates to true we skip it. When register isn’t set it means we’re saving our account fields, and if hide_in_account is true, it means that particular field should not be validated as the field wasn’t visible for us to enter any information in to.

Then, we run the same check as above but check if hide_in_registration is true when registering. We’d skip it for the same reasons as above.

If we get past all of these “stoppers” then the field is required and should contain some posted data. If it is empty, we add an error to the $errors object and carry on with the loop.

We then return our new $errors object, which may or may not contain validation errors, depending on the data that has been posted.

If there is an error, the user will be taken back to the form and the error message we added will be displayed. No data will have been saved.

Set Default Values for the Fields

There’s 2 scenarios when we would want to display a default value for the fields; when viewing the user profile (admin or WooCommerce account area), and when you submit the form but an error occurs.

Default Values for Saved Fields

When we display the fields in the WooCommerce account area, or in the WordPress admin when editing a user profile, we’ll want to populate the field with the submitted data. As such, we need to edit the iconic_print_user_frontend_fields() and iconic_print_user_admin_fields() functions.

We’ve added a check to iconic_print_user_frontend_fields(). If the user is logged in then we get their user ID and fetch the field value using iconic_get_userdata() (described in the section “Accessing the Saved user Data”).

In iconic_print_admin_user_fields() we’re doing the same; fetch the ID of the user we’re currently editing and fetch the data for that field.

We’re also now using the third parameter of woocommerce_form_field() which allows us to pass in the default value for the field.

You’ll notice I’m using a function named iconic_get_edit_user_id(). This function (shown above) will return the user ID if it exists as a URL parameter, or the currently logged in user ID. This means we can use the same function for all scenarios above.

See “Accessing the Saved User Data” for information on the iconic_get_userdata() function.

Default Values after Submission Errors

When we initially set up our fields array, we also ran them through a filter named iconic_account_fields. Well, this is the perfect scenario for us to use that filter.

After a submission error occurs, the user is redirected back to the form. The posted data is still accessible at this point, so it makes sense for us to re-populate the fields with the data they entered.

Let’s hook in to our filter and populate the field values.

First, if the $_POST object is empty we just return the fields as normal.

Otherwise, we loop through each field. If the $_POST value for that key is empty, we set the fields value to empty then skip to the next field using continue;.

If the $_POST value is set, we set it as the field’s value.

In the modified version of iconic_print_user_frontend_fields() above, at line 26 we’re checking if value is set in the $field_args. If it is, we use that, otherwise we use the saved value (if present), or null.

Accessing the Saved User Data

Now that you’ve saved this data to the user, you will want to access it and, most likely, display it or use it somewhere on your WooCommerce store.

Our data can come from 2 places; our custom metadata, or the predefined WordPress data. As such, here’s a function to get the appropriate value:

You can use this function like so: echo iconic_get_userdata( 1, 'user_url' );, where 1 is the user ID and user_url is the field key.

The function checks if the field is a predefined WordPress field using iconic_is_userdata(). If it is not, it fetches the value using get_user_meta(), a function that will fetch our custom user metadata.

If it is a predefined field, we fetch the user data using get_userdata() and pass in our user ID.

We then check if the key is set and return its value.

Want to download the code from this tutorial as an example plugin?

Simply enter your name and email to receive the complete and formatted version of this code as a feature plugin for FREE.

You will receive occasional emails from Iconic, but you're more than welcome to unsubscribe at any time. I won't spam or share your details with anyone, ever.


There we have it! I said it’d be a long post.

To recap, we’ve discussed how to add custom WooCommerce registration fields to the registration form, checkout registration, account area, and admin user profiles through the WordPress back-end.

We’ve then worked out how to save this data and validate it when submitted.

Let me know in the comments if you have any questions about your WooCommerce registration fields, or with the code provided.


James is the founder of Iconic and an experienced WooCommerce plugin developer.



  1. Avatar Thomas Rainer says:

    This was fantastic! Thank you very much for your time and effort in putting this all together. I do have a question: Is it possible to only use the default wordpress “Contact Information” website field? I’ve setup all the code for the Website Field. But the information is not showing for the User under the “Contact Information” section of the “Website” field in the admin. I’ve tried “url” and “user_url”. However, the entered website url does show in the newly added fields from your instructions.

    • Avatar James Kemp says:

      Hey, thanks!

      Yes, url is the correct key to use. Have you tried downloading the complete script? It could be some part that was missed. I tested with the URL field when writing this up, so you shouldn’t have any issues!

  2. Avatar Michelle Britton says:

    Great plugin! Thank you!

    I have one question – I am currently using your code to pull in information from three checkboxes and I am using this code to send a new registration email to the admin:

    add_action(‘woocommerce_created_customer’, ‘admin_email_on_registration’, 10 , 1);
    function admin_email_on_registration( $customer_id) {
    wp_new_user_notification( $customer_id );

    Is there any way to send the information from the three checkboxes in the email?

    • Avatar James Kemp says:

      Hey, nice!

      Yep, you can use get_user_meta( $user_id, ‘text-field’, true ); to get your data. You’ll need to modify the email template or hook into it.

      • Avatar Michelle Britton says:

        Hi there,

        I’m a little stuck here, can you give me a bit more guidance on how to hook into it? I’m using this code to customise the email but I’m not sure where or how to add in get_user_meta( $user_id, ‘text-field’, true );

        add_filter( ‘wp_new_user_notification_email_admin’, ‘custom_wp_new_user_notification_email’, 10, 3 );

        function custom_wp_new_user_notification_email( $wp_new_user_notification_email, $user, $blogname ) {

        $wp_new_user_notification_email[‘subject’] = sprintf( ‘[%s] New user %s registered.’, $blogname, $user->user_login );
        $wp_new_user_notification_email[‘message’] = sprintf( “%s ( %s ) has registerd to your blog %s.”, $user->user_login, $user->user_email, $blogname );

        return $wp_new_user_notification_email;

  3. Avatar Luigi Briganti says:

    There is not a way to add the “date” input type to wordpress user meta?

  4. Avatar Roger says:

    I am loving the Plug-in, and just grasping with creating a view of the User data will all this additional fields added to it, is there a plug in that will be be a view as the admin to the users and the fields that they have completed. Would like to dump the table of users to a CSV file

  5. Avatar Hagbard Celine says:

    Hi, would like to download the files for the tutorial. I signed up, but all I got was a newsletter subscription?

    • Avatar James Kemp says:

      Hey, the attachment is sent after you confirm your email

      • Avatar Hagbard Celine says:

        Thanks for the reply. There werent any attachments sent after email confirmation. I tried several times as this was what I expected, but no … nothing.

        • Avatar Dorothy Nelson says:

          Hi Hagbard, I had the same issue as you and I found the email in my spam folder. Sending a zip sets off all the alarm bells on Gmail, etc.

          • Avatar James Kemp says:

            Hey Dorothy – thanks for confirming. I’d have thought as the zip isn’t physically attached this wouldn’t be an issue. I’ll double check if there’s any way to fix it!

      • Avatar John Laprairie says:

        Hi, I also had the same issue with the Mailchimp process.
        My site has a custom ‘My Account’ page and it did not work there. Would like to try the plugin to check it on the main my account page

  6. Avatar Nikos Chatzirafail says:

    Hi, how can I add an input type=”file” field?

  7. Avatar Laurent Dagany says:

    Hi !
    Very nice… It will help me a lot if… A Question :
    you said in the chapter “Add Custom Fields to the WooCommerce Checkout” that there are three group (indeed) to put the new fileds : billing, shipping, and account.
    Your exemple is to put in “account”. I’d like to put them in the billing group.
    I tried to change the code
    $checkout_fields[‘account’][ $key ] = $field_args;
    $checkout_fields[‘billing’][ $key ] = $field_args;

    But nothing 🙁

    Do you have a clue for the trick to put the nex flieds in the billing part ?
    Thanks !

  8. Avatar Geraldine says:

    Thank you for a great plugin that helped us a lot with our website. We’ve opened registrations yesterday and half of the new user registrations are missing all additional fields data in the back-end. The firstname / surname / email address are always in though. It’s random and I was wondering if you had similar experience?

    • Avatar James Kemp says:

      Hey Geraldine,

      Have you tested the process yourself? Could it be that the fields aren’t required?

      • Avatar Geraldine says:

        Yes we have tested it multiple times, on desktop and mobile devices. We have half of the fields required and when not filling out those fields when testing, the form was not submitting as expected. So a bit of a strange one…

      • Avatar Geraldine says:

        After further tests, it looks like the data is being deleted AFTER being first recorded properly…

        • Avatar James Kemp says:

          Could this be coming from your theme or another plugin?

          • Avatar Geraldine says:

            I just found out that the data is being deleted when users go to their account and change their password.
            When they submit the password change form, it deletes data from the custom registration fields.
            I’m using the default user account system from WordPress + Woo Commerce.

          • Avatar Geraldine says:

            It looks like hiding the fields in the Account’s page using ‘hide_in_account’ => true,’ is what’s causing problems.
            When submitting the password change, it also re-submit “blank data” for the fields that are hidden.
            I’ve put them back to “false” but hiding them in CSS as a quick hack, but if you can think for another more permanent solution, it would be great 🙂

          • Avatar James Kemp says:

            Hey, I’ve updated the script to avoid this! I’ll be updating the article, but drop me an email to [email protected] if you want the example plugin.

          • Avatar Geraldin says:

            Only seeing this now! Will email you.

  9. I used the sample plugin you sent to me, make few editing to remove field sets I don’t want, save it,and all works fine, just that the field are not showing up at checkout page.
    Secondly, I will like to make the filed read only once a value is entered and save. Am using only text and number field to set up two fields.

    • Avatar Rodrigo Ávila says:

      You can put this code before “woocommer_form_field” in the iconic_print_user_frontend_fields:

      if($is_user_logged_in && ($key == ‘your-field-name’){
      $field_args[‘custom_attributes’] = array(‘readonly’=>’readonly’,’title’=>’title-example’);

      you can add as many custom atributes you want inside that array, include readonly.

  10. Avatar Andre Riis says:

    worked perfect, but now i had to change
    function iconic_save_account_fields( $customer_id ) {
    $fields = iconic_get_account_fields();
    $sanitized_data = array();

    foreach ( $fields as $key => $field_args ) {
    if ( ! iconic_is_field_visible( $field_args ) ) {

    $sanitize = isset( $field_args[‘sanitize’] ) ? $field_args[‘sanitize’] : ‘wc_clean’;
    $value = isset( $_POST[ $key ] ) ? call_user_func( $sanitize, $_POST[ $key ] ) : ”;

    if ( iconic_is_userdata( $key ) ) {
    $sanitized_data[ $key ] = $value;

    update_user_meta( $customer_id, $key, $value );

    if ( ! empty( $sanitized_data ) ) {
    $sanitized_data[‘ID’] = $customer_id;
    wp_update_user( $sanitized_data );

  11. Avatar Fermin June Seva Alegro III says:

    These works nicely for fields that are not yet in the My Account and Profile pages.
    Im currently in need of being able to add a Username (non changeable) but it seems it is already in the My Account (frontend) and Profile (wp-admin) pages.
    How do you override or use already present fields like these and make it non changeable?
    Also what are the keys for the fields in the billing address and shipping address?

  12. Avatar James Kemp says:

    Ha, thanks – appreciate it!

  13. Avatar Alice says:

    I’ve been using this guide to create some custom fields for our website and it works wonderfully for a little while. But all of a sudden today a required checkbox on our registration form always throws an error saying that it’s not ticked even when it has been. Do you know if any recent wordpress updates might mess with this code?
    Any help would be appreciated,

  14. Avatar Derek says:

    Hi I have added your code to my website and it works great! Thank you for your work!

    One question though, as I am quite new to wordpress, I would like to ask whether there is any code we can use to verify a field, for instance for the telephone number field, I want my users to input 10 digits of numbers only otherwise it would return an error message.


  15. Avatar Gijs Palsrok says:

    I’m using custom code to add checkout fields. These are already visible for both users who are paying for their product. It is also visible for me as an administrator in the admin. But I also need it to be visible for users in their own profile page, and preferably adjustable. Because I’m keeping the new European rules on privcay in mind.. Can’t wait for your reply. Here is my code:

    /* WooCommerce: The Code Below Removes Checkout Fields */
    add_filter( ‘woocommerce_checkout_fields’ , ‘custom_override_checkout_fields’ );

    function custom_override_checkout_fields( $fields ) {
    return $fields;

    // WooCommerce Rename Checkout Fields
    add_filter( ‘woocommerce_checkout_fields’ , ‘custom_rename_wc_checkout_fields’ );

    // Change placeholder and label text
    function custom_rename_wc_checkout_fields( $fields ) {
    $fields[‘billing’][‘billing_leeftijd’][‘placeholder’] = ”;
    $fields[‘billing’][‘billing_onderwijs’][‘placeholder’] = ”;
    $fields[‘billing’][‘billing_stad_school’][‘placeholder’] = ”;
    return $fields;

    /* CHECKOUT WooCommerce: The Code Below Removes The Additional Information Tab */
    add_filter( ‘woocommerce_product_tabs’, ‘woo_remove_product_tabs’, 98 );
    function woo_remove_product_tabs( $tabs ) {
    unset( $tabs[‘additional_information’] );
    return $tabs;

    /* CHECKOUT WooCommerce: The Code Below Removes The Additional Information Title Text */
    add_filter(‘woocommerce_enable_order_notes_field’, ‘__return_false’);

    /* Voeg checkout fields toe aan gebruikers admin overzicht */
    function new_modify_user_table( $column ) {
    $column[‘billing_stad_school’] = ‘Stad en school’;
    $column[‘billing_onderwijs’] = ‘niveau’;
    $column[‘billing_leeftijd’] = ‘leeftijd’;
    return $column;
    add_filter( ‘manage_users_columns’, ‘new_modify_user_table’ );

    function new_modify_user_table_row( $val, $column_name, $user_id ) {
    switch ($column_name) {
    case ‘billing_stad_school’ :
    return get_the_author_meta( ‘billing_stad_school’, $user_id );
    case ‘billing_onderwijs’ :
    return get_the_author_meta( ‘billing_onderwijs’, $user_id );
    case ‘billing_leeftijd’ :
    return get_the_author_meta( ‘billing_leeftijd’, $user_id );
    return $val;
    add_filter( ‘manage_users_custom_column’, ‘new_modify_user_table_row’, 10, 3 );

  16. Avatar Simon says:

    Hey James, I’m new to WordPress and i’m trying to start my first store. I’ve had trouble customizing the account page and making a login page. Your plugin is great, but how do I add a username field and most importantly, where can I find the code and edit it?

  17. Avatar TVA says:

    Thanks for the tutorial!!
    Is it possible to set the order that the field appears in the form?
    Like: put a custom field before the email field?

  18. Avatar TVA says:

    Is there a way to use this fields with the REST API?

  19. Avatar hasan says:

    how display a field information in admin edit order page.
    i need to show customer field in edit order page

  20. Avatar Reid Horton says:

    How do we add these fields to REST API end-points? I need to expose them to the REST API, but am falling short…any ideas?

  21. Avatar Peter says:

    Trying to do something really simple, I thought…. I want to add a customer ID number to the user and automatically display in Woocommerce as well.

  22. Avatar Sandro says:

    Greate tutorial! one question, how can i add a new “save changes” button for the new my account site. as a example, i have a page with partner information for the customer and i would like to save this partner information like the own customar details.

  23. Avatar Andy Agcaoili says:

    Thank you so much for this post! It is really helpful. Unfortunately, the data does not save when it is entered or when the user wants to update the site. I sent you an email to see if you could help! Thanks!

  24. Thanks for this Guide. It works really well.

    Just one thing that I noticed though, is that it’s generating a PHP notice about trying to convert an array to a string. In line 11 of the iconic_get_userdata() function, there should be a third parameter when calling get_user_meta(). Currently you’re calling get_user_meta( $user_id, $key ) but that actually returns an array (by default) which generates the notice (an in turn, doesn’t set the default value properly). Instead it should be get_user_meta( $user_id, $key, true ) which will return a string. Passing true as the thrid paramater will ensure get_user_meta() only returns a single value as a string.

  25. Avatar Shawn says:

    Thank you for this post. It has been immensely helpful. I have a question, though…I’ve added several custom checkout fields, and they save perfectly in admin and when a new account is created (including from the checkout page), but if any of the field inputs for an existing user are changed on the checkout page, those fields are not saved after the order is submitted. That is, the woocommerce_created_customer hook seems to save the info for a new customer, but if a return customer is updating data on the checkout page, this hook does not fire. I’ve tried various other hooks, such as woocommerce_checkout_order_processed and woocommerce_checkout_create_order, but I can’t figure out how to save the user data in this scenario. Do you know of a hook that will work? Thanks!

    • Avatar Richard says:

      I have the same problem! Anyone has a solution?

    • Avatar Richard says:

      I found the solution! We need to use woocommerce_checkout_update_user_meta like so:

      add_action( ‘woocommerce_checkout_update_user_meta’, ‘iconic_save_account_fields’); //Checkout process

  26. Avatar HongSik, Won says:

    hi James
    You are the best!
    It was very helpful.

  27. You never emailed the plugin after I subscribed.

    • Avatar James Kemp says:

      Hey, it’s automated but can take a few minutes to go through. Make sure you checked your spam folder too!

  28. Alright, thank you for this Tutorial, it was super useful, but I can’t make the arg Maxlenght work in “iconic_get_account_fields()”.
    I’m using it this way http://prntscr.com/lfwuro, but it doesn’t work.
    Can you help me? Please!
    Thank you again in advance.

  29. Avatar Richard says:

    Hello James! I have a question, how do I save the fields if i’m putting them on the order section on checkout? All other fields are being saved correctly everywhere, but these aren’t. And they save if I edit them on admin or account area, but not during checkout. Am I missing an action on the save function?

    Basically I changed billing to “order”:

    // Add fields to checkout
    function iconic_checkout_fields( $checkout_fields ) {
    $fields = iconic_get_account_fields();

    foreach ( $fields as $key => $field_args ) {
    if ( ! empty( $field_args[‘hide_in_checkout’] ) ) {

    $checkout_fields[‘order’][ $key ] = $field_args;

    return $checkout_fields;

  30. Avatar Case says:

    Hi James! Thanks for the great, in-depth tutorial. I learned a lot and it’s a great reference. I was wondering if you have any ideas or suggestions for making the visibility of a field conditional upon other fields. For instance, a select/dropdown field labeled “Would you like to provide additional details?” If they choose “Yes”, additional fields appear for them to fill out for a more detailed profile.

    • Avatar Daniel says:

      Hi James! Great tutorial! I would like to learn also how making conditional visibility of a field upon other fields. Do you have some tutorial or any cheat about how to do it?

  31. Avatar Stefan says:

    @James are you familiar with ACF? Is it possible to add acf field like additional input field?

    • Avatar James Kemp says:

      Hey, I love ACF! I think it’d be possible, but might not be worth the effort. It’d still need a lot of custom code.

      • Avatar Stefan says:

        Yep, i realise that after some time 😀
        Anyway how is possible with your example to some input’s?
        Just to look a little bit separate from default Woo fields

  32. Avatar Amanda says:

    First of all, congratulations!! Is a nice plugin demo to add new fields!
    But I have a question,
    I have two select fields, required, but the second select only appears with an specific select option from first. I mean, they are nested select.
    Is there a way to do it?
    I’m trying with js, to show or hide the field, but the field is declared and appears the validation that the field is mandatory…

    Thanks in advance!

  33. Avatar Manalina Rajaona says:

    Hi James!

    Thanks for the great tutorial, was really helpful. Got only one question: is it possible for me to make the person who register chose between user role or plan i created? By using the dropdown select or a radio.

    • Avatar James Kemp says:

      Hey Manalina,

      Yes, it’s definitely possible. You can just change their role during the submission based on the selection they made.

      • Avatar Mary says:

        Can you give us a code example on how to do this? Preferably one that fits into the plugin downloaded from this page 😉

  34. Avatar Gabriel Meisel says:

    Is there a way to check if the custom value already exists for any other user?
    I am asking for the ID of the user when he registers, so the ID must be unique.
    Thanks! Awesome post.

    • Avatar Gabriel Meisel says:

      I figured it out. For anyone else trying to achieve this, I added this code inside the foreach of the iconic_validate_user_frontend_fields function:

      if ( isset( $_POST[ $key ] ) ) {
      $hasCedula= get_users(‘meta_value=’.$_POST[ $key ]);
      if ( !empty($hasCedula)) {
      $message = sprintf( __( ‘Ya existe un usuario con este número de cédula’, ‘iconic’ ), ‘‘ . $field_args[‘label’] . ‘‘ );
      $errors->add( $key, $message );

  35. Avatar Kevin says:

    I signed up but never received the plugin.. checked the spam folder as well.

  36. Avatar Eddie says:

    Hi James, wow, thank you so much for sharing this. I downloaded and installed the plugin and received the activation confirmation but I don’t see the plugin settings anywhere in the dashboard. Also, the plugin is not listed under plugins, active plugins, and there is no admin menu link anywhere. I tried to install the plugin again and I got the wordpress message “the directory already exists”. I’m running WP 5.1.1 . Appreciate any/all help!

    • Avatar Eddie says:

      Disregard, I’m an idiot. There is not menu in the dashboard but the plugin editing can be done under Plugins > Plugin Editor > Woocommerce Custom Account Fields.

  37. Avatar Yngve says:

    Great tutorial
    however I encountered a problem with the required field.
    I’am this for a shopkeeper theme, setting the required to true would not be recognized, the tutorial sets the required “mark” as a html abbr tag – changing that to html span tag fixed the problem

  38. Avatar Eddie says:

    Can you show a way to lock a custom field so that it is visible on My Account page but it cannot be edited by the user? Thank you!

  39. Avatar Mida says:


    Great plugin. I only have an issue with the ‘Website” field. It doesn’t appear in the checkout nor in the user profile as shown in your example. Could you please let me know how can I activate that?

  40. Avatar Jessica Roberts says:

    Hello, great plug in !

    I’m trying to add multiple of the same type of fields (iconic-register-text and iconic-register-tel to be exact).

    It seems that one text field gets replaced by another one that is defined below it.

    Can you share some guidance on how to avoid my fields from “disappearing” and how to get multiple fields of the same type on the screen?

    Thank you.

  41. Avatar James says:

    Hey! Great Plugin, do you know of anyway to add an input that provides the ability for the user to upload and save an image here as well (not a profile image). They would also need the ability to replace that image monthly. I really can’t seem to find this ability anywhere, all I find are ways to allow them to create a post that everyone can see but I am looking for something that the user uploads and only them and the admin can see. Any help in leading me in the right direction would be much appreciated!

  42. […] I am trying to add custom field related with city/state content to user info editing page at admin interface. There is already same structure to obtain this as default in multi-level hierarchy, after country picking cities are being populated. I just need city side of this structure, country would be predefined. Current additional fields codes as follows. I am following the guide for custom fields on user info in the link below https://iconicwp.com/blog/the-ultimate-guide-to-adding-custom-woocommerce-user-account-fields/ […]

  43. Avatar Mehmet Akif says:

    Thank you for sharing such a comprehensive tutorial with us. I am trying to extend your ‘checkboxes’ type with an additional text field. Is that possible? You can check the link below about what I am trying to do. I could not find a clear way to connect them with the created checkboxes.
    Any help appreciated. Thank you

  44. Avatar Alvina says:

    I am trying to add a custom field but having an error empty fields while filling the registration form. Can you please guide me where I am doing wrong as I have seen this code here https://www.cloudways.com/blog/add-woocommerce-registration-form-fields/

    function wooc_validate_extra_register_fields( $username, $email, $validation_errors ) {
    if ( isset( $_POST[‘billing_first_name’] ) && empty( $_POST[‘billing_first_name’] ) ) {
    $validation_errors->add( ‘billing_first_name_error’, __( ‘Error: First name is required!’, ‘woocommerce’ ) );
    if ( isset( $_POST[‘billing_last_name’] ) && empty( $_POST[‘billing_last_name’] ) ) {
    $validation_errors->add( ‘billing_last_name_error’, __( ‘Error: Last name is required!.’, ‘woocommerce’ ) );

  45. Avatar Danny says:

    Hi, Firstly amazing piece of code!

    I was just wondering if there was any way for the custom data to be fed in to the order as well as attached to the user?

    I’m essentially putting a dropdown for clothing size and want this attaching to the user but also showing in their initial order.


  46. Avatar Frank Lu says:

    Thanks James for the article. This seems to be exactly what I need. I would love to get notified when you make this into a plug-in.

    Just to give you some use case background, I am working on an after school program e-commerce site, the courses are usually signed up by the parent for their children. The children’s info I already captured from the user registration form/my-account form. All I want is that when the parent purchasing a class, he/she can select which Child is this class for.

    So the check out page would need a custom field that can read from an existing account profile table.

    There are plug-ins that can add custom fields into the checkout page, but I have not seen a plug-in that can make those fields pre-populated with current user data.

  47. Avatar Per says:

    This is an amazing piece of knowlege you share. Thank you so much.

    I wonder if you could give me a pointer on how to access the fields info? I’m trying to add to the plugin to send an extra order email based on the register email value.

    If I hardcode an email in the below code it works, but I want to use the custom field based on your plugin, so I can send the extra email based on the value.

    add_filter( ‘woocommerce_email_headers’, ‘mycustom_headers_filter_function’, 10, 2);

    function mycustom_headers_filter_function( $headers, $object ) {
    if ($object == ‘customer_completed_order’) {
    $headers .= ‘BCC: Per HERE I NEED THE VALUE FROM THE FIELD’ . “rn”;

    return $headers;

    • Avatar Per says:

      $sae = iconic_get_userdata( $user_id, ‘iconic-register-email’ );
      Is returning nothing. What am I missing?

      • Avatar Per says:

        Managed to solve it, if someone else needs it

        function mycustom_headers_filter_function( $headers, $object ) {
        $sae = iconic_get_userdata( get_current_user_id(), ‘iconic-register-email’ );

        if ($object == ‘new_order’) {
        $headers .= ‘BCC: ‘ . “\r\n”;

        return $headers;

  48. Avatar Stein says:

    Hello thank you for the helpful tutorial, but i need something different, i have a plugin BAW Invitation Code from WordPress Plugin Repository, and i want to add the Invitation Code when registering/creating an account on my Account page, the Invitation Code field only in WP-Login registration Page.

    Please help me how to add it.


  49. Avatar Christina says:

    Love the tutorial and the plugin! However, The fields just don’t show up on the checkout page. Does anyone know why this might be happening?

  50. Avatar James says:

    The fields are not adding in the registration form using a plugin. I am trying to add it manually using a code that is in this complete guide https://wpitech.com/add-woocommerce-registration-form-fields/. Is there any alternative to do this? It would be really helpful if you could help me to add fields in the registration form.

    function Woo_register_fields() {?>


    add_action( 'woocommerce_register_form_start', 'Wooregister_fields' );

  51. Avatar Corey says:

    Is it possible for when the custom field is updated on the front or backend, that the user’s role can change at the same time? How would i do this?

  52. Avatar Sebastian Diaz Pena says:

    Is ti possible to make a date field with this method? I want to ask the birthday of my custumers and the date they filled the registration form.

  53. Avatar Odilon says:

    Hi! How can I adds upload file please?

    • Hi Odilon,

      Do you mean that you want to add an option in your account page to upload a file?

      • Avatar Alessandro Stevanato says:

        Hi, congratulations on the code! I am also looking for a way to upload a file (for example identity document) within the registration form, with the possibility of viewing it within the user account page and the user dashboard in administration. Is it possible to do this?
        Thanks a lot

  54. Avatar Martin Wolff says:

    Hey James,

    thanks for this awesome tutorial. I’ve got two questions about it:

    1.) How is it possible to change the order of the fields? At the moment I still have E-Mail address and password above my custom fields, but they should be underneath them at the end.

    2.) If I go to dashboard > addresses > edit it doesn’t show me name and surname although it is saved in the admin view and in dashboard > account-details. Is this a bug? How can I fix that?`

    Thanks again for your help and this great tutorial!

  55. Avatar Martin Wolff says:


    unfortunately your plugin doesn’t show me the name and last name in the checkout which I entered when registering? Is anyone facing the same issue? It works, when I create a new user in the backend and when I go to addresses–> edit address enter those data there and save. Can you help me with that?

  56. Avatar keusta says:

    Hello James,

    very usefull plugin! it works well, but im stuck!

    i try to show only for a specific role the “iconic-register-textarea” in my-account but i cant get it work.

    i try to modify iconic_print_user_frontend_fields() to add some conditional logic but idk how to filter iconic-register-textarea to hide it to all without the role.

    $roleNeeded = ”;
    $user = wp_get_current_user();
    if ( in_array( ‘roleNeeded’, (array) $user->roles ) ) {$roleNeeded = true; }
    if ( $is_user_logged_in && $roleNeeded) {
    // show all fields
    // show all fields except “iconic-register-textarea”
    If you can help me “again” \Ô/

  57. Avatar Colin says:

    Wow. I learned so much in this wonderful tutorial! Thank you so much for putting this together in such a well written and easy to understand format. You thought of everything!

  58. hello excellent plugin but I’m adding a field and in the edit it does not show the selected option

  59. […] here’s the function (from here Iconic Website) that should save the […]

  60. Avatar Selver says:

    Hi James,

    Thank you very much for this tutorial, it saves a lot of time. The plugin also working great and it’s very easy to modify. I sending data to the billing address and everything is going well. Is there any way to send the same data to the billing and shipping address?


  61. Avatar Daniel says:


    I’m a beginner at theme development, so please forgive my mistakes.
    I have implemented the code into my functions.php file. I noticed that the additional fields show in the right areas, however the fields are not populated in the my-account page and in the WordPress admin page. Did I slip up in implementing the code, or is this feature not included in the code?

    Kind regards,

  62. Avatar Jess says:


    It’s work perfect. But the position for the checkout page is not right. It’s like aligned in wrong sequence. Here is what I get:

    1. Contact Number *
    2. In-charged Person *
    3. Office Name *
    4. Create account password *
    5. Account username *

    It should be
    1. Account username *
    2. Create account password *
    3. Office Name *
    4. In-charged Person *
    5. Contact Number *

    I cant find where’s go wrong. It’s aligned perfect in My Account page. Please help


  63. Avatar 1001Webs says:

    Hi James, thanks a lot for the code and the comprehensive instructions,

    Probably abusing your generosity, but how would you add a File Upload field?
    And how would you have those uploaded files stored as part of the User Profile?


  64. Avatar Martin says:

    This is a great plugin code. I wondered if it is possble to add a confirm password field and validate it for any variance from the main password field? I also wondered is it possible to not save the confirm password field into the database?

  65. Avatar Rick S says:

    Nice work.

    I have a field that’s email 2.
    Modifying the plug-in, I can see the fields in the user’s woocommerce account details. But any preexisting values aren’t populating in the account details – they’re all the default text (“e.g. some text…”.

    The values for email are populating in the Admin screen in the Addition Information section.

  66. Avatar Leszek says:

    Hello, Thank you very much for this article it really opened my eyes. Thanks to this i was able to add a custom field to account details area. I have also tried to add the same field to checkout but it’s not appearing there (it’s not related to registration during the checkout that might be the reason). Can you lead me thru when i need to change to get the field from account detail on my checkout page?

  67. Avatar alex says:

    Thank you for the tutorial but the email system to send the plugin is not working

  68. Avatar Greg says:

    Great plugin example! Thank you.

    Can you explain where the (optional) comes from when ‘required’ => false? Is that a core WordPress hook?

Leave a Reply

Your email address will not be published. Required fields are marked *