diff --git a/district/blocks.py b/district/blocks.py
index 436cc2f07fdd283570a02220e47471e3e47aff87..2e0bff8b7cebb0d618c604c8fadb5868aa140c50 100644
--- a/district/blocks.py
+++ b/district/blocks.py
@@ -1,5 +1,6 @@
 from django.db import models
 from django.forms.utils import ErrorList
+from wagtail.blocks.struct_block import StructBlockValidationError
 from wagtail.core import blocks
 from wagtail.core.blocks import (
     BooleanBlock,
@@ -12,7 +13,6 @@ from wagtail.core.blocks import (
     TextBlock,
     URLBlock,
 )
-from wagtail.core.blocks.struct_block import StructBlockValidationError
 from wagtail.images.blocks import ImageChooserBlock
 
 from shared.blocks import ButtonBlock, ProgramItemBlock
diff --git a/majak/settings/base.py b/majak/settings/base.py
index 86731f5ae22e3419a308e29b94af90617784a6ea..cccc86814e3ae279948d9049d17f602275722d46 100644
--- a/majak/settings/base.py
+++ b/majak/settings/base.py
@@ -253,6 +253,7 @@ WAGTAILEMBEDS_RESPONSIVE_HTML = True
 # Base URL to use when referring to full URLs within the Wagtail admin backend -
 # e.g. in notification emails. Don't include '/admin' or a trailing slash
 BASE_URL = env.str("BASE_URL", default="https://majak.pirati.cz")
+WAGTAILADMIN_BASE_URL = BASE_URL
 
 # CUSTOM SETTINGS
 # ------------------------------------------------------------------------------
diff --git a/maps_utils/blocks.py b/maps_utils/blocks.py
index 161cb8f601e0ae862a174cd36c580b701ab504a8..e73ee9256d818ed9c6d58c3a8384ebd5b9c40de9 100644
--- a/maps_utils/blocks.py
+++ b/maps_utils/blocks.py
@@ -4,8 +4,8 @@ from uuid import uuid4
 
 from django.forms.utils import ErrorList
 from django.utils.text import slugify
+from wagtail.blocks.struct_block import StructBlockValidationError
 from wagtail.core import blocks
-from wagtail.core.blocks.struct_block import StructBlockValidationError
 from wagtail.images.blocks import ImageChooserBlock
 
 from .const import (
diff --git a/requirements/base.txt b/requirements/base.txt
index 9689730fd97fbf3919ccde433c63c6e293a6fd0c..98167abb4f68f3b439a3f7d67e55ad32f109ef0f 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -8,8 +8,6 @@ amqp==5.1.1
     # via kombu
 anyascii==0.3.1
     # via wagtail
-appnope==0.1.3
-    # via ipython
 arrow==0.14.7
     # via
     #   -r base.in
@@ -73,6 +71,8 @@ django==4.0.4
     # via
     #   django-extensions
     #   django-filter
+    #   django-modelcluster
+    #   django-permissionedforms
     #   django-ranged-response
     #   django-redis
     #   django-settings-export
@@ -88,7 +88,9 @@ django-extensions==3.1.5
     # via -r base.in
 django-filter==21.1
     # via wagtail
-django-modelcluster==5.3
+django-modelcluster==6.0
+    # via wagtail
+django-permissionedforms==0.1
     # via wagtail
 django-ranged-response==0.2.0
     # via django-simple-captcha
@@ -257,11 +259,11 @@ vine==5.0.0
     #   amqp
     #   celery
     #   kombu
-wagtail==2.16.2
+wagtail==3.0.1
     # via
     #   -r base.in
     #   wagtail-metadata
-wagtail-metadata==3.5.0
+wagtail-metadata==4.0.0
     # via -r base.in
 wcwidth==0.2.5
     # via prompt-toolkit
diff --git a/shared/blocks.py b/shared/blocks.py
index ecc6b3b3b7c23e077938d59088b907e8cdab4e0e..b479fd935a38426e103f80b72128291562b1f9ee 100644
--- a/shared/blocks.py
+++ b/shared/blocks.py
@@ -4,9 +4,9 @@ import urllib
 
 from django.core.files.images import ImageFile
 from django.forms.utils import ErrorList
+from wagtail.blocks.struct_block import StructBlockValidationError
 from wagtail.contrib.table_block.blocks import TableBlock
 from wagtail.core import blocks
-from wagtail.core.blocks.struct_block import StructBlockValidationError
 from wagtail.core.models import Collection
 from wagtail.images.blocks import ImageChooserBlock
 from wagtail.images.models import Image
diff --git a/tuning/wagtail_hooks.py b/tuning/wagtail_hooks.py
index 07d7a8423ea74f77ab0f9864d90dbe3d3a607fb3..619274a086fe3122c81a937f349e2743748f8615 100644
--- a/tuning/wagtail_hooks.py
+++ b/tuning/wagtail_hooks.py
@@ -4,10 +4,11 @@ from django.conf import settings
 from django.contrib.postgres.lookups import Unaccent
 from django.db.models.functions import Lower
 from django.utils.safestring import mark_safe
+from wagtail.admin.ui.components import Component
 from wagtail.core import hooks
 
 
-class HelpPanel:
+class WelcomePanel(Component):
     order = 1000
 
     def render_html(self, parent_context):
@@ -24,7 +25,7 @@ class HelpPanel:
 
 @hooks.register("construct_homepage_panels")
 def add_another_welcome_panel(request, panels):
-    panels.append(HelpPanel())
+    panels.append(WelcomePanel())
 
 
 @hooks.register("construct_explorer_page_queryset")