I'm using React to build the front-end of a site which uses Wordpress for the back-end. In particular, I'm using the Wordpress REST API to pull in and display content.

By default, the Wordpress REST API doesn't expose menu information, so I've extended it to include it:

function get_menu( $data ) {
  return wp_get_nav_menu_items( $data[ 'slug' ] );

add_action( 'rest_api_init', function () {

  register_rest_route( 'custom', '/menus/(?P<slug>[a-zA-Z0-9-]+)', 
      'methods'  => 'GET',
      'callback' => 'get_menu'


Now I can access my menu information with a request like the following:


The response I get for each of the items included in the menu looks like this:

ID: 13
attr_title: ""
classes: [""]
comment_count: "0"
comment_status: "closed"
db_id: 13
description: ""
filter: "raw"
guid: "http://localhost:8888/learn-react/admin/?p=13"
menu_item_parent: "0"
menu_order: 3
object: "page"
object_id: "8"
ping_status: "closed"
pinged: ""
post_author: "1"
post_content: " "
post_content_filtered: ""
post_date: "2018-02-10 08:57:52"
post_date_gmt: "2018-02-10 08:57:52"
post_excerpt: ""
post_mime_type: ""
post_modified: "2018-02-10 08:57:52"
post_modified_gmt: "2018-02-10 08:57:52"
post_name: "13"
post_parent: 0
post_password: ""
post_status: "publish"
post_title: ""
post_type: "nav_menu_item"
target: ""
title: "About"
to_ping: ""
type: "post_type"
type_label: "Page"
url: "http://localhost:8888/learn-react/admin/about/"
xfn: ""

My problem is I'm trying to use this data to put a link on each menu item, but since I'm using React Router I don't need the whole url (which is provided in the data above), but only the final slug. Here's my menu component:

class MainMenu extends React.Component {

  componentDidMount() {

  render() {

    let menuItemsArray = store.getState().menuReducer.mainMenuItems;     
    let menuItems = menuItemsArray.map( ( menuItem, index ) => {    

        <li key={ index }>
          <Link to={ menuItem.url }>{ menuItem.title }</Link>
    return (
      <ul>{ menuItems }</ul>

Using menuItem.url generates the following href, of course:


while, like I said, I would need something like menuItem.slug to generate:


What options do I have?

  • Option A: filter the output of wp_get_nav_menu_items() to not return full URLs. Option B: remove the http://localhost:8888/ part in your React script. Have you tried either?
    – swissspidy
    Feb 16, 2018 at 10:30
  • No, I haven't tried either of the options you suggest, but I was actually hoping for a way to achieve my goal by extending the API and adding a 'slug' parameter to the JSON response I posted above somehow. I realize it's probably more complicated, but it sounds cleaner to me. Otherwise I will try your ideas.
    – grazdev
    Feb 16, 2018 at 15:54

1 Answer 1


I had the same challenge, and fixed it by adding it to the response. Example:

function get_menu() {
    # Change 'menu' to your own navigation slug.
    $menu_items = wp_get_nav_menu_items('menu');
    foreach($menu_items as $menu_item) {
        // ALTERNATIVE: $slug = get_post_field( 'post_name', $menu_item->object_id );
        $slug = basename( get_permalink($menu_item->object_id) );
        $menu_item->slug = $slug;
    return $menu_items;

add_action( 'rest_api_init', function () {
        register_rest_route( 'myroutes', '/menu', array(
        'methods' => 'GET',
        'callback' => 'get_menu',
    ) );
} );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.