diff --git a/Gemfile.lock b/Gemfile.lock
index 4cfbe89dcbd26526510676bc5fc525af40aeb966..ed5540337363726b073708bb49a74692d7375a94 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -79,7 +79,7 @@ GEM
     autoprefixer-rails (10.3.3.0)
       execjs (~> 2)
     aws-eventstream (1.2.0)
-    aws-partitions (1.517.0)
+    aws-partitions (1.518.0)
     aws-sdk-core (3.121.3)
       aws-eventstream (~> 1, >= 1.0.2)
       aws-partitions (~> 1, >= 1.239.0)
diff --git a/app/assets/javascripts/admin/treeview.js b/app/assets/javascripts/admin/treeview.js
index e2889ea78f778262a0f9ccf1ab52e871495151ef..484d9a2509ab7f631af6d7597eafd099bdfc4014 100644
--- a/app/assets/javascripts/admin/treeview.js
+++ b/app/assets/javascripts/admin/treeview.js
@@ -13,7 +13,7 @@ window.osuny.treeView = {
         var nestedSortables,
             i;
 
-        nestedSortables = [].slice.call(document.querySelectorAll('.js-treeview-sortable'));
+        nestedSortables = [].slice.call(document.querySelectorAll('.js-treeview-sortable-container'));
         for (i = 0; i < nestedSortables.length; i += 1) {
             new Sortable(nestedSortables[i], {
                 group: 'nested',
@@ -21,16 +21,22 @@ window.osuny.treeView = {
                 fallbackOnBody: true,
                 swapThreshold: 0.65,
                 onEnd: function (evt) {
-                    var from = evt.from,
-                        to = evt.to,
+                    var to = evt.to,
                         ids = [],
-                        parentId;
+                        parentId,
+                        url;
                     $('> .js-treeview-element', to).each(function () {
                         ids.push($(this).attr('data-id'));
                     });
+                    // as the "to" can be the root object where the data-sort-url is set we use "closest" and not "parents"
+                    url = $(to).closest('.js-treeview-sortable')
+                        .attr('data-sort-url');
                     parentId = to.dataset.id;
-                    console.log(parentId, ids, from === to);
-                    // TODO
+
+                    $.post(url, {
+                        parentId: parentId,
+                        ids: ids
+                    });
                 }
             });
         }
diff --git a/app/controllers/admin/communication/website/pages_controller.rb b/app/controllers/admin/communication/website/pages_controller.rb
index 73d263dcad833ca5184fbfaccd3ba8fa8a74c3f1..89abd5760d54801511f0052c5bb84110f90cd0b9 100644
--- a/app/controllers/admin/communication/website/pages_controller.rb
+++ b/app/controllers/admin/communication/website/pages_controller.rb
@@ -6,6 +6,18 @@ class Admin::Communication::Website::PagesController < Admin::Communication::Web
     breadcrumb
   end
 
+  def reorder
+    parent_id = params['parentId'].blank? ? nil : params['parentId']
+    ids = params['ids']
+    ids.each.with_index do |id, index|
+      page = @website.pages.find(id)
+      page.update(
+        parent_id: parent_id,
+        position: index + 1
+      )
+    end
+  end
+
   def children
     return unless request.xhr?
     @page = @website.pages.find(params[:id])
diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb
index ad4e52d14a72e60b17fc268a1a6fa6adb3af4a9f..8045593859adbfafe5e2bad868fc5f91f3940979 100644
--- a/app/models/communication/website/page.rb
+++ b/app/models/communication/website/page.rb
@@ -53,6 +53,7 @@ class Communication::Website::Page < ApplicationRecord
   validates :title, presence: true
 
   before_save :make_path
+  after_save :update_children_paths if :saved_change_to_path?
 
   scope :ordered, -> { order(:position) }
   scope :recent, -> { order(updated_at: :desc).limit(5) }
@@ -72,6 +73,10 @@ class Communication::Website::Page < ApplicationRecord
     self.path = "#{parent&.path}/#{slug}".gsub('//', '/')
   end
 
+  def update_children_paths
+    children.each(&:save)
+  end
+
   def github_path
     "_pages/#{github_file}"
   end
diff --git a/app/views/admin/communication/website/pages/_treebranch.html.erb b/app/views/admin/communication/website/pages/_treebranch.html.erb
index 599e099c65fe92e510febc907b45b64dd60340b9..82f5ece37df4ca64c3173d7a7059681e4d58d9ba 100644
--- a/app/views/admin/communication/website/pages/_treebranch.html.erb
+++ b/app/views/admin/communication/website/pages/_treebranch.html.erb
@@ -12,7 +12,7 @@
       <span class="move_btn py-2 ps-2"><i class="fas fa-sort"></i></span>
     </div>
     <% if page.has_children? %>
-      <ul class="list-unstyled treeview__children js-treeview-children js-treeview-sortable ms-4" data-id="<%= page.id %>">
+      <ul class="list-unstyled treeview__children js-treeview-children js-treeview-sortable-container ms-4" data-id="<%= page.id %>">
         <li>loading...</li>
       </ul>
     <% end %>
diff --git a/app/views/admin/communication/website/pages/index.html.erb b/app/views/admin/communication/website/pages/index.html.erb
index 9c2a0a948eac6cc5036f33d61a6c718ae96ae0c4..f51b6d128dd4991096597b4647201d45b7fdb523 100644
--- a/app/views/admin/communication/website/pages/index.html.erb
+++ b/app/views/admin/communication/website/pages/index.html.erb
@@ -1,6 +1,6 @@
 <% content_for :title, Communication::Website::Page.model_name.human(count: 2) %>
 
-<ul class="list-unstyled treeview js-treeview js-treeview-sortable" data-id="">
+<ul class="list-unstyled treeview js-treeview js-treeview-sortable js-treeview-sortable-container" data-id="" data-sort-url="<%= reorder_admin_communication_website_pages_path %>">
   <%= render 'treebranch', pages: @pages %>
 </ul>
 
diff --git a/config/routes/admin/communication.rb b/config/routes/admin/communication.rb
index d32660f95fbc8981a457086447f38b25d3afe7f4..98e4d278f3283e539df38fee03866e27ad678d29 100644
--- a/config/routes/admin/communication.rb
+++ b/config/routes/admin/communication.rb
@@ -5,6 +5,9 @@ namespace :communication do
       post :import
     end
     resources :pages, controller: 'website/pages' do
+      collection do
+        post :reorder
+      end
       member do
         get :children
       end