diff --git a/district/migrations/0040_districthomepage_menu.py b/district/migrations/0040_districthomepage_menu.py
new file mode 100644
index 0000000000000000000000000000000000000000..69a02b6e1308d561632a3c217308b937c935e099
--- /dev/null
+++ b/district/migrations/0040_districthomepage_menu.py
@@ -0,0 +1,90 @@
+# Generated by Django 3.2.11 on 2022-03-09 08:35
+
+import wagtail.core.blocks
+import wagtail.core.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("district", "0039_alter_districtcustompage_content"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="districthomepage",
+            name="menu",
+            field=wagtail.core.fields.StreamField(
+                [
+                    (
+                        "menu_item",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "title",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="Titulek", required=True
+                                    ),
+                                ),
+                                (
+                                    "page",
+                                    wagtail.core.blocks.PageChooserBlock(
+                                        label="Stránka", required=False
+                                    ),
+                                ),
+                                (
+                                    "link",
+                                    wagtail.core.blocks.URLBlock(
+                                        label="Odkaz", required=False
+                                    ),
+                                ),
+                            ]
+                        ),
+                    ),
+                    (
+                        "menu_parent",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "title",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="Titulek", required=True
+                                    ),
+                                ),
+                                (
+                                    "menu_items",
+                                    wagtail.core.blocks.ListBlock(
+                                        wagtail.core.blocks.StructBlock(
+                                            [
+                                                (
+                                                    "title",
+                                                    wagtail.core.blocks.CharBlock(
+                                                        label="Titulek", required=True
+                                                    ),
+                                                ),
+                                                (
+                                                    "page",
+                                                    wagtail.core.blocks.PageChooserBlock(
+                                                        label="Stránka", required=False
+                                                    ),
+                                                ),
+                                                (
+                                                    "link",
+                                                    wagtail.core.blocks.URLBlock(
+                                                        label="Odkaz", required=False
+                                                    ),
+                                                ),
+                                            ]
+                                        )
+                                    ),
+                                ),
+                            ]
+                        ),
+                    ),
+                ],
+                blank=True,
+                verbose_name="Menu",
+            ),
+        ),
+    ]
diff --git a/district/models.py b/district/models.py
index 2adb5672456723651f9cf3a39182efd2c4a4bd10..539bc68a47c17421494f5ebd76a29236f2f6eebc 100644
--- a/district/models.py
+++ b/district/models.py
@@ -11,8 +11,10 @@ from wagtail.admin.edit_handlers import (
     CommentPanel,
     FieldPanel,
     MultiFieldPanel,
+    ObjectList,
     PageChooserPanel,
     StreamFieldPanel,
+    TabbedInterface,
 )
 from wagtail.contrib.table_block.blocks import TableBlock
 from wagtail.core.blocks import RichTextBlock
@@ -22,13 +24,13 @@ from wagtail.images.edit_handlers import ImageChooserPanel
 from wagtailmetadata.models import MetadataPageMixin
 
 from calendar_utils.models import CalendarMixin
-from shared.models import ArticleMixin, SubpageMixin
+from shared.models import ArticleMixin, MenuMixin, SubpageMixin
 from uniweb.constants import RICH_TEXT_FEATURES
 
 from . import blocks
 
 
-class DistrictHomePage(MetadataPageMixin, CalendarMixin, Page):
+class DistrictHomePage(MenuMixin, MetadataPageMixin, CalendarMixin, Page):
     ### FIELDS
 
     subheader = StreamField(
@@ -161,6 +163,16 @@ class DistrictHomePage(MetadataPageMixin, CalendarMixin, Page):
         CommentPanel(),
     ]
 
