Billing and Shipping Address Fields
There are two type of fields in WooCommerce – billing and shipping fields (sorry for being so obvious). Some of the fields are presented in both of these categories, like a first name field or a country field. Some – may be presented in one of the categories only, like phone or email.
And now read carefully:
- We can make changes in the fields using hook
woocommerce_default_address_fields
– in this case the changes will affect everything – both edit billing and shipping fields pages in “My account” and the Checkout page as well. woocommerce_shipping_fields
– the same, but affects only shipping fieldswoocommerce_billing_fields
– the same, but affects only billing fieldswoocommerce_checkout_fields
– affects only the checkout page, nothing else, this hook is already described in details in a separate tutorial.
Remove Default Billing and Shipping Fields
As easy as:
add_filter( 'woocommerce_default_address_fields', 'misha_remove_fields' );
function misha_remove_fields( $fields ) {
unset( $fields[ 'address_2' ] );
unset( $fields[ 'state' ] );
return $fields;
}
Fields IDs are:
first_name
,last_name
,company
,address_1
,address_2
,state
,city
,country
,postcode
But please note, that if you’re using woocommerce_shipping_fields
or woocommerce_billing_fields
filter hook, an appripriate prefix (billing_
or shipping_
) must be added to a field ID, example:
add_filter( 'woocommerce_billing_fields', 'misha_remove_billing_fields' );
function misha_remove_billing_fields( $fields ) {
unset( $fields[ 'billing_address_2' ] ); // or shipping_address_2 for woocommerce_shipping_fields hook
unset( $fields[ 'billing_state' ] );
return $fields;
}
Disable Field Validation
In this case you do not have to remove the whole field itself but just a certain property of it (required
).
Example of making optional the shipping last name field:
add_filter( 'woocommerce_shipping_fields', 'misha_remove_fields' );
function misha_remove_fields( $fields ) {
unset( $fields[ 'shipping_last_name' ][ 'required' ] );
return $fields;
}
Here we go:

You can also use woocommerce_default_address_fields
if you want to make the last name field optional for both billing and shipping field groups.
On the other hand, if you want to make a field required, just set the required
property to true
, like this:
$fields[ 'shipping_company' ][ 'required' ] = true;
How to Change the Default Address Fields?
In the previous example I already explained how to make any of the default fields optional or required. But required
is not the only field parameter we can change. Here is the list:
label
(string)placeholder
(string)class
(array)priority
(integer)
Any of these parameters can be changed. As an example let’s try to make changes in both billing and shipping first name fields:
add_filter( 'woocommerce_default_address_fields', 'misha_change_fname_field' );
function misha_change_fname_field( $fields ) {
$fields[ 'first_name' ][ 'label' ] = 'Name';
$fields[ 'first_name' ][ 'placeholder' ] = 'What is your name, friend?';
return $fields;
}
Here is the result:

More examples you can find in my tutorial about WooCommerce checkout fields. Yes, we work with woocommerce_checkout_fields
action hook there but it is very similar.
Create Your Custom Address Field
Creating an address field is so much easier than creating fields for the Edit Account page or for the Checkout page.
You do not even have to use woocommerce_form_field() function!
No, really, it is just all about working with an array:
add_filter( 'woocommerce_default_address_fields', 'misha_add_field' );
function misha_add_field( $fields ) {
$fields[ 'fav_color' ] = array(
'label' => 'Favorite color',
'required' => true,
'class' => array( 'form-row-wide', 'my-custom-class' ),
'priority' => 20,
'placeholder' => 'Is it black or orange or maybe green?',
);
return $fields;
}
Keep in mind some things:
If you are going to use woocommerce_shipping_fields
or woocommerce_billing_fields
hooks, do not forget about field prefix shipping_
or billing_
on line 4. I think the things will work out even without prefixes here, but let’s do everything correctly.
$fields[ 'billing_fav_color' ] = array(
You could guess that it is also a meta key how this field will be stored in the database in wp_usermeta
table.
A couple words about CSS classes as well:
form-row-wide
– fullwidth field,form-row-first
– 2-columns field, the first column,form-row-last
– 2-columns field, the second column;
You can play with the priority
parameter by yourself, for example I set 20 which placed my field under First name and Last name fields:

The cool thing is that it will appear and will be fully functional on the WooCommerce checkout page as well!
How to add the field into WordPress /wp-admin/ Edit Profile pages?
Okay, our field is now displayed on Edit Address pages in “My Account” and in the Checkout page. But what about WordPress admin? It would be cool, if the field will appear also in edit profile pages, don’t you think so? Here is what I mean:

The good news is that you do not have to use show_user_profile
and edit_user_profile
hooks! 🎉
There is a special hook for that:
add_filter( 'woocommerce_customer_meta_fields', 'misha_admin_address_field' );
function misha_admin_address_field( $admin_fields ) {
$admin_fields[ 'billing' ][ 'fields' ][ 'billing_fav_color' ] = array(
'label' => 'Fav color',
'description' => 'Some field description will go here',
);
// or $admin_fields[ 'shipping' ][ 'fields' ][ 'shipping_fav_color' ]
// or both
return $admin_fields;
}
Only two parameters available here – label
and description
and actually we do not need anything else. Just make sure, that field name (line 5) matches.
If you want to add your field on edit order pages in WordPress admin as well, read here how.

Misha Rudrastyh
Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me
Hi Misha, thanks, worked very fine for me & helped a lot. I added a VAT field in the “my account -> billig address area” via the functions.php of my impreza template. The new field also appears on the checkout page now & entered data is stored in my sql database.
However, I observe that two things do not work properly:
1) in the “my account”-“address” overview page, the new custom VAT field is not shown
2) the VAT-Field is not prefilled with the number entered the last time (both in my account area as well as on the checkout page.
Could you please help me with these two questions? ;)
Max
Hi Max,
First of all – may I ask you what filter hook did you use? 🙃
1) You can use
woocommerce_my_account_my_address_formatted_address
hook for this purpose.2) Here is an example how to make it prefilled.
Hello,
Thanks for your excellent information.
Just wanted to let you know that I think it is important to include in the post that it is not possible to remove shipping_country field from Shipping in My Account Edit, because Save_address function has the following code:
Resulting the Customer would not be able to edit its shipping address or information.
Best regards!
Finally! “woocommerce_customer_meta_fields” is the hook I was searching for! Thank you so much….
Cheers,
Cees
You are a savior! Thank you so much for sharing your knowledge.
Greeting,
I have a problem that I don’t know how to solve, if anyone can help.
When entering an address in the field on the checkout page, it refreshes the entry “too quickly”, as soon as you stop typing after maybe 1 second or less, the address field is refreshed, and then you have to select it again and continue typing, which is a little irritating especially on mobile devices. Could I slow down the refresh time somewhere, to give more time for the customer to enter the correct address?
Hey, first things first we need to remove
.address-field
class from a field wrapper. Or better change it.address-field-custom
for example.Please note, that
woocommerce_checkout_fields
won’t help us with removing the class, onlywoocommerce_default_address_fields
. And of course you may need to do it not only for the City field but for all the other address fields as well.Our next thing to do is to alter
queue_update_checkout()
method, which is incheckout.js
file.