Skip to content

Retrieving child items using GraphQL

Posted in :

rbatallas

If you’re thinking of creating a new menu navigation for your website, here is an easy way to do it using headless with Next.js.

So, the first thing to do is create the model for each item and the menu.

interface NavigationModel {
  Url: string;
  Text: string;
}

interface NavigationMenu {
  MenuItems: NavigationModel[];
}

Now, the step is to define an async method to retrieve the data using the Sitecore endpoint with the GraphQL client. I’m getting all the items under home, but filtering only the content items that are pages by using the template ID.

export const fetchMenuItems = async (language: string) => {
  const graphQLClient = new GraphQLClient(config.graphQLEndpoint);
  graphQLClient.setHeader('sc_apikey', config.sitecoreApiKey);
  const homePageSourcePath = '/sitecore/content/SUGLATAM/Workshop/Workshop Site/Home';
  const menuItemTemplateId = '{A956FDF7-E918-4BEE-9952-53B4E5D14DC5}';

  const query = `
    query {
      item(path: "${homePageSourcePath}", language: "${language}") {
        children(
          includeTemplateIDs: ["${menuItemTemplateId}"]
        ) {
          results {
            ... on Item {
              name
              id
              url{
                path
              }
            }
          }
        }
      }
    }
  `;

  const data = await graphQLClient.request(query);

  const menuList: NavigationMenu = {
    MenuItems: [],
  };

  data.item.children.results.map((menu: any) => {
    const menuItem: NavigationModel = {
      Url: menu.url.path,
      Text: menu.name,
    };
    menuList.MenuItems.push(menuItem);
  });

  return menuList;
};

Finally, let’s define and print the component, calling the async method previously created by sending as a parameter the language of the content you are planning to get the items.

const MenuNavigation = (): JSX.Element => {
  const [menuItemResult, setMenuItemResult] = useState<NavigationMenu | null>(null);

  useEffect(() => {
    fetchMenuItems('en').then((menu) => {
      setMenuItemResult(menu);
    });
  }, []);

  const liItems =
    menuItemResult &&
    menuItemResult.MenuItems.map((item: NavigationModel, key: number) => {
      return (
        <li key={key}>
          <Link href={item.Url.toLowerCase()} target="_self">
            {item.Text}
          </Link>
        </li>
      );
    });
  return (
    <div className="g-u-1 g-u-lg-3-5" id="menu">
      <nav>
        <ul>{liItems}</ul>
      </nav>
    </div>
  );
};

export default MenuNavigation;

And that is it, in this way, you can easily create a navigation menu for a headless project.

Happy coding 🙂