+    ### EDIT HANDLERS
+    edit_handler = TabbedInterface(
+        [
+            ObjectList(content_panels, heading="Obsah"),
+            ObjectList(promote_panels, heading="Propagovat"),
+            ObjectList(settings_panels, heading="Nastavení"),
+            ObjectList(MenuMixin.menu_panels, heading="Menu"),
+        ]
+    )
+
     ### RELATIONS
 
     subpage_types = [
diff --git a/district/templates/district/base.html b/district/templates/district/base.html
index 65e5ae0040b4a87d01de29e75de20a77455ad3c4..9e827574dccf7a9344ca18e28e03873703ecfea8 100644
--- a/district/templates/district/base.html
+++ b/district/templates/district/base.html
@@ -79,64 +79,9 @@
 
           <div v-if="show || isLgScreenSize" class="navbar__main navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto">
             <ul class="navbar-menu text-white">
-              {% if page.root_page.articles_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.articles_page %}" class="navbar-menu__link">
-                    Aktuality
-                  </a>
-                </li>
-              {% endif %}
-              {% if page.root_page.people_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.people_page %}" class="navbar-menu__link">
-                    Lidé
-                  </a>
-                </li>
-              {% endif %}
-              {% if page.root_page.election_page and page.root_page.program_page %}
-                <li class="navbar-menu__item">
-                  <ui-navbar-subitem label="Volby">
-                    <ul class="navbar-menu__submenu">
-                      <li>
-                        <a href="{{ page.root_page.election_page.url }}" class="navbar-menu__link">
-                          {{ page.root_page.election_page }}
-                        </a>
-                      </li>
-                      <li>
-                        <a href="{{ page.root_page.program_page.url }}" class="navbar-menu__link">
-                          {{ page.root_page.program_page }}
-                        </a>
-                      </li>
-                    </ul>
-                  </ui-navbar-subitem>
-                </li>
-              {% elif page.root_page.program_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.program_page %}" class="navbar-menu__link">
-                    Program
-                  </a>
-                </li>
-              {% elif page.root_page.election_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.election_page %}" class="navbar-menu__link">
-                    Volby
-                  </a>
-                </li>
-              {% endif %}
-              {% if page.root_page.center_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.center_page %}" class="navbar-menu__link">
-                    Pirátské centrum
-                  </a>
-                </li>
-              {% endif %}
-              {% if page.root_page.contact_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.contact_page %}" class="navbar-menu__link">
-                    Kontakt
-                  </a>
-                </li>
-              {% endif %}
+                {% for block in page.root_page.menu %}
+                    {% include_block block %}
+                {% endfor %}
             </ul>
           </div>
 
diff --git a/district/wagtail_hooks.py b/district/wagtail_hooks.py
index 07ae0e6bb082420737315f50b17f2ba9533a51b8..ea3324d401ca66f0a0c822b8b60ade28a8417ab8 100644
--- a/district/wagtail_hooks.py
+++ b/district/wagtail_hooks.py
@@ -1,46 +1,46 @@
-import re
-
-from wagtail.core import hooks
-
-# FIXME hooks are loaded globally so it doesn't make sense to have it in this module
-
-
-@hooks.register("construct_page_chooser_queryset")
-def this_web_only(pages, request):
-    add_result = re.search(
-        "page/(.*)/", request.META.get("HTTP_REFERER")
-    )  # FIXME better regex
-    edit_result = re.search("pages/(.*)/edit", request.META.get("HTTP_REFERER"))
-
-    if add_result:
-        return handle_add_page_selection(pages=pages, add_result=add_result)
-
-    if edit_result:
-        return handle_edit_page_selection(pages=pages, edit_result=edit_result)
-
-    return pages
-
-
-def handle_add_page_selection(pages, add_result):
-    parent_page_id = add_result.group(1)
-    if parent_page_id == 1:  # pro novou homepage žádné podstránky nejsou
-        return pages.none()
-
-    parent_page = pages.model.objects.get(id=parent_page_id)
-    root_page = getattr(parent_page.specific, "root_page", None)
-    return get_only_root_page_descendants(pages=pages, root_page=root_page)
-
-
-def handle_edit_page_selection(pages, edit_result):
-    current_page_id = edit_result.group(1)
-    current_page = pages.model.objects.get(id=current_page_id)
-    root_page = getattr(current_page.specific, "root_page", None)
-    return get_only_root_page_descendants(pages=pages, root_page=root_page)
-
-
-def get_only_root_page_descendants(pages, root_page):
-    if not root_page:
-        return pages
-
-    web_pages_id_list = root_page.get_descendants().live().values_list("id", flat=True)
-    return pages.filter(id__in=web_pages_id_list)
+# import re
+#
+# from wagtail.core import hooks
+#
+# # FIXME hooks are loaded globally so it doesn't make sense to have it in this module
+#
+#
+# @hooks.register("construct_page_chooser_queryset")
+# def this_web_only(pages, request):
+#     add_result = re.search(
+#         "page/(.*)/", request.META.get("HTTP_REFERER")
+#     )  # FIXME better regex
+#     edit_result = re.search("pages/(.*)/edit", request.META.get("HTTP_REFERER"))
+#
+#     if add_result:
+#         return handle_add_page_selection(pages=pages, add_result=add_result)
+#
+#     if edit_result:
+#         return handle_edit_page_selection(pages=pages, edit_result=edit_result)
+#
+#     return pages
+#
+#
+# def handle_add_page_selection(pages, add_result):
+#     parent_page_id = add_result.group(1)
+#     if parent_page_id == 1:  # pro novou homepage žádné podstránky nejsou
+#         return pages.none()
+#
+#     parent_page = pages.model.objects.get(id=parent_page_id)
+#     root_page = getattr(parent_page.specific, "root_page", None)
+#     return get_only_root_page_descendants(pages=pages, root_page=root_page)
+#
+#
+# def handle_edit_page_selection(pages, edit_result):
+#     current_page_id = edit_result.group(1)
+#     current_page = pages.model.objects.get(id=current_page_id)
+#     root_page = getattr(current_page.specific, "root_page", None)
+#     return get_only_root_page_descendants(pages=pages, root_page=root_page)
+#
+#
+# def get_only_root_page_descendants(pages, root_page):
+#     if not root_page:
+#         return pages
+#
+#     web_pages_id_list = root_page.get_descendants().live().values_list("id", flat=True)
+#     return pages.filter(id__in=web_pages_id_list)
diff --git a/region/migrations/0015_regionhomepage_menu.py b/region/migrations/0015_regionhomepage_menu.py
new file mode 100644
index 0000000000000000000000000000000000000000..85a6406d856266eb5ac6cc03630a540ad23b2c81
--- /dev/null
+++ b/region/migrations/0015_regionhomepage_menu.py
@@ -0,0 +1,90 @@
+# Generated by Django 3.2.11 on 2022-03-09 08:24
+
+import wagtail.core.blocks
+import wagtail.core.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("region", "0014_regioncrossroadpage_regioncustompage"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="regionhomepage",
+            name="menu",
+            field=wagtail.core.fields.StreamField(
+                [
+                    (
+                        "menu_item",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "title",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="Titulek", required=True
+                                    ),
+                                ),
+                                (
+                                    "page",
+                                    wagtail.core.blocks.PageChooserBlock(
+                                        label="Stránka", required=False
+                                    ),
+                                ),
+                                (
+                                    "link",
+                                    wagtail.core.blocks.URLBlock(
+                                        label="Odkaz", required=False
+                                    ),
+                                ),
+                            ]
+                        ),
+                    ),
+                    (
+                        "menu_parent",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "title",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="Titulek", required=True
+                                    ),
+                                ),
+                                (
+                                    "menu_items",
+                                    wagtail.core.blocks.ListBlock(
+                                        wagtail.core.blocks.StructBlock(
+                                            [
+                                                (
+                                                    "title",
+                                                    wagtail.core.blocks.CharBlock(
+                                                        label="Titulek", required=True
+                                                    ),
+                                                ),
+                                                (
+                                                    "page",
+                                                    wagtail.core.blocks.PageChooserBlock(
+                                                        label="Stránka", required=False
+                                                    ),
+                                                ),
+                                                (
+                                                    "link",
+                                                    wagtail.core.blocks.URLBlock(
+                                                        label="Odkaz", required=False
+                                                    ),
+                                                ),
+                                            ]
+                                        )
+                                    ),
+                                ),
+                            ]
+                        ),
+                    ),
+                ],
+                blank=True,
+                verbose_name="Menu",
+            ),
+        ),
+    ]
diff --git a/region/models.py b/region/models.py
index decef6fb873c368c083bd7d8bf1e4cc33e4ee23e..b3d86dccb892f0368d109c8ba4e196c803ab0179 100644
--- a/region/models.py
+++ b/region/models.py
@@ -11,8 +11,10 @@ from wagtail.admin.edit_handlers import (
     CommentPanel,
     FieldPanel,
     MultiFieldPanel,
+    ObjectList,
     PageChooserPanel,
     StreamFieldPanel,
+    TabbedInterface,
 )
 from wagtail.contrib.table_block.blocks import TableBlock
 from wagtail.core.blocks import RichTextBlock
