header blog

WooCommerce My Account Shortcode Explained

The My Account page, order history, addresses, payment methods, is built entirely from one shortcode. Unlike cart and checkout, there isn’t yet a block-based alternative for it, so if you’re customizing this page at all, you’re working with the shortcode and a filter, not a block.

The Code

To display the My Account area, add this shortcode to a page’s content:

[woocommerce_my_account]

That’s the entire shortcode, no attributes. Everything else, logged-in state, order history, the registration form for guests, is handled internally by WooCommerce based on your Accounts & Privacy settings.

If you need to customize which tabs show up, here’s a snippet that removes the Downloads tab (useful for stores that don’t sell digital products), renames Orders to something more specific, and adds a custom tab before Logout:

add_filter( 'woocommerce_account_menu_items', 'fixelar_custom_account_tabs' );

function fixelar_custom_account_tabs( $items ) {

    // Remove a tab you don't need
    unset( $items['downloads'] );

    // Rename an existing tab
    $items['orders'] = __( 'Order History', 'woocommerce' );

    // Add a custom tab before Logout
    $logout = $items['customer-logout'];
    unset( $items['customer-logout'] );

    $items['loyalty-points'] = __( 'Loyalty Points', 'woocommerce' );

    $items['customer-logout'] = $logout;

    return $items;
}

Where to Put This Code

The [woocommerce_my_account] shortcode goes in the content of whichever page is assigned as My Account, not in functions.php.

The woocommerce_account_menu_items filter is PHP, so it belongs in your child theme’s functions.php or a snippets plugin like Code Snippets. Keeping it out of a parent theme avoids losing the customization on the next theme update.

Adding a new tab like loyalty-points in the example above only creates the menu entry. Making the tab actually show content when clicked requires a matching endpoint registered with add_rewrite_endpoint() and a function hooked to woocommerce_account_loyalty-points_endpoint, plus a rewrite flush. Renaming or removing existing tabs works immediately with just the filter above; adding a genuinely new one is a bigger job.

How the Filter Works, Line by Line

add_filter( 'woocommerce_account_menu_items', 'fixelar_custom_account_tabs' ); hooks your function into the array WooCommerce uses to build the My Account navigation menu.

The $items array is a simple key-value list. Each key (dashboard, orders, downloads, edit-address, payment-methods, edit-account, customer-logout) is the tab’s internal ID, and the value is the label displayed to the customer.

unset( $items['downloads'] ); removes a tab by deleting its entry. This hides it from the menu, but the underlying page is still reachable by direct URL unless you also disable the corresponding endpoint under WooCommerce → Settings → Advanced → Account endpoints.

$items['orders'] = __( 'Order History', 'woocommerce' ); changes the label of an existing tab without touching its function or position.

The logout-preserving pattern (save the value, unset it, add new items, then re-add it) exists because PHP arrays preserve insertion order. Adding a new key normally appends it wherever it’s added in the code, which would push it after Logout. Removing and re-adding Logout last keeps it at the bottom of the menu, matching customer expectations.

Real Use Cases

Removing tabs that don’t apply to your store. Physical-goods stores rarely need the Downloads tab. B2C stores sometimes hide Payment Methods if they don’t support saved cards. A cleaner menu reduces confusion.

Renaming tabs to match your store’s language. “Orders” might make more sense as “My Bookings” for a service-based store, or “My Subscriptions” for a subscription business.

Reordering tabs to prioritize what customers actually use. Some stores move Orders above Dashboard, since most returning customers are checking order status, not reading a dashboard summary.

Adding a custom account section for loyalty points, referrals, or store credit. Once you’re already running a program like this, exposing it as its own My Account tab keeps everything account-related in one place instead of a separate page customers have to remember.

Common Issues

The My Account page is blank. Confirm the page is assigned as the My Account page under WooCommerce → Settings → Advanced → Page setup, and that the [woocommerce_my_account] shortcode is still present in its content.

A removed tab is still accessible by direct URL. unset() in the filter only removes the menu link, not the endpoint itself. To fully disable a section, also check WooCommerce → Settings → Advanced → Account endpoints and clear the relevant field, or add a redirect for that endpoint.

A newly added tab shows in the menu but the page is empty when clicked. This means the endpoint was never registered. Adding a tab through woocommerce_account_menu_items alone only creates the link; the content requires add_rewrite_endpoint() and a matching action hook.

Tab order changes aren’t taking effect. If another plugin also hooks into woocommerce_account_menu_items, priority order matters. Whichever function runs last wins, so check what else is hooked into that filter if your changes seem to get overwritten.

If you’d rather have a fully functional custom My Account tab, complete with a working endpoint and content, built and tested properly, that’s exactly the kind of work Fixelar handles as part of our WooCommerce custom development services. We handle the endpoint registration and the content, not just the menu label.