Add Custom Fields to User Profiles
In this tutorial I am going to show two methods how you can add additional user profile fields in WordPress admin area. In the first one we are not going to use any plugins at all, in the second one – we will do the same, but with the help of my Simple Fields plugin.
Let’s get started, I think. Here is what we are going to create:

Method 1. Add and Save Fields Manually (Without Plugins)
Add fields
In order to add custom fields we have to use the two hooks (both of them).
show_user_profile– when you edit your own profile,edit_user_profile– when you edit a profile of any user.
<?php
add_action( 'show_user_profile', 'rudr_profile_fields' );
add_action( 'edit_user_profile', 'rudr_profile_fields' );
function rudr_profile_fields( $user ) {
// let's get custom field values
$city = get_user_meta( $user->ID, 'city', true );
// what about making a default value?
$drinks = ( $drinks = get_user_meta( $user->ID, 'drinks', true ) ) ? $drinks : 'wine';
?>
<h3>Additional Information</h3>
<table class="form-table">
<tr>
<th><label for="city">City</label></th>
<td>
<input type="text" name="city" id="city" value="<?php echo esc_attr( $city ) ?>" class="regular-text" />
</td>
</tr>
<tr>
<th>Drinks</th>
<td>
<ul>
<li>
<label>
<input type="radio" value="wine" name="drinks"<?php checked( $drinks, 'wine' ) ?> /> Wine
</label>
</li>
<li>
<label>
<input type="radio" value="coffee" name="drinks"<?php checked( $drinks, 'coffee' ) ?> /> Coffee
</label>
</li>
<li>
<label>
<input type="radio" value="water" name="drinks"<?php checked( $drinks, 'water' ) ?> /> Water
</label>
</li>
</ul>
</td>
</tr>
</table>
<?php
}We can get the field values from the database using either get_user_meta() or get_the_author_meta() functions. The important thing to remember is that you have to escape the values before printing them, you can see I used esc_attr( $city ). It is not necessary to do the same for $drinks value because the only place we used it is in checked() function (we can trust WordPress functions, you know).
Save fields
For saving fields values into the database we also need two action hooks – personal_options_update and edit_user_profile_update.
add_action( 'personal_options_update', 'rudr_save_profile_fields' );
add_action( 'edit_user_profile_update', 'rudr_save_profile_fields' );
function rudr_save_profile_fields( $user_id ) {
if( ! isset( $_POST[ '_wpnonce' ] ) || ! wp_verify_nonce( $_POST[ '_wpnonce' ], 'update-user_' . $user_id ) ) {
return;
}
if( ! current_user_can( 'edit_user', $user_id ) ) {
return;
}
update_user_meta( $user_id, 'city', sanitize_text_field( $_POST[ 'city' ] ) );
update_user_meta( $user_id, 'drinks', sanitize_text_field( $_POST[ 'drinks' ] ) );
}Never forget about sanitization. Of course, when we are talking about “drinks” field, using sanitize_text_field() may be not the best solution here, so I recommend you to consider whitelist validation like:
$drinks = in_array( $_POST[ 'drinks' ], array( 'wine', 'coffee', 'water' ) ) ? $_POST[ 'drinks' ] : 'wine';
update_user_meta( $user_id, 'drinks', $drinks );Method 2. Easy and Simple (With Plugin)
Here is a step by step:
- Install and activate my Simple Fields plugin on your website.
- Copy and paste the code below into your current theme
functions.php.
add_filter( 'simple_register_user_settings', 'rudr_user_settings' );
function rudr_user_settings( $settings ) {
$settings[] = array(
'id' => 'my_settings',
'fields' => array(
array(
'id' => 'city',
'label' => 'City',
'type' => 'text'
),
array(
'id' => 'drinks',
'label' => 'Drinks',
'type' => 'radio',
'options' => array(
'wine' => 'Wine',
'coffee' => 'Coffee',
'water' => 'Water'
),
),
)
);
return $settings;
}And now we have almost the same result:

Bonus. Add Contact Method Fields
You might have noticed that our fields have been added at the end of user profiles pages. But there is also a possibility to add fields under a Contact Info section if you’re using user_contactmethods filter hook.
add_filter( 'user_contactmethods', 'rudr_contact_methods' );
function rudr_contact_methods( $contactmethods ) {
$contactmethods[ 'instagram' ] = 'Instagram';
return $contactmethods;
}Here we are:

Misha Rudrastyh
Hey guys and welcome to my website. For more than 15 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
Excellent! Just what I was looking for. Thanks very much.
Hi Misha – Greate example, thank you.
I used ‘Method 1’ and it all shows successfully in the backend and is editable.
I’m using woocommerce, how do I show the new fields in ‘MY Account’ section, in the ‘Account Details’ section, the woocommerce users only have access to this area to edit, not the backend. Many thanks in advance. Hopefully nice and simple
Bump!… I’d like to know the answer too.