@@ -22,13 +24,13 @@ from wagtail.images.edit_handlers import ImageChooserPanel
 from wagtailmetadata.models import MetadataPageMixin
 
 from calendar_utils.models import CalendarMixin
-from shared.models import ArticleMixin, SubpageMixin
+from shared.models import ArticleMixin, MenuMixin, SubpageMixin
 from uniweb.constants import RICH_TEXT_FEATURES
 
 from . import blocks
 
 
-class RegionHomePage(MetadataPageMixin, CalendarMixin, Page):
+class RegionHomePage(MenuMixin, MetadataPageMixin, CalendarMixin, Page):
     ### FIELDS
 
     subheader = StreamField(
@@ -161,6 +163,16 @@ class RegionHomePage(MetadataPageMixin, CalendarMixin, Page):
         CommentPanel(),
     ]
 
+    ### EDIT HANDLERS
+    edit_handler = TabbedInterface(
+        [
+            ObjectList(content_panels, heading="Obsah"),
+            ObjectList(promote_panels, heading="Propagovat"),
+            ObjectList(settings_panels, heading="Nastavení"),
+            ObjectList(MenuMixin.menu_panels, heading="Menu"),
+        ]
+    )
+
     ### RELATIONS
 
     subpage_types = [
diff --git a/region/templates/region/base.html b/region/templates/region/base.html
index 65e5ae0040b4a87d01de29e75de20a77455ad3c4..9e827574dccf7a9344ca18e28e03873703ecfea8 100644
--- a/region/templates/region/base.html
+++ b/region/templates/region/base.html
@@ -79,64 +79,9 @@
 
           <div v-if="show || isLgScreenSize" class="navbar__main navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto">
             <ul class="navbar-menu text-white">
-              {% if page.root_page.articles_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.articles_page %}" class="navbar-menu__link">
-                    Aktuality
-                  </a>
-                </li>
-              {% endif %}
-              {% if page.root_page.people_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.people_page %}" class="navbar-menu__link">
-                    Lidé
-                  </a>
-                </li>
-              {% endif %}
-              {% if page.root_page.election_page and page.root_page.program_page %}
-                <li class="navbar-menu__item">
-                  <ui-navbar-subitem label="Volby">
-                    <ul class="navbar-menu__submenu">
-                      <li>
-                        <a href="{{ page.root_page.election_page.url }}" class="navbar-menu__link">
-                          {{ page.root_page.election_page }}
-                        </a>
-                      </li>
-                      <li>
-                        <a href="{{ page.root_page.program_page.url }}" class="navbar-menu__link">
-                          {{ page.root_page.program_page }}
-                        </a>
-                      </li>
-                    </ul>
-                  </ui-navbar-subitem>
-                </li>
-              {% elif page.root_page.program_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.program_page %}" class="navbar-menu__link">
-                    Program
-                  </a>
-                </li>
-              {% elif page.root_page.election_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.election_page %}" class="navbar-menu__link">
-                    Volby
-                  </a>
-                </li>
-              {% endif %}
-              {% if page.root_page.center_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.center_page %}" class="navbar-menu__link">
-                    Pirátské centrum
-                  </a>
-                </li>
-              {% endif %}
-              {% if page.root_page.contact_page %}
-                <li class="navbar-menu__item">
-                  <a href="{% pageurl page.root_page.contact_page %}" class="navbar-menu__link">
-                    Kontakt
-                  </a>
-                </li>
-              {% endif %}
+                {% for block in page.root_page.menu %}
+                    {% include_block block %}
+                {% endfor %}
             </ul>
           </div>
 
diff --git a/shared/blocks.py b/shared/blocks.py
new file mode 100644
index 0000000000000000000000000000000000000000..b0d28484ffa65460d0761e21033b258f0c0d814d
--- /dev/null
+++ b/shared/blocks.py
@@ -0,0 +1,38 @@
+from django.forms.utils import ErrorList
+from wagtail.core import blocks
+from wagtail.core.blocks.struct_block import StructBlockValidationError
+
+
+class MenuItemBlock(blocks.StructBlock):
+    title = blocks.CharBlock(label="Titulek", required=True)
+    page = blocks.PageChooserBlock(label="Stránka", required=False)
+    link = blocks.URLBlock(label="Odkaz", required=False)
+
+    class Meta:
+        label = "Položka v menu"
+        template = "styleguide/2.3.x/menu_item.html"
+
+    def clean(self, value):
+        errors = {}
+
+        if value["page"] and value["link"]:
+            errors["page"] = ErrorList(
+                ["Stránka nemůže být vybrána současně s odkazem."]
+            )
+            errors["link"] = ErrorList(
+                ["Odkaz nemůže být vybrán současně se stránkou."]
+            )
+        if errors:
+            raise StructBlockValidationError(errors)
+        return super().clean(value)
+
+
+class MenuParentBlock(blocks.StructBlock):
+    title = blocks.CharBlock(label="Titulek", required=True)
+    menu_items = blocks.ListBlock(
+        MenuItemBlock(),
+    )
+
+    class Meta:
+        label = "Podmenu"
+        template = "styleguide/2.3.x/menu_parent.html"
diff --git a/shared/models.py b/shared/models.py
index 7fec651d1969c2955066403ac7f82eb5011a976f..e399811a875c7bdcc94c0e602a70c0230f8baa5a 100644
--- a/shared/models.py
+++ b/shared/models.py
@@ -1,13 +1,12 @@
-import requests
-from django.core.cache import cache
-from django.core.validators import MaxValueValidator, MinValueValidator
 from django.db import models
 from django.utils import timezone
-from wagtail.admin.edit_handlers import FieldPanel
-from wagtail.core.fields import RichTextField
+from wagtail.admin.edit_handlers import FieldPanel, MultiFieldPanel, StreamFieldPanel
+from wagtail.core.fields import RichTextField, StreamField
 from wagtail.core.models import Page
 from wagtail.images.edit_handlers import ImageChooserPanel
 
+from shared.blocks import MenuItemBlock, MenuParentBlock
+
 
 class SubpageMixin:
     """Must be used in class definition before MetadataPageMixin!"""
@@ -82,3 +81,23 @@ class ArticleMixin(models.Model):
     def tag_filter_page(self):
         """Page used for filtering by tags in url like `?tag=foo`."""
         return self.get_parent()
+
+
+class MenuMixin(Page):
+    menu = StreamField(
+        [("menu_item", MenuItemBlock()), ("menu_parent", MenuParentBlock())],
+        verbose_name="Menu",
+        blank=True,
+    )
+
+    menu_panels = [
+        MultiFieldPanel(
+            [
+                StreamFieldPanel("menu"),
+            ],
+            heading="Menu Options",
+        ),
+    ]
+
+    class Meta:
+        abstract = True
diff --git a/shared/templates/styleguide/2.3.x/menu_item.html b/shared/templates/styleguide/2.3.x/menu_item.html
new file mode 100644
index 0000000000000000000000000000000000000000..9c0b7fda56a961a62fc39197c37a158ee90bf239
--- /dev/null
+++ b/shared/templates/styleguide/2.3.x/menu_item.html
@@ -0,0 +1,6 @@
+<li class="navbar-menu__item">
+    {% firstof self.page.url self.link as target %}
+    <a href="{{ target }}" class="navbar-menu__link">
+        {{ self.title }}
+    </a>
+</li>
diff --git a/shared/templates/styleguide/2.3.x/menu_parent.html b/shared/templates/styleguide/2.3.x/menu_parent.html
new file mode 100644
index 0000000000000000000000000000000000000000..26d600ff2cb28cf9ad121d6329bc13e29de815f9
--- /dev/null
+++ b/shared/templates/styleguide/2.3.x/menu_parent.html
@@ -0,0 +1,14 @@
+<li class="navbar-menu__item">
+    <ui-navbar-subitem label="{{ self.title }}">
+        <ul class="navbar-menu__submenu">
+            {% for nested_item in self.menu_items %}
+                <li>
+                    {% firstof nested_item.page.url nested_item.link as target %}
+                    <a href="{{ target }}" class="navbar-menu__link">
+                        {{ nested_item.title }}
+                    </a>
+                </li>
+            {% endfor %}
+        </ul>
+    </ui-navbar-subitem>
+</li>