diff --git a/src-ui/package-lock.json b/src-ui/package-lock.json
index c3827f80c..cc43532d0 100644
--- a/src-ui/package-lock.json
+++ b/src-ui/package-lock.json
@@ -2070,6 +2070,11 @@
         "tslib": "^2.0.0"
       }
     },
+    "@ngneat/dirty-check-forms": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@ngneat/dirty-check-forms/-/dirty-check-forms-1.0.1.tgz",
+      "integrity": "sha512-3rgThvjpZIxLS3sANYvma4J4VLITeAsnHrWOe9dtEYauCI4Vl5wDLB2aPNJkKu6EQD/X0QLs96rZvFqe3A3paw=="
+    },
     "@ngtools/webpack": {
       "version": "10.2.0",
       "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-10.2.0.tgz",
diff --git a/src-ui/package.json b/src-ui/package.json
index 14d828483..c7965ff04 100644
--- a/src-ui/package.json
+++ b/src-ui/package.json
@@ -22,6 +22,7 @@
     "@angular/router": "~10.1.5",
     "@ng-bootstrap/ng-bootstrap": "^8.0.0",
     "@ng-select/ng-select": "^5.0.9",
+    "@ngneat/dirty-check-forms": "^1.0.1",
     "bootstrap": "^4.5.0",
     "ng-bootstrap": "^1.6.3",
     "ng2-pdf-viewer": "^6.3.2",
diff --git a/src-ui/src/app/components/manage/settings/settings.component.html b/src-ui/src/app/components/manage/settings/settings.component.html
index 13ffb4517..688100100 100644
--- a/src-ui/src/app/components/manage/settings/settings.component.html
+++ b/src-ui/src/app/components/manage/settings/settings.component.html
@@ -150,5 +150,5 @@
 
   <div [ngbNavOutlet]="nav" class="border-left border-right border-bottom p-3 mb-3 shadow"></div>
 
-  <button type="submit" class="btn btn-primary" i18n>Save</button>
+  <button type="submit" class="btn btn-primary" [disabled]="!(isDirty$ | async)" i18n>Save</button>
 </form>
diff --git a/src-ui/src/app/components/manage/settings/settings.component.ts b/src-ui/src/app/components/manage/settings/settings.component.ts
index 3c4de59b6..231a5a45d 100644
--- a/src-ui/src/app/components/manage/settings/settings.component.ts
+++ b/src-ui/src/app/components/manage/settings/settings.component.ts
@@ -1,35 +1,41 @@
-import { Component, OnInit, Renderer2  } from '@angular/core';
+import { Component, OnInit, OnDestroy, Renderer2  } from '@angular/core';
 import { FormControl, FormGroup } from '@angular/forms';
 import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
 import { DocumentListViewService } from 'src/app/services/document-list-view.service';
 import { SavedViewService } from 'src/app/services/rest/saved-view.service';
 import { LanguageOption, SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
 import { ToastService } from 'src/app/services/toast.service';
+import { dirtyCheck, DirtyComponent } from '@ngneat/dirty-check-forms';
+import { Observable, Subscription, BehaviorSubject } from 'rxjs';
 
 @Component({
   selector: 'app-settings',
   templateUrl: './settings.component.html',
   styleUrls: ['./settings.component.scss']
 })
-export class SettingsComponent implements OnInit {
+export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
 
   savedViewGroup = new FormGroup({})
 
   settingsForm = new FormGroup({
-    'bulkEditConfirmationDialogs': new FormControl(this.settings.get(SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS)),
-    'bulkEditApplyOnClose': new FormControl(this.settings.get(SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE)),
-    'documentListItemPerPage': new FormControl(this.settings.get(SETTINGS_KEYS.DOCUMENT_LIST_SIZE)),
-    'darkModeUseSystem': new FormControl(this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM)),
-    'darkModeEnabled': new FormControl(this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED)),
-    'useNativePdfViewer': new FormControl(this.settings.get(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER)),
+    'bulkEditConfirmationDialogs': new FormControl(null),
+    'bulkEditApplyOnClose': new FormControl(null),
+    'documentListItemPerPage': new FormControl(null),
+    'darkModeUseSystem': new FormControl(null),
+    'darkModeEnabled': new FormControl(null),
+    'useNativePdfViewer': new FormControl(null),
     'savedViews': this.savedViewGroup,
-    'displayLanguage': new FormControl(this.settings.getLanguage()),
-    'dateLocale': new FormControl(this.settings.get(SETTINGS_KEYS.DATE_LOCALE)),
-    'dateFormat': new FormControl(this.settings.get(SETTINGS_KEYS.DATE_FORMAT)),
+    'displayLanguage': new FormControl(null),
+    'dateLocale': new FormControl(null),
+    'dateFormat': new FormControl(null),
   })
 
   savedViews: PaperlessSavedView[]
 
+  store: BehaviorSubject<any>;
+  storeSub: Subscription;
+  isDirty$: Observable<boolean>;
+
   get computedDateLocale(): string {
     return this.settingsForm.value.dateLocale || this.settingsForm.value.displayLanguage
   }
@@ -44,17 +50,49 @@ export class SettingsComponent implements OnInit {
   ngOnInit() {
     this.savedViewService.listAll().subscribe(r => {
       this.savedViews = r.results
+      let storeData = {
+        'bulkEditConfirmationDialogs': this.settings.get(SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS),
+        'bulkEditApplyOnClose': this.settings.get(SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE),
+        'documentListItemPerPage': this.settings.get(SETTINGS_KEYS.DOCUMENT_LIST_SIZE),
+        'darkModeUseSystem': this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM),
+        'darkModeEnabled': this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED),
+        'useNativePdfViewer': this.settings.get(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER),
+        'savedViews': {},
+        'displayLanguage': this.settings.getLanguage(),
+        'dateLocale': this.settings.get(SETTINGS_KEYS.DATE_LOCALE),
+        'dateFormat': this.settings.get(SETTINGS_KEYS.DATE_FORMAT),
+      }
+
       for (let view of this.savedViews) {
+        storeData.savedViews[view.id.toString()] = {
+          "id": view.id,
+          "name": view.name,
+          "show_on_dashboard": view.show_on_dashboard,
+          "show_in_sidebar": view.show_in_sidebar
+        }
         this.savedViewGroup.addControl(view.id.toString(), new FormGroup({
-          "id": new FormControl(view.id),
-          "name": new FormControl(view.name),
-          "show_on_dashboard": new FormControl(view.show_on_dashboard),
-          "show_in_sidebar": new FormControl(view.show_in_sidebar)
+          "id": new FormControl(null),
+          "name": new FormControl(null),
+          "show_on_dashboard": new FormControl(null),
+          "show_in_sidebar": new FormControl(null)
         }))
       }
+
+      this.store = new BehaviorSubject(storeData)
+
+      this.storeSub = this.store.asObservable().subscribe(state => {
+        this.settingsForm.patchValue(state, { emitEvent: false })
+      });
+
+      // Initialize dirtyCheck
+      this.isDirty$ = dirtyCheck(this.settingsForm, this.store.asObservable());
     })
   }
 
+  ngOnDestroy() {
+    this.storeSub && this.storeSub.unsubscribe();
+  }
+
   deleteSavedView(savedView: PaperlessSavedView) {
     this.savedViewService.delete(savedView).subscribe(() => {
       this.savedViewGroup.removeControl(savedView.id.toString())