WooCommerce My Account Menu Customization

default my account menu woocomerce

It is a complete my account menu customization guide. In this tutorial I will explain you how to remove links from the menu properly, how to add pages with custom icons there and how to reorder menu elements.

default my account menu woocomerce
This is how “My Account” menu looks by default with Storefront theme active.

Remove Links from My Account Menu 

Probably, it is the most easiest part of this tutorial. For example let’s imagine that our e-commerce shop doesn’t sell physical goods – and in that case maybe we do not need Addresses section (yes, I know that Billing Address details are also there, but we’re just learning now). Or maybe you want to remove Downloads from WooCommerce my account menu. Both are possible.

/**
 * @snippet       Remove My Account Menu Links
 * @author        Misha Rudrastyh
 * @url           https://rudrastyh.com/woocommerce/my-account-menu.html#remove_items
 */
add_filter( 'woocommerce_account_menu_items', 'misha_remove_my_account_links' );
function misha_remove_my_account_links( $menu_links ){
	
	unset( $menu_links[ 'edit-address' ] ); // Addresses
	
	//unset( $menu_links[ 'dashboard' ] ); // Remove Dashboard
	//unset( $menu_links[ 'payment-methods' ] ); // Remove Payment Methods
	//unset( $menu_links[ 'orders' ] ); // Remove Orders
	//unset( $menu_links[ 'downloads' ] ); // Disable Downloads
	//unset( $menu_links[ 'edit-account' ] ); // Remove Account details tab
	//unset( $menu_links[ 'customer-logout' ] ); // Remove Logout link
	
	return $menu_links;
	
}

I hope you know where to insert all the code from this post, if you don’t – insert the code to your current theme functions.php.

WooCommerce My Account menu with removed Addresses link.
WooCommerce My Account Menu Customization 11

How to remove endpoints so the removed pages will return 404 

It was simple enough, but we have not finished yet, if you go to /my-account/edit-address/ directly, it will show you Addresses page. This should not happen, right?

The first thought that came to my mind was to remove endpoints somehow. Dealing with $wp_rewrite or something like that. Please do not!

The thing is when you want to remove both the menu item and its page as well, you do not need any coding. You can find all the default My Account subpages in WooCommerce > Settings > Advanced. All you need is just to set a specific endpoint empty.

WooCommerce Edit My Account Endpoints in Settings
WooCommerce My Account Menu Customization 12

Rename My Account Menu Links 

Can be done with the same woocommerce_account_menu_items, all you need is to know a tab ID you would like to rename, all of them were mentioned above.

/**
 * @snippet       Rename My Account Menu Links
 * @author        Misha Rudrastyh
 * @url           https://rudrastyh.com/woocommerce/my-account-menu.html#rename_tabs
 */
add_filter( 'woocommerce_account_menu_items', 'misha_rename_downloads' );

function misha_rename_downloads( $menu_links ){
	
	// $menu_links[ 'TAB ID HERE' ] = 'NEW TAB NAME HERE';
	$menu_links[ 'downloads' ] = 'My Files';

	return $menu_links;
}
rename my account menu links
“Downloads” was renamed to “My Files”.

The same way you can rename any menu item you want 👍

Change My Account Menu Items Order 

Changing order of my account menu items is just changing order of array elements. So, if you didn’t remove or add any custom menu links there, your $menu_links may look like this:

print_r( $menu_links );
/* Array
(
    [dashboard] => Dashboard
    [orders] => Orders
    [downloads] => Downloads
    [edit-address] => Addresses
    [edit-account] => Account details
    [customer-logout] => Logout
) */

The easiest way to reorder it is just to re-create this array.

/**
 * @snippet       Reorder My Account Menu Links
 * @author        Misha Rudrastyh
 * @url           https://rudrastyh.com/woocommerce/my-account-menu.html#change-order
 */
add_filter( 'woocommerce_account_menu_items', 'misha_menu_links_reorder' );

function misha_menu_links_reorder( $menu_links ){
	
	return array(
		'dashboard' => __( 'Dashboard', 'woocommerce' ),
		'downloads' => __( 'My Files', 'mishadomain' ),
		'orders' => __( 'Orders', 'woocommerce' ),
		//'edit-address' => __( 'Addresses', 'woocommerce' ),
		'edit-account' => __( 'Account details', 'woocommerce' ),
		'customer-logout' => __( 'Logout', 'woocommerce' )
	);

}

I also decided to add the changes that we’ve made in this and this chapters.

WooCommerce customized my account menu
WooCommerce My Account Menu Customization 13

Add Custom Page in My Account 

In order to make it easier I will just provide the read-to-use code, you can insert it to your current theme functions.php file or a custom plugin.

