diff --git a/aleksis/core/templates/core/index.html b/aleksis/core/templates/core/index.html
index 766c88278ca688381356c35e79b3424b7fb5ce75..ed75f0512706299dda87b12f2a4ab9f8a613a595 100644
--- a/aleksis/core/templates/core/index.html
+++ b/aleksis/core/templates/core/index.html
@@ -19,21 +19,6 @@
     </div>
   {% endif %}
 
-  {% for notification in unread_notifications %}
-    <figure class="alert primary scale-transition">
-        <i class="material-icons left iconify" data-icon="mdi:information-outline"></i>
-
-        <div class="right">
-          <a class="btn-flat waves-effect" href="{% url "notification_mark_read" notification.id %}">
-            <i class="material-icons center iconify" data-icon="mdi:close"></i>
-          </a>
-        </div>
-
-        <figcaption>{{ notification.title }}</figcaption>
-        <p>{{ notification.description|linebreaks }}</p>
-    </figure>
-  {% endfor %}
-
   {% include "core/partials/announcements.html" with announcements=announcements %}
 
   <div class="row" id="live_load">
diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py
index 54e854c8117843e8bd4f5139280bd4c46318a95c..c441d2ab8430d26faf539dbcbf4d69b5824196d5 100644
--- a/aleksis/core/urls.py
+++ b/aleksis/core/urls.py
@@ -96,6 +96,7 @@ urlpatterns = [
     path("group/<int:id_>/edit", views.edit_group, name="edit_group_by_id"),
     path("group/<int:id_>/delete", views.delete_group, name="delete_group_by_id"),
     path("", views.index, name="index"),
+    path("notifications/", views.NotificationsListView.as_view(), name="notifications"),
     path("dashboard/edit/", views.EditDashboardView.as_view(), name="edit_dashboard"),
     path("groups/group_type/create", views.edit_group_type, name="create_group_type"),
     path(
diff --git a/aleksis/core/views.py b/aleksis/core/views.py
index df8469036d2e4330f66e92455f4a21156c4d84ca..005f1b1d11947ae4e5a9dcf6ebc133148aaeca3d 100644
--- a/aleksis/core/views.py
+++ b/aleksis/core/views.py
@@ -248,6 +248,20 @@ def index(request: HttpRequest) -> HttpResponse:
     return render(request, "core/index.html", context)
 
 
+class NotificationsListView(PermissionRequiredMixin, ListView):
+    permission_required = "core.view_notifications_rule"
+    template_name = "core/notifications.html"
+
+    def get_queryset(self) -> QuerySet:
+        return self.request.user.person.notifications.filter(send_at__lte=timezone.now()).order_by(
+            "-created"
+        )
+
+    def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
+        self.get_queryset().filter(read=False).update(read=True)
+        return super().get_context_data(**kwargs)
+
+
 def about(request: HttpRequest) -> HttpResponse:
     """About page listing all apps."""
     context = {}