diff --git a/__tests__/src/components/WindowSideBarCanvasPanel.test.js b/__tests__/src/components/WindowSideBarCanvasPanel.test.js
index e01de7a023d63ddbb5747e67434e9a7e6450650e..d38027ec1e54b53c2acbb8c7a96f094368f8adaa 100644
--- a/__tests__/src/components/WindowSideBarCanvasPanel.test.js
+++ b/__tests__/src/components/WindowSideBarCanvasPanel.test.js
@@ -7,7 +7,6 @@ import manifesto from 'manifesto.js';
 import { WindowSideBarCanvasPanel } from '../../../src/components/WindowSideBarCanvasPanel';
 import { CanvasThumbnail } from '../../../src/components/CanvasThumbnail';
 import manifestJson from '../../fixtures/version-2/019.json';
-import { getIdAndLabelOfCanvases } from '../../../src/state/selectors';
 
 /**
  * Helper function to create a shallow wrapper around WindowSideBarCanvasPanel
@@ -68,21 +67,20 @@ describe('WindowSideBarCanvasPanel', () => {
 
   it('should set the correct labels', () => {
     const wrapper = createWrapper();
-    const canvases = manifesto.create(manifestJson).getSequences()[0].getCanvases();
-    const idsAndLabels = getIdAndLabelOfCanvases(canvases);
+
     expect(wrapper
       .find(List)
       .find(Typography)
       .at(0)
       .render()
-      .text()).toBe(idsAndLabels[0].label);
+      .text()).toBe('Test 19 Canvas: 1');
 
     expect(wrapper
       .find(List)
       .find(Typography)
       .at(1)
       .render()
-      .text()).toBe(idsAndLabels[1].label);
+      .text()).toBe('Image 1');
   });
 
   it('should call the onClick handler of a list item', () => {
@@ -90,4 +88,36 @@ describe('WindowSideBarCanvasPanel', () => {
     wrapper.find(ListItem).at(1).simulate('click');
     expect(setCanvas).toHaveBeenCalledTimes(1);
   });
+
+  describe('getIdAndLabelOfCanvases', () => {
+    it('should return id and label of each canvas in manifest', () => {
+      const canvases = manifesto
+        .create(manifestJson)
+        .getSequences()[0]
+        .getCanvases();
+      const wrapper = createWrapper({ canvases });
+      const received = wrapper.instance().getIdAndLabelOfCanvases(canvases);
+      const expected = [
+        {
+          id: 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json',
+          label: 'Test 19 Canvas: 1',
+        },
+        {
+          id: 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1',
+          label: 'Image 1',
+        },
+        {
+          id: 'https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1',
+          label: 'Image 2',
+        },
+      ];
+      expect(received).toEqual(expected);
+    });
+
+    it('should return empty array if canvas if empty', () => {
+      const wrapper = createWrapper({ canvases: [] });
+      const received = wrapper.instance().getIdAndLabelOfCanvases([]);
+      expect(received).toEqual([]);
+    });
+  });
 });
diff --git a/__tests__/src/selectors/index.test.js b/__tests__/src/selectors/index.test.js
index fdd9ae417dffce6bafbda95487853d8e2d2dde61..c2391dfede742134be0bb4c5b15ff55c9540a2b9 100644
--- a/__tests__/src/selectors/index.test.js
+++ b/__tests__/src/selectors/index.test.js
@@ -1,25 +1,17 @@
-import manifesto from 'manifesto.js';
 import manifestFixture001 from '../../fixtures/version-2/001.json';
-import manifestFixture002 from '../../fixtures/version-2/002.json';
-import manifestFixture019 from '../../fixtures/version-2/019.json';
-import manifestFixtureWithAProvider from '../../fixtures/version-3/with_a_provider.json';
 import {
   getCanvasLabel,
   getCompanionWindowForPosition,
   getAnnotationResourcesByMotivation,
   getIdAndContentOfResources,
   getLanguagesFromConfigWithCurrent,
-  getSelectedCanvas,
-  getSelectedCanvases,
   getThumbnailNavigationPosition,
   getSelectedAnnotationIds,
   getSelectedTargetAnnotations,
   getSelectedTargetsAnnotations,
   getSelectedTargetAnnotationResources,
   getWindowViewType,
-  getIdAndLabelOfCanvases,
   getCompanionWindowsOfWindow,
-  getWindowTitles,
 } from '../../../src/state/selectors';
 import Annotation from '../../../src/lib/Annotation';
 import AnnotationResource from '../../../src/lib/AnnotationResource';
@@ -36,17 +28,17 @@ describe('getThumbnailNavigationPosition', () => {
   };
 
   it('should return thumbnail navigation position if window exists', () => {
-    const received = getThumbnailNavigationPosition(state, 'a');
+    const received = getThumbnailNavigationPosition(state, { windowId: 'a' });
     expect(received).toBe('bottom');
   });
 
   it('should return undefined if position does not exist in window', () => {
-    const received = getThumbnailNavigationPosition(state, 'b');
+    const received = getThumbnailNavigationPosition(state, { windowId: 'b' });
     expect(received).toBeUndefined();
   });
 
   it('should return undefined if window does not exists', () => {
-    const received = getThumbnailNavigationPosition(state, 'c');
+    const received = getThumbnailNavigationPosition(state, { windowId: 'c' });
     expect(received).toBeUndefined();
   });
 });
@@ -60,40 +52,53 @@ describe('getWindowViewType', () => {
   };
 
   it('should return view type if window exists', () => {
-    const received = getWindowViewType(state, 'a');
+    const received = getWindowViewType(state, { windowId: 'a' });
     expect(received).toBe('single');
   });
 
   it('should return undefined if view type does not exist in window', () => {
-    const received = getWindowViewType(state, 'b');
+    const received = getWindowViewType(state, { windowId: 'b' });
     expect(received).toBeUndefined();
   });
 
   it('should return undefined if window does not exists', () => {
-    const received = getWindowViewType(state, 'c');
+    const received = getWindowViewType(state, { windowId: 'c' });
     expect(received).toBeUndefined();
   });
 });
 
 describe('getCanvasLabel', () => {
   it('should return label of the canvas', () => {
-    const canvas = manifesto
-      .create(manifestFixture001)
-      .getSequences()[0]
-      .getCanvases()[0];
-
-    const received = getCanvasLabel(canvas);
+    const state = { manifests: { a: { json: manifestFixture001 } } };
+    const received = getCanvasLabel(state, { manifestId: 'a', canvasIndex: 0 });
     expect(received).toBe('Whole Page');
   });
 
   it('should return undefined if the canvas is undefined', () => {
-    expect(getCanvasLabel(undefined)).toBeUndefined();
+    const state = { manifests: { } };
+    expect(getCanvasLabel(state, { manifestId: 'b', canvasIndex: 0 })).toBeUndefined();
   });
 
   it('should return the canvas index as (+1) as string if no label given', () => {
-    const canvas = { getLabel: () => [] };
-    const received = getCanvasLabel(canvas, 42);
-    expect(received).toBe('43');
+    const manifest = {
+      '@context': 'http://iiif.io/api/presentation/2/context.json',
+      '@id':
+       'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json',
+      '@type': 'sc:Manifest',
+      sequences: [
+        {
+          canvases: [
+            {
+              '@id': 'some-canvas-without-a-label',
+            },
+          ],
+        },
+      ],
+    };
+
+    const state = { manifests: { a: { json: manifest } } };
+    const received = getCanvasLabel(state, { manifestId: 'a', canvasIndex: 0 });
+    expect(received).toBe('1');
   });
 });
 
@@ -202,36 +207,6 @@ describe('getIdAndContentOfResources', () => {
   });
 });
 
-describe('getIdAndLabelOfCanvases', () => {
-  it('should return id and label of each canvas in manifest', () => {
-    const canvases = manifesto
-      .create(manifestFixture019)
-      .getSequences()[0]
-      .getCanvases();
-    const received = getIdAndLabelOfCanvases(canvases);
-    const expected = [
-      {
-        id: 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json',
-        label: 'Test 19 Canvas: 1',
-      },
-      {
-        id: 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1',
-        label: 'Image 1',
-      },
-      {
-        id: 'https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1',
-        label: 'Image 2',
-      },
-    ];
-    expect(received).toEqual(expected);
-  });
-
-  it('should return empty array if canvas if empty', () => {
-    const received = getIdAndLabelOfCanvases([]);
-    expect(received).toEqual([]);
-  });
-});
-
 describe('getCompanionWindowForPosition', () => {
   const state = {
     windows: { a: { companionWindowIds: ['abc'] } },
@@ -242,19 +217,19 @@ describe('getCompanionWindowForPosition', () => {
   };
 
   it('the companion window type based on the given position', () => {
-    const received = getCompanionWindowForPosition(state, 'a', 'right');
+    const received = getCompanionWindowForPosition(state, { windowId: 'a', position: 'right' });
 
     expect(received.id).toEqual('abc');
   });
 
   it('returns undefined if the given window does not exist', () => {
-    const received = getCompanionWindowForPosition(state, 'c', 'right');
+    const received = getCompanionWindowForPosition(state, { windowId: 'c', position: 'right' });
 
     expect(received).toBeUndefined();
   });
 
   it('returns undefined if a companion window at the given position does not exist', () => {
-    const received = getCompanionWindowForPosition(state, 'a', 'bottom');
+    const received = getCompanionWindowForPosition(state, { windowId: 'a', position: 'bottom' });
 
     expect(received).toBeUndefined();
   });
@@ -295,7 +270,7 @@ describe('getCompanionWindowsOfWindow', () => {
   };
 
   it('should return companion windows for a given window id', () => {
-    const received = getCompanionWindowsOfWindow(state, 'abc123');
+    const received = getCompanionWindowsOfWindow(state, { windowId: 'abc123' });
 
     expect(received).toEqual([
       { id: 'foo', content: 'info' },
diff --git a/src/components/GalleryView.js b/src/components/GalleryView.js
index 9c9e66b4a09bf1fdefa69af35dbbbd90ffdb9313..5b348e60b074ae4a087279a39e34bf9becdeb404 100644
--- a/src/components/GalleryView.js
+++ b/src/components/GalleryView.js
@@ -2,7 +2,6 @@ import React, { Component } from 'react';
 import PropTypes from 'prop-types';
 import Typography from '@material-ui/core/Typography';
 import ManifestoCanvas from '../lib/ManifestoCanvas';
-import { getCanvasLabel } from '../state/selectors';
 import { CanvasThumbnail } from './CanvasThumbnail';
 import ns from '../config/css-ns';
 
@@ -52,7 +51,7 @@ export class GalleryView extends Component {
                     aspectRatio={manifestoCanvas.aspectRatio}
                   />
                   <Typography variant="caption">
-                    {getCanvasLabel(canvas, canvas.index)}
+                    {manifestoCanvas.getLabel()}
                   </Typography>
                 </div>
               );
diff --git a/src/components/ThumbnailNavigation.js b/src/components/ThumbnailNavigation.js
index 2b185d1c1225ab9c2951a7ca47f1c21c41834715..2626aaadbb367d23dfe07edb4e5afab6c22dae20 100644
--- a/src/components/ThumbnailNavigation.js
+++ b/src/components/ThumbnailNavigation.js
@@ -5,7 +5,6 @@ import Grid from 'react-virtualized/dist/commonjs/Grid';
 import GridListTile from '@material-ui/core/GridListTile';
 import GridListTileBar from '@material-ui/core/GridListTileBar';
 import Typography from '@material-ui/core/Typography';
-import { getCanvasLabel } from '../state/selectors';
 import { CanvasThumbnail } from './CanvasThumbnail';
 import ManifestoCanvas from '../lib/ManifestoCanvas';
 import ns from '../config/css-ns';
@@ -97,7 +96,7 @@ export class ThumbnailNavigation extends Component {
                   classes={{ root: classes.root }}
                   title={(
                     <Typography classes={{ root: classes.title }} variant="caption">
-                      {getCanvasLabel(canvas, canvas.index)}
+                      {manifestoCanvas.getLabel()}
                     </Typography>
                   )}
                 />
diff --git a/src/components/WindowSideBarCanvasPanel.js b/src/components/WindowSideBarCanvasPanel.js
index 80eae9a8e822f1344acb91fe46a7d5685923bbe1..f8f641fa7e2713a75ee135d4e3308d8f140cfb57 100644
--- a/src/components/WindowSideBarCanvasPanel.js
+++ b/src/components/WindowSideBarCanvasPanel.js
@@ -10,7 +10,6 @@ import Select from '@material-ui/core/Select';
 import { CanvasThumbnail } from './CanvasThumbnail';
 import ManifestoCanvas from '../lib/ManifestoCanvas';
 import CompanionWindow from '../containers/CompanionWindow';
-import { getIdAndLabelOfCanvases } from '../state/selectors';
 
 /**
  * a panel showing the canvases for a given manifest
@@ -24,6 +23,16 @@ export class WindowSideBarCanvasPanel extends Component {
     this.handleVariantChange = this.handleVariantChange.bind(this);
   }
 
+  /** @private */
+  getIdAndLabelOfCanvases() {
+    const { canvases } = this.props;
+
+    return canvases.map((canvas, index) => ({
+      id: canvas.id,
+      label: new ManifestoCanvas(canvas).getLabel(),
+    }));
+  }
+
   /** */
   handleVariantChange(event) {
     this.setState({ variant: event.target.value });
@@ -88,7 +97,7 @@ export class WindowSideBarCanvasPanel extends Component {
     const { variant } = this.state;
 
 
-    const canvasesIdAndLabel = getIdAndLabelOfCanvases(canvases);
+    const canvasesIdAndLabel = this.getIdAndLabelOfCanvases(canvases);
     return (
       <CompanionWindow
         title={t('canvasIndex')}
diff --git a/src/containers/CompanionArea.js b/src/containers/CompanionArea.js
index f8b29c6825ac731664f881c0093551852e0b6477..f9d577e2489addb37b578fb708a282a7271a7269 100644
--- a/src/containers/CompanionArea.js
+++ b/src/containers/CompanionArea.js
@@ -10,7 +10,7 @@ import { CompanionArea } from '../components/CompanionArea';
 /** */
 const mapStateToProps = (state, { windowId, position }) => ({
   sideBarOpen: state.windows[windowId].sideBarOpen,
-  companionWindows: getCompanionWindowsOfWindow(state, windowId)
+  companionWindows: getCompanionWindowsOfWindow(state, { windowId })
     .filter(cw => cw.position === position),
   companionAreaOpen: position !== 'left' || state.windows[windowId].companionAreaOpen,
 });
diff --git a/src/containers/OpenSeadragonViewer.js b/src/containers/OpenSeadragonViewer.js
index cbc4861798567df5b782a9ba6e18c51364c1dc9e..d0aecea6e5f6abe235e13986d836459018a5d520 100644
--- a/src/containers/OpenSeadragonViewer.js
+++ b/src/containers/OpenSeadragonViewer.js
@@ -9,7 +9,6 @@ import * as actions from '../state/actions';
 import {
   getCanvasLabel,
   getSelectedAnnotationIds,
-  getSelectedCanvas,
   getSelectedTargetAnnotationResources,
 } from '../state/selectors';
 
@@ -22,10 +21,7 @@ const mapStateToProps = ({
   viewers, windows, manifests, annotations,
 }, { windowId, currentCanvases }) => ({
   viewer: viewers[windowId],
-  label: getCanvasLabel(
-    getSelectedCanvas({ windows, manifests }, { windowId }),
-    windows[windowId].canvasIndex,
-  ),
+  label: getCanvasLabel({ windows, manifests }, { windowId, canvasIndex: 'selected' }),
   annotations: getSelectedTargetAnnotationResources(
     { annotations },
     currentCanvases.map(c => c.id),
diff --git a/src/containers/ViewerInfo.js b/src/containers/ViewerInfo.js
index 9581824ccab9a2b41fb6bd6b5c79ace79cae1d14..ad0fcfd101cae2559d82297fba95bb783c78825b 100644
--- a/src/containers/ViewerInfo.js
+++ b/src/containers/ViewerInfo.js
@@ -18,7 +18,7 @@ const mapStateToProps = (state, props) => {
   return {
     canvasCount: canvases.length,
     canvasIndex,
-    canvasLabel: getCanvasLabel(canvases[canvasIndex], canvasIndex),
+    canvasLabel: getCanvasLabel(state, { windowId, canvasIndex }),
   };
 };
 
diff --git a/src/containers/Window.js b/src/containers/Window.js
index 318daa9b52ad7530f2deaf5c4de2e0d4b31efc34..2bdfa90e2efd6bec46fd4ec38207ad7db1f1a82e 100644
--- a/src/containers/Window.js
+++ b/src/containers/Window.js
@@ -18,7 +18,7 @@ const mapStateToProps = (state, props) => ({
   window: state.windows[props.window.id],
   workspaceType: state.config.workspace.type,
   label: getManifestTitle(state, { windowId: props.window.id }),
-  thumbnailNavigationPosition: getThumbnailNavigationPosition(state, props.window.id),
+  thumbnailNavigationPosition: getThumbnailNavigationPosition(state, { windowId: props.window.id }),
 });
 
 /**
diff --git a/src/containers/WindowCanvasNavigationControls.js b/src/containers/WindowCanvasNavigationControls.js
index b76793a10ee93704145d1466876ce19d1d31bca8..a8b8384879ab07c538f816113fa62e11a48b292b 100644
--- a/src/containers/WindowCanvasNavigationControls.js
+++ b/src/containers/WindowCanvasNavigationControls.js
@@ -3,17 +3,13 @@ import { compose } from 'redux';
 import { withPlugins } from '../extend';
 import {
   getCanvasLabel,
-  getSelectedCanvas,
 } from '../state/selectors';
 import { WindowCanvasNavigationControls } from '../components/WindowCanvasNavigationControls';
 
 /** */
 const mapStateToProps = (state, { windowId }) => ({
   window: state.windows[windowId],
-  canvasLabel: getCanvasLabel(
-    getSelectedCanvas(state, { windowId }),
-    state.windows[windowId].canvasIndex,
-  ),
+  canvasLabel: getCanvasLabel(state, { windowId, canvasIndex: 'selected' }),
   visible: state.workspace.focusedWindowId === windowId,
 });
 
diff --git a/src/containers/WindowSideBarButtons.js b/src/containers/WindowSideBarButtons.js
index 2cec11da4ce48d811b600db0899b272341063da8..17dbfd7bc913e57fc69f5e10cb1a938417098c63 100644
--- a/src/containers/WindowSideBarButtons.js
+++ b/src/containers/WindowSideBarButtons.js
@@ -36,7 +36,7 @@ const mapStateToProps = (state, { windowId }) => ({
     getSelectedTargetAnnotations(state, (getSelectedCanvas(state, { windowId }) || {}).id),
     ['oa:commenting', 'sc:painting'],
   ).length > 0,
-  sideBarPanel: (getCompanionWindowForPosition(state, windowId, 'left') || {}).content,
+  sideBarPanel: (getCompanionWindowForPosition(state, { windowId, position: 'left' }) || {}).content,
 });
 
 /** */
diff --git a/src/containers/WindowSideBarInfoPanel.js b/src/containers/WindowSideBarInfoPanel.js
index dd10cbe92196623d7b6b013a4f96c2178e484509..e55cc7a520ad0537a6f9c6330c49e50adc32ffc5 100644
--- a/src/containers/WindowSideBarInfoPanel.js
+++ b/src/containers/WindowSideBarInfoPanel.js
@@ -20,11 +20,8 @@ import { WindowSideBarInfoPanel } from '../components/WindowSideBarInfoPanel';
  * @private
  */
 const mapStateToProps = (state, { windowId }) => ({
-  canvasLabel: getCanvasLabel(
-    getSelectedCanvas(state, { windowId }),
-    state.windows[windowId].canvasIndex,
-  ),
-  canvasDescription: getCanvasDescription(getSelectedCanvas(state, { windowId })),
+  canvasLabel: getCanvasLabel(state, { windowId, canvasIndex: 'selected' }),
+  canvasDescription: getCanvasDescription(state, { windowId, canvasIndex: 'selected' }),
   canvasMetadata: getDestructuredMetadata(getSelectedCanvas(state, { windowId })),
   manifestLabel: getManifestTitle(state, { windowId }),
   manifestDescription: getManifestDescription(state, { windowId }),
diff --git a/src/containers/WindowThumbnailSettings.js b/src/containers/WindowThumbnailSettings.js
index 0fa87898f2c0b6877f70e50b777f4d3bbb6ee5e5..86ece45e61d629e6425997f314c2816905220ea2 100644
--- a/src/containers/WindowThumbnailSettings.js
+++ b/src/containers/WindowThumbnailSettings.js
@@ -19,9 +19,9 @@ const mapDispatchToProps = { setWindowThumbnailPosition: actions.setWindowThumbn
  * @memberof WindowViewer
  * @private
  */
-const mapStateToProps = (state, props) => (
+const mapStateToProps = (state, { windowId }) => (
   {
-    thumbnailNavigationPosition: getThumbnailNavigationPosition(state, props.windowId),
+    thumbnailNavigationPosition: getThumbnailNavigationPosition(state, { windowId }),
   }
 );
 
diff --git a/src/containers/WindowViewSettings.js b/src/containers/WindowViewSettings.js
index 1a7d8c44ed4911d6f23f24e6fe71115508d973ea..dcd29e9ea9ed3cf4ceb058c31ac2512b1359d054 100644
--- a/src/containers/WindowViewSettings.js
+++ b/src/containers/WindowViewSettings.js
@@ -19,9 +19,9 @@ const mapDispatchToProps = { setWindowViewType: actions.setWindowViewType };
  * @memberof WindowViewer
  * @private
  */
-const mapStateToProps = (state, props) => (
+const mapStateToProps = (state, { windowId }) => (
   {
-    windowViewType: getWindowViewType(state, props.windowId),
+    windowViewType: getWindowViewType(state, { windowId }),
   }
 );
 
diff --git a/src/lib/ManifestoCanvas.js b/src/lib/ManifestoCanvas.js
index 684ae96ee85cbe8157c1d9e67f5efe1957ccb5eb..221691aa9e04e20e87d003aacb7938435d7bcfb2 100644
--- a/src/lib/ManifestoCanvas.js
+++ b/src/lib/ManifestoCanvas.js
@@ -79,6 +79,15 @@ export default class ManifestoCanvas {
     );
   }
 
+  /**
+   * Get the canvas label
+   */
+  getLabel() {
+    return this.canvas.getLabel().length > 0
+      ? this.canvas.getLabel().map(label => label.value)[0]
+      : String(this.canvas.index + 1);
+  }
+
   /**
    * Creates a canonical image request for a thumb
    * @param {Number} height
diff --git a/src/state/selectors/canvases.js b/src/state/selectors/canvases.js
index 26d74e5dac2ca23be28bc48141b0a56c37e0f73e..8051a0d019dd4bcf1270989d0e457888b978834d 100644
--- a/src/state/selectors/canvases.js
+++ b/src/state/selectors/canvases.js
@@ -2,18 +2,27 @@ import { createSelector } from 'reselect';
 import CanvasGroupings from '../../lib/CanvasGroupings';
 import { getManifestoInstance } from './manifests';
 
+export const getCanvases = createSelector(
+  [getManifestoInstance],
+  manifest => manifest && manifest.getSequences()[0].getCanvases(),
+);
+
 /**
-* Return the current canvas selected in a window
+* Return the canvas selected by an index
 * @param {object} state
 * @param {object} props
 * @param {string} props.manifestId
 * @param {string} props.windowId
 * @return {Object}
 */
-export const getSelectedCanvas = createSelector(
+export const getCanvas = createSelector(
   [
     getManifestoInstance,
-    (state, { windowId }) => state.windows[windowId].canvasIndex,
+    (state, { windowId, canvasIndex }) => (
+      canvasIndex === 'selected'
+        ? state.windows[windowId].canvasIndex
+        : canvasIndex
+    ),
   ],
   (manifest, canvasIndex) => manifest
     && manifest
@@ -21,6 +30,18 @@ export const getSelectedCanvas = createSelector(
       .getCanvasByIndex(canvasIndex),
 );
 
+/**
+* Return the current canvas selected in a window
+* @param {object} state
+* @param {object} props
+* @param {string} props.manifestId
+* @param {string} props.windowId
+* @return {Object}
+*/
+export function getSelectedCanvas(state, props) {
+  return getCanvas(state, { ...props, canvasIndex: 'selected' });
+}
+
 /**
 * Return the current canvases selected in a window
 * For book view returns 2, for single returns 1
@@ -32,12 +53,12 @@ export const getSelectedCanvas = createSelector(
 */
 export const getSelectedCanvases = createSelector(
   [
-    getManifestoInstance,
+    getCanvases,
     (state, { windowId }) => state.windows[windowId],
   ],
-  (manifest, { canvasIndex, view }) => manifest
+  (canvases, { canvasIndex, view }) => canvases
     && new CanvasGroupings(
-      manifest.getSequences()[0].getCanvases(),
+      canvases,
       view,
     ).getCanvases(canvasIndex),
 );
diff --git a/src/state/selectors/index.js b/src/state/selectors/index.js
index c51fdf2df3a9c7a298bffb59357da71d29a90c83..fb5f2f433329dc23d8e9840b12e19654a5acb8c9 100644
--- a/src/state/selectors/index.js
+++ b/src/state/selectors/index.js
@@ -1,23 +1,13 @@
+import { createSelector } from 'reselect';
 import filter from 'lodash/filter';
 import flatten from 'lodash/flatten';
 import Annotation from '../../lib/Annotation';
+import { getCanvas } from './canvases';
 
 export * from './canvases';
 export * from './manifests';
 export * from './windows';
 
-/**
-* Return ids and labels of canvases
-* @ param {Array} canvases
-* @return {Array} - [ {id: 'id', label: 'label' }, ... ]
-*/
-export function getIdAndLabelOfCanvases(canvases) {
-  return canvases.map((canvas, index) => ({
-    id: canvas.id,
-    label: getCanvasLabel(canvas, index),
-  }));
-}
-
 /**
 * Return annotations for an array of targets
 * @param {object} state
@@ -76,18 +66,25 @@ export function getIdAndContentOfResources(resources) {
   }));
 }
 
+/** */
+function getWindow(state, { windowId }) {
+  return state.windows && state.windows[windowId];
+}
+
 /** Return position of thumbnail navigation in a certain window.
 * @param {object} state
 * @param {String} windowId
 * @param {String}
 */
-export function getThumbnailNavigationPosition(state, windowId) {
-  return state.windows[windowId]
-    && state.windows[windowId].thumbnailNavigationId
-    && state.companionWindows[state.windows[windowId].thumbnailNavigationId]
-    && state.companionWindows[state.windows[windowId].thumbnailNavigationId].position;
-}
-
+export const getThumbnailNavigationPosition = createSelector(
+  [
+    getWindow,
+    state => state.companionWindows,
+  ],
+  (window, companionWindows) => window
+    && companionWindows[window.thumbnailNavigationId]
+    && companionWindows[window.thumbnailNavigationId].position,
+);
 
 /** Return type of view in a certain window.
 * @param {object} state
@@ -96,68 +93,66 @@ export function getThumbnailNavigationPosition(state, windowId) {
 * @param {string} props.windowId
 * @param {String}
 */
-export function getWindowViewType(state, windowId) {
-  return state.windows[windowId] && state.windows[windowId].view;
-}
+export const getWindowViewType = createSelector(
+  [getWindow],
+  window => window && window.view,
+);
 
 /**
 * Return canvas label, or alternatively return the given index + 1 to be displayed
 * @param {object} canvas
 * @return {String|Integer}
 */
-export function getCanvasLabel(canvas, canvasIndex) {
-  if (!canvas) {
-    return undefined;
-  }
-  if (canvas.getLabel().length > 0) {
-    return canvas.getLabel().map(label => label.value)[0];
-  }
-  return String(canvasIndex + 1);
-}
+export const getCanvasLabel = createSelector(
+  [getCanvas],
+  canvas => (canvas && (
+    canvas.getLabel().length > 0
+      ? canvas.getLabel().map(label => label.value)[0]
+      : String(canvas.index + 1)
+  )),
+);
 
 /**
 * Return canvas description
 * @param {object} canvas
 * @param {String}
 */
-export function getCanvasDescription(canvas) {
-  return canvas
-    && canvas.getProperty('description');
-}
-
-/**
-* Return the companion window string from state in a given windowId and position
-* @param {object} state
-* @param {String} windowId
-* @param {String} position
-* @return {String}
-*/
-export function getCompanionWindowForPosition(state, windowId, position) {
-  return ((state.windows[windowId] || {}).companionWindowIds || []).map(key => (
-    state.companionWindows[key]
-  )).find(cw => (
-    cw.position === position
-  ));
-}
+export const getCanvasDescription = createSelector(
+  [getCanvas],
+  canvas => canvas && canvas.getProperty('description'),
+);
 
 /**
 * Return compantion window ids from a window
 * @param {String} windowId
 * @return {Array}
 */
-export function getCompanionWindowIds(state, windowId) {
-  return state.windows[windowId].companionWindowIds;
-}
+export const getCompanionWindowIds = createSelector(
+  [getWindow],
+  window => (window && window.companionWindowIds) || [],
+);
 
 /**
  * Return companion windows of a window
  * @param {String} windowId
  * @return {Array}
  */
-export function getCompanionWindowsOfWindow(state, windowId) {
-  return getCompanionWindowIds(state, windowId)
-    .map(id => state.companionWindows[id]);
-}
+export const getCompanionWindowsOfWindow = createSelector(
+  [getCompanionWindowIds, state => state.companionWindows],
+  (companionWindowIds, companionWindows) => companionWindowIds.map(id => companionWindows[id]),
+);
+
+/**
+* Return the companion window string from state in a given windowId and position
+* @param {object} state
+* @param {String} windowId
+* @param {String} position
+* @return {String}
+*/
+export const getCompanionWindowForPosition = createSelector(
+  [getCompanionWindowsOfWindow, (state, { position }) => position],
+  (companionWindows, position) => companionWindows.find(cw => cw.position === position),
+);
 
 /**
 * Return languages from config (in state) and indicate which is currently set
diff --git a/src/state/selectors/manifests.js b/src/state/selectors/manifests.js
index 2d57c9607f1d696b19c279bf7c3b31b877cec9e9..3a25e301d38531bd4d49b4dca0e5d7243841a28c 100644
--- a/src/state/selectors/manifests.js
+++ b/src/state/selectors/manifests.js
@@ -6,7 +6,7 @@ import ManifestoCanvas from '../../lib/ManifestoCanvas';
 export function getManifest(state, { manifestId, windowId }) {
   return state.manifests[
     manifestId
-    || (windowId && state.windows[windowId] && state.windows[windowId].manifestId)
+    || (windowId && state.windows && state.windows[windowId] && state.windows[windowId].manifestId)
   ];
 }