diff --git a/web/app.js b/web/app.js
index 9d03cc234..505eeb469 100644
--- a/web/app.js
+++ b/web/app.js
@@ -150,6 +150,8 @@ var PDFViewerApplication = {
   pdfOutlineViewer: null,
   /** @type {PDFAttachmentViewer} */
   pdfAttachmentViewer: null,
+  /** @type {ViewHistory} */
+  store: null,
   pageRotation: 0,
   isInitialViewSet: false,
   animationStartedPromise: null,
@@ -603,6 +605,8 @@ var PDFViewerApplication = {
       this.pdfViewer.setDocument(null);
       this.pdfLinkService.setDocument(null, null);
     }
+    this.store = null;
+    this.isInitialViewSet = false;
 
     this.pdfSidebar.reset();
     this.pdfOutlineViewer.reset();
@@ -925,7 +929,6 @@ var PDFViewerApplication = {
     var onePageRendered = pdfViewer.onePageRendered;
 
     this.pageRotation = 0;
-    this.isInitialViewSet = false;
 
     this.pdfThumbnailViewer.setDocument(pdfDocument);
 
@@ -1002,7 +1005,7 @@ var PDFViewerApplication = {
         self.initialBookmark = initialParams.bookmark;
 
         self.pdfViewer.currentScaleValue = self.pdfViewer.currentScaleValue;
-        self.setInitialView(initialParams.hash, scale);
+        self.setInitialView(initialParams.hash);
       });
     });
 
@@ -1682,23 +1685,37 @@ window.addEventListener('presentationmodechanged', function (e) {
     active ? PresentationModeState.FULLSCREEN : PresentationModeState.NORMAL;
 });
 
+window.addEventListener('sidebarviewchanged', function (evt) {
+  if (!PDFViewerApplication.initialized) {
+    return;
+  }
+  PDFViewerApplication.pdfRenderingQueue.isThumbnailViewEnabled =
+    PDFViewerApplication.pdfSidebar.isThumbnailViewVisible;
+
+  var store = PDFViewerApplication.store;
+  if (!store || !PDFViewerApplication.isInitialViewSet) {
+    // Only update the storage when the document has been loaded *and* rendered.
+    return;
+  }
+}, true);
+
 window.addEventListener('updateviewarea', function (evt) {
   if (!PDFViewerApplication.initialized) {
     return;
   }
-  var location = evt.location;
-
-  PDFViewerApplication.store.initializedPromise.then(function() {
-    PDFViewerApplication.store.setMultiple({
-      'exists': true,
-      'page': location.pageNumber,
-      'zoom': location.scale,
-      'scrollLeft': location.left,
-      'scrollTop': location.top
-    }).catch(function() {
-      // unable to write to storage
+  var location = evt.location, store = PDFViewerApplication.store;
+
+  if (store) {
+    store.initializedPromise.then(function() {
+      store.setMultiple({
+        'exists': true,
+        'page': location.pageNumber,
+        'zoom': location.scale,
+        'scrollLeft': location.left,
+        'scrollTop': location.top,
+      }).catch(function() { /* unable to write to storage */ });
     });
-  });
+  }
   var href =
     PDFViewerApplication.pdfLinkService.getAnchorUrl(location.pdfOpenParams);
   document.getElementById('viewBookmark').href = href;
diff --git a/web/pdf_sidebar.js b/web/pdf_sidebar.js
index c28b4db49..0cbae2c50 100644
--- a/web/pdf_sidebar.js
+++ b/web/pdf_sidebar.js
@@ -37,9 +37,9 @@ var SidebarView = {
 
 /**
  * @typedef {Object} PDFSidebarOptions
- * @property {PDFViewer} - The document viewer.
- * @property {PDFThumbnailViewer} - The thumbnail viewer.
- * @property {PDFOutlineViewer} - The outline viewer.
+ * @property {PDFViewer} pdfViewer - The document viewer.
+ * @property {PDFThumbnailViewer} pdfThumbnailViewer - The thumbnail viewer.
+ * @property {PDFOutlineViewer} pdfOutlineViewer - The outline viewer.
  * @property {HTMLDivElement} mainContainer - The main container
  *   (in which the viewer element is placed).
  * @property {HTMLDivElement} outerContainer - The outer container
@@ -139,17 +139,25 @@ var PDFSidebar = (function PDFSidebarClosure() {
       this.isInitialViewSet = true;
 
       if (this.isOpen && view === SidebarView.NONE) {
+        this._dispatchEvent();
         // If the user has already manually opened the sidebar,
         // immediately closing it would be bad UX.
         return;
       }
-      this.switchView(view, true);
+      var isViewPreserved = (view === this.visibleView);
+      this.switchView(view, /* forceOpen */ true);
+
+      if (isViewPreserved) {
+        // Prevent dispatching two back-to-back `sidebarviewchanged` events,
+        // since `this.switchView` dispatched the event if the view changed.
+        this._dispatchEvent();
+      }
     },
 
     /**
      * @param {number} view - The sidebar view that should be switched to,
      *                        must be one of the values in {SidebarView}.
-     * @param {boolean} forceOpen - Ensure that the sidebar is opened.
+     * @param {boolean} forceOpen - (optional) Ensure that the sidebar is open.
      *                              The default value is false.
      */
     switchView: function PDFSidebar_switchView(view, forceOpen) {
@@ -157,9 +165,7 @@ var PDFSidebar = (function PDFSidebarClosure() {
         this.close();
         return;
       }
-      if (forceOpen) {
-        this.open();
-      }
+      var isViewChanged = (view !== this.active);
       var shouldForceRendering = false;
 
       switch (view) {
@@ -172,7 +178,7 @@ var PDFSidebar = (function PDFSidebarClosure() {
           this.outlineView.classList.add('hidden');
           this.attachmentsView.classList.add('hidden');
 
-          if (this.isOpen && view !== this.active) {
+          if (this.isOpen && isViewChanged) {
             this._updateThumbnailViewer();
             shouldForceRendering = true;
           }
@@ -210,9 +216,17 @@ var PDFSidebar = (function PDFSidebarClosure() {
       // in order to prevent setting it to an invalid state.
       this.active = view | 0;
 
+      if (forceOpen && !this.isOpen) {
+        this.open();
+        // NOTE: `this.open` will trigger rendering, and dispatch the event.
+        return;
+      }
       if (shouldForceRendering) {
         this._forceRendering();
       }
+      if (isViewChanged) {
+        this._dispatchEvent();
+      }
     },
 
     open: function PDFSidebar_open() {
@@ -229,6 +243,7 @@ var PDFSidebar = (function PDFSidebarClosure() {
         this._updateThumbnailViewer();
       }
       this._forceRendering();
+      this._dispatchEvent();
     },
 
     close: function PDFSidebar_close() {
@@ -242,6 +257,7 @@ var PDFSidebar = (function PDFSidebarClosure() {
       this.outerContainer.classList.remove('sidebarOpen');
 
       this._forceRendering();
+      this._dispatchEvent();
     },
 
     toggle: function PDFSidebar_toggle() {
@@ -252,6 +268,17 @@ var PDFSidebar = (function PDFSidebarClosure() {
       }
     },
 
+    /**
+     * @private
+     */
+    _dispatchEvent: function PDFSidebar_dispatchEvent() {
+      var event = document.createEvent('CustomEvent');
+      event.initCustomEvent('sidebarviewchanged', true, true, {
+        view: this.visibleView,
+      });
+      this.outerContainer.dispatchEvent(event);
+    },
+
     /**
      * @private
      */