Appearance
Display Groups
Overview
Display Groups are the visual organizational units within a menu that group items into sections as they appear to customers. While categories serve as a backend classification system, display groups control the actual layout and presentation of items on customer-facing channels (kiosk, online ordering, QR ordering). Each display group belongs to a menu, contains ordered item references, and has per-channel visibility controls.
Display groups are stored in the menus MongoDB collection with model type display_group and support soft deletion. They hold multilingual details, a content image reference, channel visibility settings, external IDs for third-party integrations, and an ordered array of item/variant group references.
Purpose
This page lets you create, edit, and manage display groups that organize menu items into visual sections on kiosks, online ordering, and other customer-facing channels, controlling exactly which items appear together and in what order.
Key Concepts
- Display Group: A named container of menu items that defines a visual section on the customer-facing menu. Each display group has multilingual
details(with adefaultkey containingnameanddescription), acontent_idreferencing an optional image, an ordereditem_idsarray,menu_idsfor menu associations,visibilityfor channel control, alocation_id, apos_namefor POS integration, andexternal_ids/external_datafor third-party systems. Stored in themenuscollection withSOFT_DELETE = true. - Visibility: An array of
ChannelOptionsenum values that controls where the display group appears. Valid channels are:Kiosk,POS,Online Ordering,Table Qr Ordering,Uber Eats,Takeaway, andShopify. A display group is only rendered on channels listed in its visibility array. Items within the group are further filtered by their own platform settings. - Item Ordering: Items within a display group are displayed in the order they appear in the
item_idsarray. This ordering is preserved when rendering menus on kiosk (kioskSerialize) and online ordering (onlineOrderingSerialize). The array can contain both regular item IDs and variant group IDs, which are resolved at render time. - Menu Association: Display groups are linked to menus via a bidirectional relationship. The display group stores
menu_idsand the menu storesdisplay_group_ids. When a display group is created, thesyncRelationsmethod adds its ID to the specified menu'sdisplay_group_idsarray and syncs the menu reference on the display group. - Label Consistency: All items within a single display group must share the same label (e.g., all "Regular" items or all items with a specific external integration label). The
validateItemsmethod checks every item's label against the first item's label and throws an exception with a descriptive message naming the group if labels are mixed.
Route
- Backoffice Route:
/menus(Menu Builder),/menus/display-groups(dedicated page) - Backend Controller:
app/Http/Controllers/Api/DisplayGroupController.php - Orchestrator:
app/Services/Orchestrators/BackOffice/DisplayGroupOrchestrator.php - Service:
app/Services/BackOffice/DisplayGroupService.php - Model:
app/RawModels/DisplayGroup.php - Repository:
app/Repositories/DisplayGroupRepository.php - Request Validators:
app/Http/Requests/BackOffice/DisplayGroup/StoreDisplayGroupRequest.php,app/Http/Requests/BackOffice/DisplayGroup/UpdateDisplayGroupRequest.php - Resources:
app/Http/Resources/BackOffice/Menu/DisplayGroupResource.php,app/Http/Resources/BackOffice/Menu/ShowDisplayGroupResource.php - Vue Components:
src/views/menus/dialogs/DisplayGroupDialog.vue,src/views/menus/components/MenuDisplayGroups.vue,src/components/dialogs/DisplayGroupListDialog.vue - Store Module:
src/store/modules/displayGroup.ts
Actions
List Display Groups
Retrieve all display groups for the current vendor, filtered by location. The service first fetches all menus for the vendor, then queries display groups where menu_ids contains any of those menu IDs. Additional filter parameters from the LocationScopedRequest are applied. Returns a collection of DisplayGroupResource objects.
- Endpoint:
GET /api/back-office/display-groups?location_id={locationId} - Response: JSON array of display group resources with
id,details,content,visibility, and other fields
Create Display Group
Create a new display group with the required fields. The flow:
- Validates the request via
StoreDisplayGroupRequest - Checks name uniqueness within the target menu using
isFieldValueUsedon theDisplayGroupRepository - Wraps the name/description in a
details.defaultstructure for multi-language support - If an image is provided, uploads it via
handleMediaUploadunder thedisplay-groupsdirectory and stores the resultingcontent_id - Saves the display group document via the repository
- Calls
syncRelationsto link items and add the display group to the specified menu - Dispatches a
DisplayGroupCreatedguided setup event with the vendor database, location ID, service path (self-service), and setup category (build_menu)
- Endpoint:
POST /api/back-office/display-groups - Response: JSON
DisplayGroupResourceof the created display group
View Display Group Details
Retrieve the full details of a specific display group by ID, including its items, visibility settings, menu associations, and content image. Returns a ShowDisplayGroupResource with expanded item data.
- Endpoint:
GET /api/back-office/display-groups/{id} - Response: JSON
ShowDisplayGroupResource
Update Display Group
Modify a display group's name, description, image, POS name, or visibility settings. The flow:
- Validates the request via
UpdateDisplayGroupRequest - Retrieves the existing display group
- Checks name uniqueness against other display groups in the same menu (excluding the current one by ID)
- Merges new details into the existing details structure under the
defaultkey - If a new image is provided, uploads it and updates
content_id; otherwise setscontent_idto null - Saves the updated document
- Dispatches a
ReloadMenuevent for the affected location to refresh cached menus
- Endpoint:
PUT /api/back-office/display-groups/{id} - Response: JSON
DisplayGroupResourceof the updated display group
Delete Display Group
Permanently remove a display group (soft delete). Dispatches a ReloadMenu event to refresh cached menus for the affected location. The deleteByMenuId method allows bulk deletion of all display groups associated with a given menu ID, dispatching ReloadMenu events for each affected location.
- Endpoint:
DELETE /api/back-office/display-groups/{id} - Response: Success response
Fields
| Field | ID | Type | Required | Validation |
|---|---|---|---|---|
| Name | details.name | String | Yes | required|string -- must be unique within the same menu |
| Description | details.description | String | No | nullable|string |
| POS Name | pos_name | String | No | nullable|string -- unique within connection via custom rule |
| Image Source | image.source | Enum | No | One of: direct_upload, existing, url, photo_studio, external, square, suggestions_api |
| Image File | image.file | File | No | nullable|max:5000 (5 MB maximum) |
| Visibility | visibility | Array | Yes | required|array -- at least one channel required |
| Visibility Channel | visibility.* | Enum | Yes | One of: Kiosk, POS, Online Ordering, Table Qr Ordering, Uber Eats, Takeaway, Shopify |
| Location ID | location_id | String | Yes | required|string|exists:locations,_id |
| Menu ID | menu_id | String | Yes (create) | required|string -- must exist in menus collection; not required on update |
Business Rules
- Display group names must be unique within the same menu. The
isFieldValueUsedmethod queries theDisplayGroupRepositorywith the name value and an optionalmoreFilterofmenu_idsto scope the uniqueness check. A 400 error with "Name should be unique" is returned for duplicates. - All items within a display group must have the same label. The
validateItemsmethod iterates through all item IDs, retrieves each item (or variant group), checks its label, and throws an exception with "Group {name}: All items must have the same label" if any mismatch is found. - Display groups use soft delete (
SOFT_DELETE = true), meaning deleted records are marked with a deletion timestamp rather than physically removed from themenusMongoDB collection. - When a display group is created or updated with an image, the image is uploaded to Cloudflare Images under the
display-groupsdirectory path via theContentTrait.handleMediaUploadmethod. If no image is provided on update,content_idis set to null. - Deleting a menu automatically deletes all associated display groups via the
deleteByMenuIdmethod, which iterates through all display groups with the matchingmenu_idsfilter and callsdeleteon each, dispatchingReloadMenuevents per affected location. - The
syncRelationsmethod handles both item assignment (syncingitem_idson the display group) and menu linkage (adding the display group ID to the menu'sdisplay_group_idsarray). It also callssyncMenuon the repository to update the menu-to-display-group mapping. - Display group content images use the
kioskgroupvariant by default when resolving URLs viagetContentUrl, ensuring optimized image sizes for kiosk display. - Items within a display group are further filtered at render time by status (
Activeonly) and platform visibility, so even if an item is in the group'sitem_ids, it will not appear on a channel if it is inactive or lacks the channel in its platforms list.
Customer Impact
- Kiosk: Display groups define the main navigation sections on the kiosk screen. Customers browse items by tapping on display group tabs or scrolling through sections. Only display groups with
Kioskin their visibility array appear. Items within each group are rendered initem_idsorder, filtered toActivestatus andKioskplatform. - Online Ordering: Display groups structure the online menu into browsable sections. Each display group renders as a section header with its multilingual name, optional description, and image (via
getContentUrl), followed by the items it contains. Only groups withOnline Orderingvisibility appear. - QR Ordering: Display groups with
Table Qr Orderingvisibility appear on the table QR ordering menu, organizing items for dine-in customers scanning a QR code at their table. - Third-Party Integrations: Display groups with
Uber Eats,Takeaway, orShopifyvisibility are synced to those external platforms, withexternal_idsandexternal_datatracking the mapping.
FAQs
What is the difference between a display group and a category?
Categories are a backend classification system for items (used for tax rates, reporting, and organization). Display groups control the visual layout of items on customer-facing menus. An item belongs to one category but can appear in multiple display groups across different menus.
Can an item appear in multiple display groups?
Yes. An item can be added to multiple display groups, even within the same menu. The item will appear in each section where it is included, and its order within each group is independent.
How do I control the order of items within a display group?
Items are displayed in the order they appear in the item_ids array. You can reorder items by dragging them in the Menu Builder interface, which updates the array order. The backend preserves this order when serializing for kiosk and online ordering.
Can I assign a display group to multiple menus?
A display group tracks menu_ids as an array and can technically be associated with multiple menus, but the standard creation flow assigns it to a single menu via the required menu_id field. The bidirectional relationship is managed through both the display group's menu_ids and the menu's display_group_ids.
What happens to items when I delete a display group?
Deleting a display group does not delete the items within it. The items remain in the system and can be assigned to other display groups. Only the grouping container is removed.
What are the supported image sources for display groups?
Display group images can come from: direct_upload (file upload), existing (existing content), url (external URL), photo_studio (Photo Studio library), external (external import), square (Square integration), or suggestions_api (AI suggestions).
How does soft delete work for display groups?
Display groups use soft delete (SOFT_DELETE = true), meaning they are marked with a deletion timestamp rather than physically removed from the MongoDB menus collection. This allows for potential recovery and ensures referential integrity with other documents that may reference the display group.
Can I translate display group names?
Yes. Display group names and descriptions are stored in a multilingual details structure. The default key holds the primary language text, and additional language keys can be added through the translations system. The TranslationEntities enum includes a reference for display groups.
Troubleshooting
Display group does not appear on the kiosk or online ordering
Check the display group's visibility array -- it must include the specific channel (Kiosk, Online Ordering, etc.) to appear on that platform. Also verify the parent menu is assigned and active for the relevant location. Check that items within the group are set to Active status and have the matching platform in their platforms list.
"Name should be unique" error when creating a display group
Another display group with the same name already exists within the target menu. Use a different name or rename the existing display group first. The uniqueness check is scoped to the menu, so the same name can be used across different menus.
"All items must have the same label" error
This occurs when items with different labels (e.g., mixing "Regular" items with externally imported items from a different integration) are assigned to the same display group. Ensure all items in the group share the same label classification. The error message includes the display group name for identification.
Display group image is not showing
Verify the image was uploaded successfully by checking the content_id field on the display group document. Ensure Cloudflare Images is configured and the referenced Content document exists with valid cloudflare_image_id. The image file must be under 5 MB per the validation rule (max:5000).
Changes to display group are not reflected on kiosk/ordering
Display group updates trigger a ReloadMenu event, but cached menus may take a moment to refresh. Check that the menu cache has been cleared for the affected location. If the issue persists, try making a minor edit to the parent menu to force a complete cache refresh.
Items appear in wrong order in the display group
Item order is determined by the item_ids array sequence. If items appear in an unexpected order, check the array contents in the database. In the Menu Builder, you can drag items to reorder them, which updates the item_ids array through the syncRelations method.
Technical Details
Serialization for Customer Channels
Display groups are serialized differently depending on the target channel:
- Online Ordering (
onlineOrderingSerialize): Returnsid,details(multilingual),image_url, anditems. Items are filtered byvisibilitymatching the online ordering channel andstatus: Active. Each item is serialized using itsonlineOrderingSerializemethod with the location context. - Kiosk (
kioskSerialize): Returnsid,details,image_url, anditems. Items are filtered byplatforms: Kioskandstatus: Active. Each item is serialized using itskioskSerializemethod. The image URL uses thekioskgroupvariant from Cloudflare Images.
Variant Group Handling
The item_ids array can contain both regular item IDs and variant group IDs. The getItems method resolves both types by querying both the ItemRepository and VariantGroupRepository. When withVariantGroup is true, variant groups are returned as-is; when false, variant groups are expanded into their individual items. In production, variant groups are always expanded for kiosk rendering (as the kiosk app does not yet fully support variant groups).
External Integration Data
Display groups carry external_ids and external_data fields for third-party platform synchronization. These fields store mapping information for platforms like Uber Eats, Deliveroo, Takeaway, Shopify, and Square. The toSnapshot method includes these fields when creating a point-in-time snapshot for offers, but only for display groups with non-regular labels.
Multi-Language Support
Display group details are stored in a nested structure with a default key containing the primary language name and description. When a display group is updated, the new details are merged under the default key while preserving other language entries. The translation system references display groups via the TranslationEntities enum.
Import and Sync Mechanisms
Display groups can be imported from external sources through two mechanisms:
- Kassanet Import: The
ImportKassanetDisplayGroupsJobimports display groups from the Kassanet POS system, creating display group documents with external IDs and data mapping. - Third-Party Integrations: The
AbstractThirdPartyIntegrationServiceand its implementations (UberEatsService,DeliverooService,ShopifyIntegrationService,SquareUpService) handle bidirectional syncing of display groups with external platforms, mapping between Upvendo's display group structure and each platform's category/section format.
Assistant Guidance
When users ask about display groups, clarify the distinction from categories -- display groups control visual layout on customer channels, while categories are for backend organization and tax rate assignment. Guide users to create display groups within the Menu Builder interface by selecting a menu first. If users want items to appear on specific channels only, explain the visibility array and how to configure it per channel. When troubleshooting missing items on kiosk or online ordering, check three things: (1) the display group's visibility array includes the target channel, (2) the individual item's platform settings include the target channel, and (3) the item's status is Active. For multi-language setups, explain that display group names and descriptions are stored under the details.default key and can have translations added per language.
Relations
Depends On
- Menus: Display groups must belong to at least one menu. The menu must exist before a display group can be created within it, enforced by the
menu_idvalidation rule. - Items: Display groups reference items (and variant groups) via
item_ids. Items must exist before being added to a display group. - Locations: Display groups are scoped to a location via
location_id, which must reference a valid location document. - Content Service: Images for display groups are stored as Content entities via Cloudflare Images, referenced by
content_id. - Variant Groups: Display groups can contain variant group IDs in their
item_idsarray, which are resolved to individual items at render time.
Affects
- Kiosk App: Display groups define the navigation structure and item grouping on kiosk screens via
kioskSerialize. - Online Ordering: Display groups structure the online menu layout for customers via
onlineOrderingSerialize. - QR Ordering: Display groups organize the table QR ordering menu for dine-in customers.
- Menu Cache: Creating, updating, or deleting display groups triggers
ReloadMenuevents to refresh cached menus for the affected location. - Guided Setup: Creating a display group dispatches a
DisplayGroupCreatedevent to update guided setup progress for thebuild_menutask. - Third-Party Integrations: Display groups with external platform visibility are synced to Uber Eats, Takeaway, and Shopify via their respective integration services.
- Translations: Display group names and descriptions can be translated via the translation system, with entries keyed by
TranslationEntitiesenum.