How We Built a Drag‑Drop Electronic Menu Builder with SVG & React

This article details the design and implementation of a customizable electronic menu system that evolved from static images to an H5‑based, SVG‑driven, React-powered solution, covering business requirements, technology selection, data binding, rendering, store isolation, and offline stability.

Goodme Frontend Team
Goodme Frontend Team
Goodme Frontend Team
How We Built a Drag‑Drop Electronic Menu Builder with SVG & React

Background

To help readers understand what an electronic menu is, we first show the evolution of the Guming menu from paper to the current electronic version, from static images to H5 links.

Note: The image‑based electronic menu can also be reproduced 1:1 by dragging materials in the site builder.

Business Situation

Before the H5 version, the electronic screen displayed a single image. With 8,000 stores and multiple brands, several problems emerged:

Designers had to create 100‑200 menu images for each update, with no guarantee of accuracy.

Image menus could not reflect real‑time product availability, leading to out‑of‑stock orders.

Promotions could not be synchronized, reducing order efficiency and customer experience.

These issues motivated the creation of a rapid design and delivery system for brand designers.

Requirement Collection

Stakeholder demands included:

Department A: full menu with top‑new items, region‑specific updates.

Department B: simplified menu for new‑store activities.

Department C: promotion display and strike‑through pricing for mini‑program traffic.

Department D: real‑time product status and activity tags on the menu.

Conclusion: Fixed layouts cannot satisfy these varying needs.

Design Plan

Feature Preview

Designers are accustomed to Sketch or Photoshop. We built a drag‑and‑drop canvas that matches their workflow, allowing free‑form layout.

Implementation Principle

Technology Selection

For drag‑drop, zoom, and custom node configuration we considered Canvas and SVG. With moderate node counts (<100), SVG proved superior, leading us to choose Antv‑X6.

Canvas event handling is similar to raw JavaScript but lacks a proper event model, suffers from collision detection complexity, and cannot easily distinguish drag vs click.

SVG nodes are easier to customize; foreignObject enables embedding HTML/React components directly.

Custom Node Creation

Using foreignObject we can embed any HTML, for example:

<svg xmlns="http://www.w3.org/2000/svg">
  <foreignObject width="120" height="50">
    <body xmlns="http://www.w3.org/1999/xhtml">
      <p>Text.</p>
    </body>
  </foreignObject>
</svg>

Each dragged item becomes a foreignObject containing a React, Vue, or plain HTML component. We use a stateless functional React component where View = Fn(props) , driven by props from a side panel.

Data‑Driven View Binding

Our backend uses Ant Design forms. By listening to onValuesChange and shouldUpdate, we propagate form changes to node props, achieving data‑driven view updates. Global state is managed with useContext and useReducer only.

Page Information Protocol

The exported JSON describes each node’s position, size, type, and props. A shortened example:

{
  "cells": [
    {
      "position": {"x":0,"y":0},
      "size": {"width":1920,"height":1080},
      "view": "react-shape-view",
      "shape": "background-node",
      "data": {"backColor":"#fff","backType":"backColor"},
      "id": "wrapper-node",
      "zIndex": 0,
      "children": ["aeb782ee-..."]
    },
    {
      "position": {"x":610,"y":330},
      "size": {"width":430,"height":134},
      "view": "react-shape-view",
      "shape": "custom-react-node",
      "data": {"componentType":"list-product","type":"product"},
      "id": "aeb782ee-...",
      "parent": "wrapper-node"
    }
  ]
}

Other & Outlook

Language‑level performance can be improved with WebAssembly, allowing C++ code to run as binary in the browser, boosting load speed threefold.

Hardware‑level acceleration via WebGL enables GPU‑driven rendering for smoother graphics.

Electronic Menu Rendering

Pre‑questions

How to display the built template on the electronic screen?

How to isolate content per store?

How to ensure stable menu presentation?

Displaying Templates on Screens

The menu runs inside a third‑party Android app using a WebView. The native host provides store code, cache control, and version info. After the WebView loads, it calls a predefined JS entry point with these parameters to start the rendering workflow.

Node data includes position.x and position.y, which determine where each component is drawn, reproducing the exact design created in the builder.

Store‑Level Content Isolation

Different brands (e.g., Guming Tea, goottt) and store‑specific promotions require separate content. We introduce a “version” concept: a template is “finalized” into a hash‑named bundle containing both material JSON and component code. Stores bind to a specific hash, guaranteeing that even if the source template changes, the deployed version remains unchanged.

Ensuring Menu Stability

For stores with poor connectivity we package the menu as a PWA. A Service Worker intercepts requests, caching API responses in IndexedDB and static assets in CacheStorage, allowing offline or weak‑network operation without disrupting ordering.

Conclusion

As the number of stores grows, digitalization becomes critical. The project improves operational efficiency and customer experience by letting designers create menus without code, while the technical stack (React, Antv‑X6, SVG, PWA) ensures flexibility, scalability, and stability.

Technology should serve business needs, not the other way around. Low‑code solutions are valuable when non‑technical users need to build complex interactive interfaces, as demonstrated by this electronic menu system.

frontendlow-codeSVGPWA
Goodme Frontend Team
Written by

Goodme Frontend Team

Regularly sharing the team's insights and expertise in the frontend field

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.