Registering with WooCommerce Admin Navigation

Introduction

Recent versions of WooCommerce include a dedicated, immersive navigation menu that supersedes the underlying WordPress navigation. In order to provide a first-class experience for merchants, it’s important for WooCommerce extensions to register support for this navigation. This ensures that their navigation items will be close at hand for merchants as they manage their stores.

There are a number of different ways to create and manage WooCommerce navigation items. Depending on your extension’s set up, one or more approaches below may be appropriate for your particular situation.


Creating navigation categories and items with PHP

While the WooCommerce navigation menu supports React-based extensions, no JavaScript is necessary for adding new navigation items. WooCommerce provides a PHP API for handling this.

For the purposes of illustration, assume that your extension has some admin content available at /wp-admin/admin.php?page=my-great-extension. To register that content with the WooCommerce navigation, you’ll need to:

  • Import the Navigation classes to your PHP file.
  • Implement a class availability check as a safeguard.
  • Register any applicable navigation items or categories.
  • Hook your registration logic into the admin_menu action.

Importing navigation classes

In order to use the WooCommerce navigation API, you need to import the classes that support them. Be sure to include them alongside any other imports.

use Automattic\WooCommerce\Admin\Features\Navigation\Menu;
use Automattic\WooCommerce\Admin\Features\Navigation\Screen;
use Automattic\WooCommerce\Admin\Features\Features;

Checking for navigation feature availability

While recent versions of WooCommerce include the dedicated navigation, not all stores will be running a version that includes it.

if (
    ! method_exists( Screen::class, 'register_post_type' ) ||
    ! method_exists( Menu::class, 'add_plugin_item' ) ||
    ! method_exists( Menu::class, 'add_plugin_category' ) ||
    ! Features::is_enabled( 'navigation' )
) {
    return;
}

Registering menu items and categories

If the navigation classes are available, you can add your content using the Menu class’ add_plugin_item() and add_plugin_category() functions. When adding items and categories, it’s important to choose an ID carefully because no two navigation items may have the same ID. Prefixing IDs can be a practical approach for this constraint.

function register_menu_items() {

    // Register a standalone menu item. 
    Menu::add_plugin_item(
        array(
            'id'         => 'my-extension',
            'title'      => 'My Extension',
            'capability' => 'manage_woocommerce',
            'url'        => 'my-extension-slug',
        )
    );

    // Register a navigation category with a child item.
    Menu::add_plugin_category(
        array(
            'id'     => 'my-extension-category',
            'title'  => 'My Extension Category',
            'parent' => 'woocommerce',
        )
    );

    Menu::add_plugin_item(
        array(
            'id'         => 'my-extension-cat-page',
            'title'      => 'My Extension Cat Page',
            'capability' => 'manage_woocommerce',
            'url'        => 'my-extension-slug-cat-page',
            'parent'     => 'my-extension-category',
        )
    );
}

Note: the example above has been simplified for the purposes of demonstration. In a real-world extension, you’d likely include internationalization support for the title string, and the register_menu_items function itself would be properly encapsulated in an appropriate class.

The code above will create an “Extensions” menu in the WooCommerce navigation and will add a navigation item for “My Extension” as well as a “My Extension Category” category with a “My Extension Cat Page” navigation item nested underneath it.

Be sure to read through the [code reference for the Menu class](https://woocommerce.github.io/code-reference/classes/Automattic-WooCommerce-Admin-Features-Navigation-Menu.html
), because there are other helper functions available as well as functions for adding items to core WooCommerce navigation categories.

Hooking into the navigation renderer

Finally, to ensure everything runs as it should, hook your registration function into the admin_menu action. In a real-world extension, this call to add_action would probably be a part of your extension’s initialization process.

add_action( 'admin_menu', 'register_navigation_items' );

Working with custom post types

If your extension creates custom post types, you can register those post types with WooCommerce’s navigation similar to the way we added navigation items above, but you’ll need to register the screen ID to identify that the screen supports the WooCommerce navigation. Here’s an example of what that might look like:

function register_menu_items {

    // Use the Screen class to register your post types' screen.
    Screen::register_post_type( 'my-post-type' );

    // Get menu item templates of nav items available for a given post type.
    $post_type_items = Menu::get_post_type_items(
        'my_post_type',
        array(
            'title'  => 'My Extension Post Type',
            'parent' => 'my-extension-category',
        )
    );

    // Supply the "all" item to add_plugin_item to feed it the templates
    Menu::add_plugin_item( $post_type_items['all'] );

}

Be sure to read through the code reference for the Navigation classes, because there are other helper functions available as well as functions for adding items to core WooCommerce navigation categories.


Using JavaScript and SlotFill to customize navigation item behavior

If your extension is set up to use WooCommerce Admin’s React features, you can use JavaScript to replace existing navigation items with custom React components. This can be useful for things like adding route-aware links to navigation items to avoid unnecessary page refreshes. Below is a simplified example of a custom component that would replace the navigation item we created with the PHP API earlier in this guide.

// src/index.js

// Import external dependencies.
import { WooNavigationItem } from '@woocommerce/navigation';
import { registerPlugin } from '@wordpress/plugins';
import { Button } from '@wordpress/components';

// Build a functional React component using JSX.
const MyExtenstionNavItem = () => (
    <WooNavigationItem item="my-extension">
        <Button>Hello From JavaScript</Button>
    </WooNavigationItem>
);

// Use the registerPlugin function to register your component with the navigation 
registerPlugin( 'my-extension', { render: MyExtenstionNavItem } );

Note that the item property we supply to our component (“my-extension”) matches the id of the navigation item we are supplanting. This is important because it is how WooCommerce knows which navigation item to modify.