diff --git a/app/app.js b/app/app.js
index 45290a9775a490fb86d8dc7dace4af561ba294df..a6a2cdc843beef7d0a8bbd1a4a84ffc1f0dc3aa8 100644
--- a/app/app.js
+++ b/app/app.js
@@ -3,7 +3,7 @@ import Resolver from 'ember-resolver';
 import loadInitializers from 'ember-load-initializers';
 import config from 'papermerge/config/environment';
 import '@popperjs/core';
-import 'bootstrap';
+import bootstrap from 'bootstrap';
 
 
 export default class App extends Application {
@@ -27,6 +27,13 @@ export default class App extends Application {
     if (divs.length > 0) {
       divs[0].style.display = 'None';
     }
+
+    /*Initializer bootstrap toasts*/
+    let toastElList = [].slice.call(document.querySelectorAll('.toast'))
+    toastElList.map(function (toastEl) {
+      return new bootstrap.Toast(toastEl)
+    })
+
   }
 }
 
diff --git a/app/components/notifications/index.hbs b/app/components/notifications/index.hbs
new file mode 100644
index 0000000000000000000000000000000000000000..f6cc4c69f44c38490d03ac23a263d5254611dbdc
--- /dev/null
+++ b/app/components/notifications/index.hbs
@@ -0,0 +1,5 @@
+<div class="toast-container position-fixed top-0 end-0 p-3">
+  {{#each this.notifications as |notification|}}
+    <Notifications::Toast @notification={{notification}} />
+  {{/each}}
+</div>
diff --git a/app/components/notifications/index.js b/app/components/notifications/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..e025c2d2c79ad692421a2e0a94bd4f21ed6c182b
--- /dev/null
+++ b/app/components/notifications/index.js
@@ -0,0 +1,11 @@
+import Component from '@glimmer/component';
+import { service } from '@ember/service';
+
+
+export default class NotificationsComponent extends Component {
+  @service notify;
+
+  get notifications() {
+    return this.notify.notifications;
+  }
+}
\ No newline at end of file
diff --git a/app/components/notifications/toast/index.hbs b/app/components/notifications/toast/index.hbs
new file mode 100644
index 0000000000000000000000000000000000000000..ac470689bd7cc5d9c3796f3dbc9e643b1882edea
--- /dev/null
+++ b/app/components/notifications/toast/index.hbs
@@ -0,0 +1,21 @@
+<div class="toast show" role="alert" aria-live="assertive" aria-atomic="true">
+  <div class="toast-header">
+    {{#if (is_equal this.type 'info') }}
+      <strong class="me-auto text-primary">
+        <i class='bi bi-info-circle mx-2'></i>Info
+      </strong>
+    {{else if (is_equal this.type 'error')}}
+      <strong class="me-auto text-danger">
+        <i class='bi bi-info-circle mx-2'></i>Error
+      </strong>
+    {{else}}
+      <strong class="me-auto text-warning">
+        <i class='bi bi-info-circle mx-2'></i>Warning
+      </strong>
+    {{/if}}
+    <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
+  </div>
+  <div class="toast-body">
+    {{this.message}}
+  </div>
+</div>
diff --git a/app/components/notifications/toast/index.js b/app/components/notifications/toast/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..03f0ff49e29048be635cb7386473bc835477b2ab
--- /dev/null
+++ b/app/components/notifications/toast/index.js
@@ -0,0 +1,12 @@
+import Component from '@glimmer/component';
+
+
+export default class ToastComponent extends Component {
+  get type() {
+    return this.args.notification.type;
+  }
+
+  get message() {
+    return this.args.notification.message;
+  }
+}
\ No newline at end of file
diff --git a/app/components/role/edit.js b/app/components/role/edit.js
index 4096a3660ddff7ef63ccbe8b4ea8507450529868..2ff0d1c002f4963aa219588288d977565da59c92 100644
--- a/app/components/role/edit.js
+++ b/app/components/role/edit.js
@@ -1,6 +1,5 @@
 import Component from '@glimmer/component';
 import { action } from '@ember/object';
-import { tracked } from '@glimmer/tracking';
 import { inject as service } from '@ember/service';
 import { group_perms_by_model } from 'papermerge/utils';
 
diff --git a/app/components/viewer/action_buttons/index.hbs b/app/components/viewer/action_buttons/index.hbs
index e52acb690179ea7adbedebeed4564624a35f91eb..67102cdac9e54c41f1e9c3476b5236b5c6936db8 100644
--- a/app/components/viewer/action_buttons/index.hbs
+++ b/app/components/viewer/action_buttons/index.hbs
@@ -31,10 +31,11 @@
   {{#if @page_order_changed }}
     Page order changed.
     <button
-      class="btn btn-success"
+      class="btn btn-success pe-4"
       type="button"
       {{on "click" @onPageOrderApply}}>
-      Apply Changes
+        <Spinner @inProgress={{@apply_page_order_changes_in_progress}} />
+        Apply Changes
     </button>
     <button
       class="btn btn-secondary"
diff --git a/app/components/viewer/index.hbs b/app/components/viewer/index.hbs
index 1925961bb7d809f71d10d11cc373c90fb5b96709..87dccdc290adcba37ec032396da02a2071b5f3e4 100644
--- a/app/components/viewer/index.hbs
+++ b/app/components/viewer/index.hbs
@@ -6,6 +6,7 @@
       @ocrStatus={{this.ocrStatus}}
       @selectedPages={{this.selected_pages}}
       @page_order_changed={{this.page_order_changed}}
+      @apply_page_order_changes_in_progress={{this.apply_page_order_changes_in_progress}}
       @onPageOrderApply={{this.onPageOrderApply}}
       @onPageOrderDiscard={{this.onPageOrderDiscard}}
       @openConfirmDeletionModal={{this.openConfirmDeletionModal}}
diff --git a/app/components/viewer/index.js b/app/components/viewer/index.js
index 3afae65deb38ea79b212693c65b9f392ee01e9b1..ec2e4a26c4d574f1821b168f5b3e46388b25605f 100644
--- a/app/components/viewer/index.js
+++ b/app/components/viewer/index.js
@@ -23,6 +23,7 @@ export default class ViewerComponent extends Component {
   @service websockets;
   @service store;
   @service requests;
+  @service notify;
   @service router;
 
   @tracked ocr_status = null;
@@ -38,6 +39,7 @@ export default class ViewerComponent extends Component {
   @tracked show_confirm_pages_deletion_modal = false;
   @tracked show_rename_node_modal = false;
   @tracked page_order_changed = false;
+  @tracked apply_page_order_changes_in_progress = false;
 
   initial_pages_memo = A([]);
 
@@ -254,11 +256,26 @@ export default class ViewerComponent extends Component {
 
   @action
   async onPageOrderApply() {
-    await this.requests.reorderPagesApply({
+    this.apply_page_order_changes_in_progress = true;
+    this.requests.reorderPagesApply({
       old_items: this.initial_pages_memo,
       new_items: this.pages
-    });
-    this.router.refresh();
+    }).then(
+      () => { // on success
+        this.apply_page_order_changes_in_progress = false;
+        this.notify.info(
+          'New page order successfully applied'
+        );
+        this.page_order_changed = false;
+      },
+      () => { // on failure
+        this.apply_page_order_changes_in_progress = false;
+        this.notify.error(
+          'There was a problem while saving new page order'
+        );
+        this.page_order_changed = false;
+      }
+    );
   }
 
   @action
diff --git a/app/services/notify.js b/app/services/notify.js
new file mode 100644
index 0000000000000000000000000000000000000000..0c8df9b6e2cfe6205bb025809ec8f501e64c8ff0
--- /dev/null
+++ b/app/services/notify.js
@@ -0,0 +1,29 @@
+import Service from '@ember/service';
+import { tracked } from 'tracked-built-ins';
+import { TrackedArray } from 'tracked-built-ins';
+
+
+export default class Notify extends Service {
+  /*
+    Push notifications to your visitors with a toast, a lightweight and easily customizable alert message.
+  */
+  @tracked notifications = new TrackedArray([]);
+
+  info(message) {
+    let type = 'info';
+
+    this.notifications.push({message, type});
+  }
+
+  warning(message) {
+    let type = 'warning';
+
+    this.notifications.push({message, type});
+  }
+
+  error(message) {
+    let type = 'error';
+
+    this.notifications.push({message, type});
+  }
+}
diff --git a/app/styles/app.scss b/app/styles/app.scss
index 62e279daba65ce75b68079c2ac613aacd6eec65b..3bd27afe138dadb007d0555eda0abf8f70fb8302 100644
--- a/app/styles/app.scss
+++ b/app/styles/app.scss
@@ -73,3 +73,7 @@ main {
 .droparea {
   outline: 1px solid green;
 }
+
+.toast-container {
+  z-index: 1000;
+}
\ No newline at end of file
diff --git a/app/templates/authenticated.hbs b/app/templates/authenticated.hbs
index 56b274ac94251b0209ea59891ac0ccdead9420e7..a28f426d8d8d9b86fcf07bf1e338a16b40f08a9a 100644
--- a/app/templates/authenticated.hbs
+++ b/app/templates/authenticated.hbs
@@ -6,6 +6,7 @@
     @pinned_tags={{@model.pinned_tags}}
     @expanded={{this.expanded_sidebar}} />
   <div class="w-100 central-bar">
+    <Notifications />
     <Nav::Topbar
       @onSidebarToggle={{this.onSidebarToggle}} />
     <div class="container-fluid mx-2 my-1">
diff --git a/package.json b/package.json
index f208e376e7f1da7925e8aebfca9e729139121789..d26c93661dcea294a92a141312d3e38d1024e1da 100644
--- a/package.json
+++ b/package.json
@@ -69,7 +69,8 @@
     "prettier": "^2.5.1",
     "qunit": "^2.17.2",
     "qunit-dom": "^2.0.0",
-    "sass": "^1.47.0"
+    "sass": "^1.47.0",
+    "tracked-built-ins": "^2.0.1"
   },
   "engines": {
     "node": "12.* || 14.* || >= 16"
@@ -78,7 +79,6 @@
     "edition": "octane"
   },
   "devDependencies": {
-    "tracked-built-ins": "^2.0.1",
     "webpack": "^5.65.0"
   }
 }