Complete guide to Wordpress menu sourcing in Gatsby

bouthouri

Oussama Bouthouri

Posted on July 13, 2019

Complete guide to Wordpress menu sourcing in Gatsby

Using the Gatsby plugin gatsby-source-wordpress we can fetch almost everything from a Wordpress website.
There are only two things that were not there by default, the menus and the custom options.
This blog post is about menus.

1. Preparing the menu

As I have just mentioned, the Wordpress menu are, by default, not available on the Wordpress REST api, so the first step is to make them visible.

We can make this easily with a Wordpress plugin WP REST API Menus that you can't find when you want to install it directly from your website.

You need to download it and use WordPress Admin Plugin Upload, here's a link to a tutorial if you don't know how the.
Now that you have installed the plugin, your menus are available on the rest api.

WP-REST-API V2 Menus is not the good plugin to install.

2. The request:

After installing the plugin if you run gatsby develop a new GraphQL request will be available:

  • allWordpressWpApiMenusMenus to get the menus available
  • allWordpressWpApiMenusMenusItems to get the item of the menus
  • allWordpressWpApiMenusMenuLocations to get the available menu location

3. Useful request:

There are a lot of useful requests but in our case we just need to retrieve the menus and their items "content", and this is the request for that.

{
  allWordpressWpApiMenusMenusItems {
    edges{
      node {
        slug
        name
        items {
          title
          url
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

If your menu contains sub-menus use the wordpress_childer attribute

{
  allWordpressWpApiMenusMenusItems {
    edges{
      node {
        slug
        name
        items {
          title
          url
          wordpress_children {
            title
            url
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

If you want to retrieve a specific menu use filters like this

{
  allWordpressWpApiMenusMenusItems(filter: {slug: {eq: "sidebar-menu"}}) {
    edges{
      node {
        slug
        name
        items {
          title
          url
          object_slug
          wordpress_children {
            title,
            url
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Getting the menu

The complete code in a Gatsby component:
Now that we have all what we need, this is a small component to display the Wordpress menu

import React from "react"
import { StaticQuery, graphql } from "gatsby"

export default () => (
  <StaticQuery
    query={graphql`
      query {
        allWordpressWpApiMenusMenusItems(
          filter: { slug: { eq: "sidebar-menu" } }
        ) {
          edges {
            node {
              slug
              name
              items {
                title
                url
                object_slug
                wordpress_children {
                  title
                  url
                }
              }
            }
          }
        }
      }
    `}
    render={data => {
      return (
        <nav className="menu">
          <ul className="nav flex-column">
            {data &&
              data.allWordpressWpApiMenusMenusItems &&
              data.allWordpressWpApiMenusMenusItems.edges &&
              data.allWordpressWpApiMenusMenusItems.edges[0] &&
              data.allWordpressWpApiMenusMenusItems.edges[0].node &&
              data.allWordpressWpApiMenusMenusItems.edges[0].node.items &&
              data.allWordpressWpApiMenusMenusItems.edges[0].node.items.map(
                prop => {
                  return (
                    <li className="nav-item">
                      <a
                        className="nav-link active"
                        href={prop.url}
                        alt={prop.title}
                      >
                        {prop.title}
                      </a>
                      <div className="sub-menu">
                        {prop &&
                          prop.wordpress_children &&
                          prop.wordpress_children.map(child => {
                            console.log("child ", child)

                            return (
                              <a
                                className="dropdown-item"
                                href={child.url}
                                alt={child.title}
                              >
                                {child.title}
                              </a>
                            )
                          })}
                      </div>
                    </li>
                  )
                }
              )}
          </ul>
        </nav>
      )
    }}
  />
)
Enter fullscreen mode Exit fullscreen mode

5. The correct url

If your Wordpress domain name is not the same as your Gatsby website don't forget to replace them.
In gatsby-config.js put this in the plugin declaration

searchAndReplaceContentUrls: {
    sourceUrl: "http://localhost:8080",
    replacementUrl: "http://localhost:8000",
}
Enter fullscreen mode Exit fullscreen mode

here's the complete example:

{
      resolve: "gatsby-source-wordpress",
      options: {
        baseUrl: "http://localhost:8080/",
        protocol: "http",
        hostingWPCOM: false,
        useACF: false,
        excludedRoutes: ["**/settings", "**/themes", "**/users/me"],
        verboseOutput: true,
        searchAndReplaceContentUrls: {
          sourceUrl: "http://localhost:8080",
          replacementUrl: "http://localhost:3000",
        },
      },
    }
Enter fullscreen mode Exit fullscreen mode

6. Conclusion

This is not always the good approach and sometime it's overkill, but it's nice to know everything about Wordpress's menus and their use in Gatsby. You might have another opinion or a different method.
Please share your point of view with me in comment.

💖 💪 🙅 🚩
bouthouri
Oussama Bouthouri

Posted on July 13, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related