Designing a “Restaurant Menu” Block

An animation showing the transition between a selected block, with toolbar and "add" icon, and a deselected block. The block contains a heading that says "Appetizers," and lists four menu items along with their price and description.

Download Sketch file.

View InVision prototype.

I’ve wanted a better way of making restaurant menus since first working on’s restaurant menu custom post type a couple years ago. The process felt so slow, clunky, and divorced from the final product. CPTs never felt like the right method for providing this kind of content. Blocks provide a perfect opportunity to redesign how we add restaurant menus to our a site —  they’re UI-first, and both edited and previewed in-context.

What the best way to approach this kind of block? If I were to convert the restaurant CPT 1:1, it would look like:

  • A parent block to act as a container.
  • Child blocks for menu sections, featuring names and descriptions.
  • Child blocks within menu sections for menu items, featuring a placeholder for featured image, name, price, and description.
  • Custom taxonomies (“menu labels”) for menu items.

That seems like a whole lot of overhead for some content that, let’s be honest, doesn’t change very often. In many cases, the most a menu is changed is seasonally. I think we can ease the setup and maintenance of the block quite a bit.

Zooming In

Let’s look at simplifying restaurant menus down to their basic element: menu items. What if the only restaurant block that exists was a menu item?

Menu item on the top left, price on the top right, and description below were the most common pattern I found when reviewing restaurant menus.


  • Super simple — only need to enter three lines of text.
  • Minimal settings. Bold and italic options for some minimal text formatting control, but otherwise, no sidebar options.


  • You have to add a new block for every menu item, which will get tedious fast.
  • Because menu items aren’t grouped into a shared container, styling options for your menu are limited.
  • Doesn’t make sense to be able to add menu items everywhere.

These cons seem pretty big; let’s widen the scope.

Zooming Out

The next level above a menu item is a menu section. This is a parent container that features a section title, and individual menu items as children.

Heading and Menu Item contained within the same container block.


  • A wrapper means the entire section can be targeted with custom CSS, or support layout options.
  • The block could default to adding a new menu item next, so all you need to do to get another item is press “enter” at the end of the description field.
  • The block is still relatively simple, compared to the original.


  • Doesn’t support the complex scenarios that the original CPT supports, including taxonomies and featured images.

This feels like a happy middle-ground between the existing CPT, and a completely zoomed-in version of the block. The restaurant menu block acts as a wrapper with minimal default settings (columns, background color, text color) that could be extended to include fancy borders, background images, or other decorative elements. These could alternately be block styles.

Additionally, the block could register some core blocks like additional headings, paragraphs, and images as child blocks:

This negates the need for featured images, because you can insert images inline. And, most menus I’ve seen don’t show a thumbnail for every item on their menu — they mostly scatter highlights throughout the menu. This system supports that better, allowing for more flexible layout and display of menu items.

Block settings

Speaking of layout, this block could easily support some columns:

Two column menu layout.

I also included a toggle on the menu item itself for allergens. I don’t think this is necessarily the best label, but I couldn’t think of a better word. Toggling “allergens” on adds a new field underneath the item description, so you can add some extra details like “gluten-free” or “vegan.”

Allergen setting activated in the block
Allergen setting in the sidebar

The supported core blocks (heading, paragraph, image, and gallery) would keep their default settings.


After mocking up most of the block states, I linked them together in Sketch with the InVision Craft plugin:

I do this because I find actually clicking through the various block states is the best way to wrap my head around how the block actually works, and easily allows me to catch any errors I made while mocking up the block. In this case, I went through a couple rounds of minor revisions based on issues I saw in the prototype.

For example, an earlier iteration of a menu item showed the block outline around the entire block, rather than just the menu item. Most recently, I updated some of the toolbars to use more up-to-date Gutenberg patterns.

If you want to explore the design more closely, you can download the Sketch file or look through the InVision prototype.

If you want to use this design to build your own restaurant block, that’s cool too — just credit me and link back to my site in your plugin readme.

I’d prefer if this design wasn’t used for a premium plugin, but I’m okay with you using it as a starting point — just make sure to update it and introduce new features instead of building this exact design. Honor system!

What should I design next? 🤔

Posted on

One thought on “Designing a “Restaurant Menu” Block

  1. Thanks for this article Mel! I would add two other settings. One toggle for Chef suggestion and another one to add a volume/size field that would be necessary mainly for beverages and sometimes for plates.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.