WooCommerce My Account Menu

When I faced with My Account menu first time, my client asked me to add a custom link to it. I was surprised that this task was not so simple as it sounds.

#WooCommerce, #myaccount  /    /   159

WooCommerce Default My Account menu.
This is how “My Account” menu looks by default.

How to Remove Tabs from My Account menu. How to Remove their Endpoints as well and Make the Appropriate Pages to Return 404. #

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.

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 not – to functions.php. The result:

WooCommerce My Account menu with removed Addresses link.

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, should it?

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 above code is good. But 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 > Account. All you need is just to set a specific endpoint empty.

WooCommerce Edit My Account Endpoints in Settings

How to Rename Tabs in My Account #

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.

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;
}

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

Add My Account Menu Links with Custom URLs #

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 (if you have experience with adding columns to admin Dashboard earlier, this code will be familiar to you).

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

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;
 
 
}
 
add_filter( 'woocommerce_get_endpoint_url', 'misha_hook_endpoint', 10, 4 );
function misha_hook_endpoint( $url, $endpoint, $value, $permalink ){
 
	if( $endpoint === 'anyuniquetext123' ) {
 
		// ok, here is the place for your custom URL, it could be external
		$url = site_url();
 
	}
	return $url;
 
}

But what about the menu icon?

If you use WooCommerce StoreFront theme, this question could appear in your mind. Really, how to add your own beautiful icon there?

Let’s begin with the point that StoreFront uses Font Awesome icon collection. So, go to their official website, choose any icon and find its unicode code.

Font Awesome: Where to find icon unicode string.

Once you found it, use it in CSS:

body.woocommerce-account ul li.woocommerce-MyAccount-navigation-link--anyuniquetext123 a:before{
	content: "\f1fd"
}

This is how My Account menu looks for me now:

Here we added custom My Account menu link with its own icon.
Custom tabs in WooCommerce My Account

Add Custom My Account Menu Tabs with their Own Pages #

Well, this part of the tutorial is also simple enough and consists of 4 steps. Sometimes people forget about 4th step, but it is as much important as the others.

So, here is how to add additional menu items with custom pages:

/*
 * Step 1. Add Link (Tab) to My Account menu
 */
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;
 
}
/*
 * Step 2. Register Permalink Endpoint
 */
add_action( 'init', 'misha_add_endpoint' );
function misha_add_endpoint() {
 
	// WP_Rewrite is my Achilles' heel, so please do not ask me for detailed explanation
	add_rewrite_endpoint( 'log-history', EP_PAGES );
 
}
/*
 * Step 3. 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.';
 
}
/*
 * Step 4
 */
// Go to Settings > Permalinks and just push "Save Changes" button.

I also took care of the icon.

body.woocommerce-account ul li.woocommerce-MyAccount-navigation-link--log-history a:before{
	content: "\f1da";
}

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

Custom My Account menu element with its own page.

Actually this is all I wanted to show you, but below is a small bonus.

Two WordPress Action Hooks that Allows to Add Any Content Before and After WooCommerce My Account Menu #

So, 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.

Thank you for reading! Subscribe below if you want to receive new awesome WordPress and WooCommerce-related content once a week. Or leave a comment if you still have unanswered questions.

Misha Rudrastyh
About the author Misha Rudrastyh

Passionate about WordPress and snowboarding, creating websites for over 9 years! Let's work together — just contact me.

If you are a developer too, subscribe to my facebook page.

Comments 159

← Older
  • Thanks for the tutorial!

    When you click the links the h1 tag changes (ie. “My Account”, “Orders”, “Account Details”, etc.). But it doesn’ change for the new custom tab inserted?

    I have your code as this:

    // Add new button link to "My Account" page in Woo
    // SOURCE - https://rudrastyh.com/woocommerce/my-account-menu.html
    add_filter ( 'woocommerce_account_menu_items', 'usca_group_registration_link', 40 );
    function usca_group_registration_link( $menu_links ){
     
    	$menu_links = array_slice( $menu_links, 0, 1, true ) 
    	+ array( 'group-registration' => 'Group Registration' )
    	+ array_slice( $menu_links, 1, NULL, true );
     
    	return $menu_links;
    }
     
    // Register Permalink Endpoint
    add_action( 'init', 'usca_add_endpoint' );
    function usca_add_endpoint() {
    	// WP_Rewrite is my Achilles' heel, so please do not ask me for detailed explanation
    	add_rewrite_endpoint( 'group-registration', EP_PAGES );
    }
     
    // Content for the new page in My Account, woocommerce_account_{ENDPOINT NAME}_endpoint
    add_action( 'woocommerce_account_group-registration_endpoint', 'usca_my_account_endpoint_content' );
    function usca_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 do_shortcode( '[wdm_group_users]' );
    }

    Everything seems to be working fine except that the title tag is not updating. I have flushed permalinks and flushed cache.

    Any thoughts?

    • Thank you for the very interesting question! 🔥

      Hmmm… I have only this idea:

      add_filter( 'the_title', 'misha_hook_my_account_title' );
       
      function misha_hook_my_account_title( $title ) {
       
      	global $wp_query;
       
      	if( isset( $wp_query->query_vars['group-registration'] ) && $title == 'My account' ) {
      		return 'Group Registration';
      	}
      	return $title;
       
      }
      • I have tried your suggestion, but it is not changing the title on the newly created endpoint.

      • Strange, for me it works. Maybe the title is hardcoded in your theme.

        • I see the issue…

          $title == 'My account' when I change it to $title == 'My Account' your code changes the title.

          But I run into another issue is that I have a link in my top nav bar entitled “My Account” and it changes that link name as well.

        • Just go to Appearance > Menus and manually change it there.

  • Hi Misha

    I’ve got a new menu with a specific new filed for the user account.
    How can i save this changes with a “save changes” button.

    Thank you for your help.

    kind regards
    sandro

  • Hi Misha!

    Thank you once again for the great tutorial. But one question, for an external url added in $url = (‘myurl’)

    How can I open it in a new tab?

    Is there a way to do that?

    ErnestPH

  • Thank you so much for this code, Misha! This has been very handy in adding a custom URL to our customers’ account page to process their own returns.

    My question would be:

    We are using Custom URL code, and am curious how one would go about making that custom URL open in a new tab, as our return processing is handled on a different site.

    TIA! Very much appreciated.

  • Does someone has figure out how to get My Account Menu Links with Custom URLs to open in a new tab? I saw they said using jquery but I couldn’t make it work so far.

  • Hi Misha,

    thanks for code and examples. I have two questions about this:

    1.) How do I have to set the url for an internal WordPress site? Do I have to set the complete url, the page id or something?

    2.) Is it possible to change the first page displayed? I want to hide the dashboard an make another menu-point the first one.

    Thanks for some help!

    Best regards,

    Timo

    • Hi Timo,

      1) Yep, the complete URL, you can use site_url() or home_url() for that.

      2) The code below works for me.

      add_action('template_redirect', 'misha_default_my_account_tab' );
      function misha_default_my_account_tab(){
       
      	if( is_account_page() && wc_get_page_permalink( 'myaccount' ) == "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]" ){
      		 wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) . '/edit-address' );
      		 exit;
      	}
       
      }
  • I want my menu link to go to a specific URL and not use $url = site_url();

    What can I change to have a custom URL in there?

  • I copy/pasted your code for adding a tab in the menu, but nothing happend

  • I did. At the bottom
    Do I need to delete cache ?

Leave your question or feedback

phpjsHTMLCSSSQLCode
Please, enter a comment
Please, enter a name
Incorrect email