Menus: Multilingual Navigation with Nested Submenus

AliothPress uses one menu tree for all languages. You build the menu once, and each visitor sees it resolved into their language automatically: correct slugs, translated labels, and no links to unavailable content. The header menu supports up to 3 levels (top item → child → grandchild). The footer menu is intentionally flat. Menu items can be pages, posts, or custom links (including anchors and file URLs), each with per-language behavior. Drafts and missing translations are hidden per language, never site-wide.

How multilingual resolution works

You add a page or post to the menu by picking any of its language versions. The engine links the menu item to the content's translation group, not to one language.

For each visitor, every item is resolved independently:

Situation What the visitor sees
Translation exists and is published The item, with that language's own slug and title
That language's version is a draft Item hidden in that language only
No translation in that language Item hidden in that language only
A parent item is hidden Its whole branch (children and grandchildren) is hidden
The language is deactivated in Settings Its pages return 404. Menus in other languages are unaffected

Two useful consequences:

  • It doesn't matter which language you clicked in the builder. Adding the German version of a page produces the same menu item as adding the English one. Adding both is safe: duplicates within the same level are merged automatically. The menu stores language-neutral references instead of language-specific pages.
  • Un-drafting or re-activating a language restores its menu items instantly. Nothing needs to be rebuilt.

Nesting: three levels

The header menu supports three tiers:

Top item

├── Child

│   └── Grandchild

└── Child

In the builder:

  • Drag an item right (≥ 30 px) over another item to nest it as that item's child. Works on top items (creates a child) and on children (creates a grandchild).
  • Drag left to pop an item one level up.
  • The ⤵ / ⤴ buttons do the same without dragging. The ⤵ button hides itself when nesting would exceed three levels.
  • A branch always moves as a whole. Dragging, nesting, un-nesting, or removing a parent takes its entire subtree along.
  • A fourth level cannot be created: not by drag, not by buttons, not by hand-crafted requests. The server enforces the same limit independently.

On the public site:

  • Desktop: children appear in a dropdown. Grandchildren open in a side flyout (with keyboard support and ARIA attributes). Near the right screen edge the flyout opens to the left automatically.
  • Mobile: the sidebar renders nested accordions: tap a parent to unfold children, tap a child with items to unfold grandchildren. No hover required.

The three-level cap is built into the engine. It is designed so that future official modules, such as a shop with deep category trees, can extend it without changes to menu logic.

Custom links, anchors, and files

The Links tab adds items that are not pages or posts:

  • Per-language URLs and labels. Example: /docs#getting-started labeled Docs for English, /dokumentation#erste-schritte labeled Doku for German. In a language with no URL set, the item is hidden.
  • Anchor links stay language-aware: the language switcher maps /docs#getting-started to its German counterpart, at any nesting depth.
  • File URLs (e.g. /press-kit.pdf) work as menu items, including as grandchildren, and support target="_blank".
  • Only https://, http://, mailto:, tel:, and relative / URLs are accepted. javascript:, data:, and protocol-relative URLs are rejected by the builder and, independently, by the server.

What happens when content changes

Action Menu behavior
Set one language version to draft Item hidden in that language. Other languages unaffected
Delete one language version Item re-anchors to a surviving published translation. Its submenu is preserved
Delete the last version of the content The menu item and its entire branch are removed
Deactivate a language Menus in remaining languages continue to work. Nothing is deleted
Reactivate the language Items reappear in it with their original slugs and labels

The admin builder stays functional in every one of these states: inconsistent language coverage across menu items is a supported, tested configuration, not an error.

Frequently Asked Questions

How many menu levels does AliothPress support?
Three in the header menu: top items, children, and grandchildren. The footer menu is flat by design.
Do I have to build a separate menu for each language?
No. There is one menu tree. Each language version of the site resolves it automatically using translation groups.
What if a page in the menu has no translation for some language?
The item is simply hidden in that language. If the page is a parent, its children and grandchildren are hidden with it in that language.
Do drafts ever appear in public menus?
No. A draft hides its language's menu entry, and the resolver never links to unpublished content, even when the draft is the exact version the item was anchored to.
Can a submenu item be a custom link or a file?
Yes. Custom links, including anchors and file URLs, can be children or grandchildren, with per-language URLs and labels.
What happens to submenu items if I delete their parent page?
If another published translation of the parent exists, the menu item re-anchors to it and the submenu is kept. If it was the last translation, the item and its whole branch are removed from the menu.
Why can't I drag an item deeper than three levels?
The depth cap is enforced in the builder (the nest control disables itself) and again on the server, which also protects against malformed requests. Deeper structures would be clamped, never silently lost.
Does the mobile menu support three levels?
Yes: as nested accordions in the sidebar, which need taps only, no hover. Desktop uses a dropdown plus a side flyout with keyboard and screen-reader support.