/**
 * @snippet       Add Custom Page in My Account
 * @author        Misha Rudrastyh
 * @url           https://rudrastyh.com/woocommerce/my-account-menu.html#add-custom-tab
 */
// add menu link
add_filter ( 'woocommerce_account_menu_items', 'misha_log_history_link', 40 );
function misha_log_history_link( $menu_links ){
	
	$menu_links = array_slice( $menu_links, 0, 5, true ) 
	+ array( 'log-history' => 'Log history' )
	+ array_slice( $menu_links, 5, NULL, true );
	
	return $menu_links;

}
// register permalink endpoint
add_action( 'init', 'misha_add_endpoint' );
function misha_add_endpoint() {

	add_rewrite_endpoint( 'log-history', EP_PAGES );

}
// content for the new page in My Account, woocommerce_account_{ENDPOINT NAME}_endpoint
add_action( 'woocommerce_account_log-history_endpoint', 'misha_my_account_endpoint_content' );
function misha_my_account_endpoint_content() {

	// of course you can print dynamic content here, one of the most useful functions here is get_current_user_id()
	echo 'Last time you logged in: yesterday from Safari.';

}

Some notes:

  • I used array_splice() PHP function in order to display our “Log history” link just before “Logout” link. If I used code like this $menu_links[ 'log-history' ] = 'Log history', then our new link was displayed at the very end.
  • Everything else should be pretty clear but because we made changes in permalinks, do not forget to refresh the cache. In order to do that please go to Settings > Permalinks in WordPress admin and just save changes without changing anything.

How to set a custom icon 

When you add a custom page into My Account, by default its icon is kind of boring:

default icon in my account
WooCommerce My Account Menu Customization 14

What about changing it to something more interesting?

Great idea, but the implementation may vary depending on a theme you’re currently using. For WooCommerce Storefront theme it is quite simple – you can use any of FontAwesome icons for that purpose.

So, you can go to FontAwesome website, then choose an icon and copy its unicode code.

how to change an icon for a my account menu link WooCommerce
From FontAwesome website.

Now we have to use that code in CSS like that:

.woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link--log-history a:before{
	content: "\f21b"
}

You can add this CSS to an existing .css file of your theme or via wp_head action hook. Don’t forget to change --log-history part of the CSS class with your own.

Now, if you go to /my-account/log-history/ or click the appropriate menu item, this page should appear.

how to add a custom page to WooCommerce my account menu
WooCommerce My Account Menu Customization 15

Add Menu Link with External URL 

There is no specific filter for that but I will show you a very simple trick. In the first part of the code we will add a new element to menu items array.

In the second part of the code we’ll just hook its URL.

<?php
// add link to the menu
add_filter ( 'woocommerce_account_menu_items', 'misha_one_more_link' );
function misha_one_more_link( $menu_links ){

	// we will hook "anyuniquetext123" later
	$new = array( 'anyuniquetext123' => 'Gift for you' );

	// or in case you need 2 links
	// $new = array( 'link1' => 'Link 1', 'link2' => 'Link 2' );

	// array_slice() is good when you want to add an element between the other ones
	$menu_links = array_slice( $menu_links, 0, 1, true ) 
	+ $new 
	+ array_slice( $menu_links, 1, NULL, true );

	return $menu_links;
 
}

// hook the external URL
add_filter( 'woocommerce_get_endpoint_url', 'misha_hook_endpoint', 10, 4 );
function misha_hook_endpoint( $url, $endpoint, $value, $permalink ){
 
	if( 'anyuniquetext123' === $endpoint ) {
 
		// ok, here is the place for your custom URL, it could be external
		$url = 'https://example.com';
 
	}
	return $url;
 
}

// custom icon
add_action( 'wp_head', 'misha_link_custom_icon' );
function misha_link_custom_icon() {
	?><style>
	.woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link--anyuniquetext123 a:before{
		content: "\f1fd"
	}
	</style><?php
	
}

This is how My Account menu looks for me now:

menu item with custom icon
WooCommerce My Account Menu Customization 16

My Account Menu Hooks 

Using the action hooks below you can add any text or HTML code just before and just after the menu <nav> element.

<?php
	add_action( 'woocommerce_before_account_navigation', 'misha_some_content_before' );
	function misha_some_content_before(){
		echo 'blah blah blah before';
	}

	add_action( 'woocommerce_after_account_navigation', 'misha_some_content_after' );
	function misha_some_content_after(){
		?>
			<p>blah blah blah after</p>
		<?php
	}

But I want you to keep in mind one thing – this may not be so simple as it seems, because in most cases the My Account <nav> element has float:left CSS property.

That’s all!